From f9feb0a2c1c3fbed72cead7deb5150a8b1fd14fa Mon Sep 17 00:00:00 2001 From: mike kowalski Date: Sat, 23 Oct 2021 07:44:23 -0700 Subject: [PATCH 1/9] fix column sizes and scrollbar overlay --- src/ui/dialog/objects.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 8d56d942af..e253b92790 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -619,9 +619,10 @@ ObjectsPanel::ObjectsPanel() : _text_renderer->property_editable() = true; _text_renderer->property_ellipsize().set_value(Pango::ELLIPSIZE_END); + const int icon_col_width = 24; auto icon_renderer = Gtk::manage(new Inkscape::UI::Widget::CellRendererItemIcon()); icon_renderer->property_xpad() = 2; - icon_renderer->property_width() = 24; + icon_renderer->property_width() = icon_col_width; _tree.append_column(*_name_column); _name_column->set_expand(true); _name_column->pack_start(*icon_renderer, false); @@ -643,6 +644,7 @@ ObjectsPanel::ObjectsPanel() : eye->add_attribute(eyeRenderer->property_cell_background_rgba(), _model->_colBgColor); eye->add_attribute(eyeRenderer->property_activatable(), _model->_colHover); eye->add_attribute(eyeRenderer->property_gossamer(), _model->_colAncestorInvisible); + eye->set_fixed_width(icon_col_width); } // Unlocked icon @@ -655,6 +657,7 @@ ObjectsPanel::ObjectsPanel() : lock->add_attribute(lockRenderer->property_cell_background_rgba(), _model->_colBgColor); lock->add_attribute(lockRenderer->property_activatable(), _model->_colHover); lock->add_attribute(lockRenderer->property_gossamer(), _model->_colAncestorLocked); + lock->set_fixed_width(icon_col_width); } //Set the expander and search columns @@ -689,6 +692,8 @@ ObjectsPanel::ObjectsPanel() : _text_renderer->signal_edited().connect(sigc::mem_fun(*this, &ObjectsPanel::_handleEdited)); //Set up the scroller window and pack the page + // turn off overlay scrollbars - they block access to the 'lock' icon + _scroller.set_overlay_scrolling(false); _scroller.add(_tree); _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); _scroller.set_shadow_type(Gtk::SHADOW_IN); @@ -715,9 +720,12 @@ ObjectsPanel::ObjectsPanel() : _object_mode.set_tooltip_text(_("Switch to layers only view.")); _object_mode.property_active() = prefs->getBool("/dialogs/objects/layers_only", false); _object_mode.property_active().signal_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_objects_toggle)); - _buttonsPrimary.pack_start(_object_mode, Gtk::PACK_SHRINK); + _buttonsPrimary.pack_start(_object_mode, Gtk::PACK_SHRINK); _buttonsPrimary.pack_start(*_addBarButton(INKSCAPE_ICON("layer-new"), _("Add layer..."), (int)SP_VERB_LAYER_NEW), Gtk::PACK_SHRINK); + // uncomment if we think 'properties' dialog button deserves to be exposed: + // _buttonsPrimary.pack_start(*_addBarButton(INKSCAPE_ICON("dialog-object-properties"), _("Object properties..."), (int)SP_VERB_DIALOG_ITEM), Gtk::PACK_SHRINK); + _buttonsSecondary.pack_end(*_addBarButton(INKSCAPE_ICON("edit-delete"), _("Remove object"), (int)SP_VERB_EDIT_DELETE), Gtk::PACK_SHRINK); _buttonsSecondary.pack_end(*_addBarButton(INKSCAPE_ICON("go-down"), _("Move Down"), (int)SP_VERB_SELECTION_STACK_DOWN), Gtk::PACK_SHRINK); _buttonsSecondary.pack_end(*_addBarButton(INKSCAPE_ICON("go-up"), _("Move Up"), (int)SP_VERB_SELECTION_STACK_UP), Gtk::PACK_SHRINK); -- GitLab From 0e20abf186c577de4e05d4f760a7c89e317607d0 Mon Sep 17 00:00:00 2001 From: mike kowalski Date: Sun, 24 Oct 2021 15:19:21 -0700 Subject: [PATCH 2/9] added columns for layer hierachy colors --- src/ui/dialog/objects.cpp | 88 +++++++++++++++++++++++++++++++++++---- src/ui/dialog/objects.h | 2 + 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index e253b92790..63a9e75358 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -17,6 +17,7 @@ #include "objects.h" +#include #include #include #include @@ -59,7 +60,18 @@ #include "ui/widget/imagetoggler.h" #include "ui/widget/shapeicon.h" -static double const SELECTED_ALPHA[8] = {0.0, 2.5, 4.0, 2.0, 8.0, 2.5, 1.0, 1.0}; +// alpha (transparency) multipliers corresponding to item selection state combinations (SelectionState) +// when 0 - do not color item's background +static double const SELECTED_ALPHA[8] = { + 0.00, //0 not selected + 1.00, //1 selected + 0.50, //2 layer focused + 1.00, //3 layer focused & selected + 0.00, //4 child of focused layer + 1.00, //5 selected child of focused layer + 0.50, //6 2 and 4 + 1.00 //7 1, 2 and 4 +}; //#define DUMP_LAYERS 1 @@ -290,6 +302,8 @@ void ObjectWatcher::updateRowAncestorState(bool invisible, bool locked) { } } +Gdk::RGBA selection_color; + /** * Updates the row's background colour as indicated by it's selection. */ @@ -302,16 +316,13 @@ void ObjectWatcher::updateRowBg(guint32 rgba) row[panel->_model->_colBgColor] = Gdk::RGBA(); return; } - if (rgba == 0.0) { - rgba = row[panel->_model->_colIconColor]; - } - auto color = ColorRGBA(rgba); + const auto& sel = selection_color; auto gdk_color = Gdk::RGBA(); - gdk_color.set_red(color[0]); - gdk_color.set_green(color[1]); - gdk_color.set_blue(color[2]); - gdk_color.set_alpha(color[3] / alpha); + gdk_color.set_red(sel.get_red()); + gdk_color.set_green(sel.get_green()); + gdk_color.set_blue(sel.get_blue()); + gdk_color.set_alpha(sel.get_alpha() * alpha); row[panel->_model->_colBgColor] = gdk_color; } } @@ -588,6 +599,50 @@ ObjectWatcher* ObjectsPanel::getWatcher(Node *node) return nullptr; } +class ColorTagRenderer : public Gtk::CellRenderer { +public: + ColorTagRenderer() : + Glib::ObjectBase(typeid(CellRenderer)), + Gtk::CellRenderer(), + _property_color(*this, "tagcolor", 0) { + + int dummy; + // height size is not critical + Gtk::IconSize::lookup(Gtk::ICON_SIZE_MENU, dummy, _height); + } + + ~ColorTagRenderer() override = default; + + Glib::PropertyProxy property_color() { + return _property_color.get_proxy(); + } + + void render_vfunc(const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags) override { + cr->rectangle(cell_area.get_x(), cell_area.get_y(), cell_area.get_width(), cell_area.get_height()); + ColorRGBA color(_property_color.get_value()); + cr->set_source_rgb(color[0], color[1], color[2]); + cr->fill(); + } + + void get_preferred_width_vfunc(Gtk::Widget& widget, int& min_w, int& nat_w) const override { + min_w = nat_w = _width; + } + + void get_preferred_height_vfunc(Gtk::Widget& widget, int& min_h, int& nat_h) const override { + min_h = 1; + nat_h = _height; + } + +private: + int _width = 8; + int _height; + Glib::Property _property_color; +}; + /** * Constructor */ @@ -660,6 +715,14 @@ ObjectsPanel::ObjectsPanel() : lock->set_fixed_width(icon_col_width); } + // hierarchy indicator - using item's layer highlight color + auto tag_renderer = Gtk::manage(new ColorTagRenderer()); + int tag_column = _tree.append_column("tag", *tag_renderer) - 1; + if (auto tag = _tree.get_column(tag_column)) { + tag->add_attribute(tag_renderer->property_color(), _model->_colIconColor); + tag->set_fixed_width(8); + } + //Set the expander and search columns _tree.set_expander_column(*_name_column); // Disable search (it doesn't make much sense) @@ -672,6 +735,8 @@ ObjectsPanel::ObjectsPanel() : _tree.signal_button_release_event().connect(sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false); _tree.signal_key_press_event().connect(sigc::mem_fun(*this, &ObjectsPanel::_handleKeyEvent), false); _tree.signal_motion_notify_event().connect(sigc::mem_fun(*this, &ObjectsPanel::_handleMotionEvent), false); + // watch mouse leave too + _tree.signal_leave_notify_event().connect([=](GdkEventCrossing*){ return _handleMotionEvent(nullptr); }, false); // Before expanding a row, replace the dummy child with the actual children _tree.signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &) { @@ -733,6 +798,11 @@ ObjectsPanel::ObjectsPanel() : _buttonsRow.pack_start(_buttonsPrimary, Gtk::PACK_SHRINK); _buttonsRow.pack_end(_buttonsSecondary, Gtk::PACK_SHRINK); + selection_color = _tree.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED); + _tree_style = _tree.signal_style_updated().connect([&](){ + selection_color = _tree.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED); + }); + update(); show_all_children(); } diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h index f55f1fe35e..729acb718a 100644 --- a/src/ui/dialog/objects.h +++ b/src/ui/dialog/objects.h @@ -25,6 +25,7 @@ #include "selection.h" #include "color-rgba.h" +#include "helper/auto-connection.h" using Inkscape::XML::Node; @@ -113,6 +114,7 @@ private: Gtk::Menu _popupMenu; Gtk::Box _page; Gtk::ToggleButton _object_mode; + Inkscape::auto_connection _tree_style; ObjectsPanel(ObjectsPanel const &) = delete; // no copy ObjectsPanel &operator=(ObjectsPanel const &) = delete; // no assign -- GitLab From e9fa5843ceb451e81828bd0ba2de2dc882d75063 Mon Sep 17 00:00:00 2001 From: mike kowalski Date: Tue, 26 Oct 2021 18:12:43 -0700 Subject: [PATCH 3/9] move default highligh colors to a text file --- share/ui/highlight-colors.ini | 9 +++++++++ src/inkscape.cpp | 24 ++++++++++++++++++++++++ src/object/sp-item-group.cpp | 14 +++++++++++--- src/object/sp-item-group.h | 8 ++------ src/ui/dialog/objects.cpp | 19 +++++++++++++------ 5 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 share/ui/highlight-colors.ini diff --git a/share/ui/highlight-colors.ini b/share/ui/highlight-colors.ini new file mode 100644 index 0000000000..d6de707f19 --- /dev/null +++ b/share/ui/highlight-colors.ini @@ -0,0 +1,9 @@ +# default highlight colors +# two corresponding variants for light and dark backgrounds: +# gray, blue, yellow, red, green, orange, cyan, purple + +[light-theme] +highlights = babdb6ff; 729fcfff; edd400ff; eb486aff; 73b92fff; fcaf3eff; 54d5baff; ad7fa8ff + +[dark-theme] +highlights = b1b5adff; 3b80eeff; c3e33eff; f3215aff; 36a936ff; f37f35ff; 3be3c2ff; b85ac9ff diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 085d9b6316..1d55701032 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -19,6 +19,7 @@ #include +#include #include #include @@ -50,6 +51,7 @@ #include "libnrtype/FontFactory.h" +#include "object/sp-item-group.h" #include "object/sp-root.h" #include "ui/themes.h" @@ -253,6 +255,28 @@ Application::Application(bool use_gui) : /* Check for global remapping of Alt key */ mapalt(guint(prefs->getInt("/options/mapalt/value", 0))); trackalt(guint(prefs->getInt("/options/trackalt/value", 0))); + + themecontext->getChangeThemeSignal().connect([=](){ + try { + auto desktop = active_desktop(); + bool dark = desktop ? themecontext->isCurrentThemeDark(desktop->getToplevel()) : false; + Glib::KeyFile file; + file.load_from_file(std::string(get_path(SYSTEM, UIS, "highlight-colors.ini"))); + auto array = file.get_string_list(dark ? "dark-theme" : "light-theme", "highlights"); + std::vector colors; + for (auto&& entry : array) { + guint32 c = std::stoul(entry.c_str(), nullptr, 16); + if (c) colors.push_back(c); + } + set_default_highlight_colors(std::move(colors)); + } + catch (Glib::Error& error) { + g_warning("Error loading default highlight colors: %s", error.what().c_str()); + } + catch (...) { + g_warning("Error loading default highlight colors."); + } + }); } /* Initialize the extensions */ diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index 394eb6ad7e..571f394460 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -1027,21 +1027,29 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa } } + +// A list of default highlight colours to use when one isn't set. +std::vector default_highlights; + /** * Generate a highlight colour if one isn't set and return it. */ guint32 SPGroup::highlight_color() const { // Parent must not be a layer (root, or similar) and this group must also be a layer - if (!_highlightColor && !SP_IS_LAYER(parent) && this->_layer_mode == SPGroup::LAYER) { + if (!_highlightColor && !SP_IS_LAYER(parent) && this->_layer_mode == SPGroup::LAYER && !default_highlights.empty()) { char const * oid = defaultLabel(); - if (oid) { + if (oid && *oid) { // Color based on the last few bits of the label or object id. - return default_highlights[oid[(strlen(oid) - 1)] & 0x07]; + return default_highlights[oid[(strlen(oid) - 1)] % default_highlights.size()]; } } return SPItem::highlight_color(); } +void set_default_highlight_colors(std::vector colors) { + std::swap(default_highlights, colors); +} + /* Local Variables: mode:c++ diff --git a/src/object/sp-item-group.h b/src/object/sp-item-group.h index 63f0a3ddc3..fe2e8a54eb 100644 --- a/src/object/sp-item-group.h +++ b/src/object/sp-item-group.h @@ -17,12 +17,6 @@ #include #include "sp-lpe-item.h" -// A list of default highlight colours to use when one isn't set. -const unsigned int default_highlights[8] = { - 0xad7fa8ff, 0x729fcfff, 0xbabdb6ff, 0xdb2828ff, - 0x73b92fff, 0xedd400ff, 0xfcaf3eff, 0xbabdb6ff, -}; - namespace Inkscape { class Drawing; @@ -121,6 +115,8 @@ inline bool SP_IS_LAYER(SPObject const *obj) return group && group->layerMode() == SPGroup::LAYER; } +void set_default_highlight_colors(std::vector colors); + #endif /* diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 63a9e75358..2c9b6c0cf9 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -605,10 +605,10 @@ public: Glib::ObjectBase(typeid(CellRenderer)), Gtk::CellRenderer(), _property_color(*this, "tagcolor", 0) { - - int dummy; + + int dummy_width; // height size is not critical - Gtk::IconSize::lookup(Gtk::ICON_SIZE_MENU, dummy, _height); + Gtk::IconSize::lookup(Gtk::ICON_SIZE_MENU, dummy_width, _height); } ~ColorTagRenderer() override = default; @@ -617,6 +617,10 @@ public: return _property_color.get_proxy(); } + int get_width() const { + return _width; + } + void render_vfunc(const Cairo::RefPtr& cr, Gtk::Widget& widget, const Gdk::Rectangle& background_area, @@ -720,7 +724,7 @@ ObjectsPanel::ObjectsPanel() : int tag_column = _tree.append_column("tag", *tag_renderer) - 1; if (auto tag = _tree.get_column(tag_column)) { tag->add_attribute(tag_renderer->property_color(), _model->_colIconColor); - tag->set_fixed_width(8); + tag->set_fixed_width(tag_renderer->get_width()); } //Set the expander and search columns @@ -788,8 +792,6 @@ ObjectsPanel::ObjectsPanel() : _buttonsPrimary.pack_start(_object_mode, Gtk::PACK_SHRINK); _buttonsPrimary.pack_start(*_addBarButton(INKSCAPE_ICON("layer-new"), _("Add layer..."), (int)SP_VERB_LAYER_NEW), Gtk::PACK_SHRINK); - // uncomment if we think 'properties' dialog button deserves to be exposed: - // _buttonsPrimary.pack_start(*_addBarButton(INKSCAPE_ICON("dialog-object-properties"), _("Object properties..."), (int)SP_VERB_DIALOG_ITEM), Gtk::PACK_SHRINK); _buttonsSecondary.pack_end(*_addBarButton(INKSCAPE_ICON("edit-delete"), _("Remove object"), (int)SP_VERB_EDIT_DELETE), Gtk::PACK_SHRINK); _buttonsSecondary.pack_end(*_addBarButton(INKSCAPE_ICON("go-down"), _("Move Down"), (int)SP_VERB_SELECTION_STACK_DOWN), Gtk::PACK_SHRINK); @@ -801,6 +803,11 @@ ObjectsPanel::ObjectsPanel() : selection_color = _tree.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED); _tree_style = _tree.signal_style_updated().connect([&](){ selection_color = _tree.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED); + for (auto&& kv : root_watcher->child_watchers) { + if (kv.second) { + kv.second->updateRowHighlight(); + } + } }); update(); -- GitLab From ea6d8f4b2acd9d5227472abc28db615364b9286a Mon Sep 17 00:00:00 2001 From: mike kowalski Date: Tue, 26 Oct 2021 18:54:53 -0700 Subject: [PATCH 4/9] add highlight colors --- share/ui/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/ui/CMakeLists.txt b/share/ui/CMakeLists.txt index 149d76e5e6..4e1843894d 100644 --- a/share/ui/CMakeLists.txt +++ b/share/ui/CMakeLists.txt @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-or-later -file(GLOB _FILES "*.xml" "*.rc" "*.css" "*.ui" "*.glade" "*.svg") +file(GLOB _FILES "*.xml" "*.rc" "*.css" "*.ui" "*.glade" "*.svg" "*.ini") install(FILES ${_FILES} DESTINATION ${INKSCAPE_SHARE_INSTALL}/ui) file(GLOB _RESOURCES "resources/*.png" "resources/*.svg") -- GitLab From 59056925b74acb96f61822c1d6c455e518ff42f0 Mon Sep 17 00:00:00 2001 From: mike kowalski Date: Wed, 27 Oct 2021 19:16:35 -0700 Subject: [PATCH 5/9] highlight colors migrated to css --- share/ui/CMakeLists.txt | 2 +- share/ui/highlight-colors-dark.css | 29 +++++++++++++++++++++++++ share/ui/highlight-colors.css | 29 +++++++++++++++++++++++++ share/ui/highlight-colors.ini | 9 -------- src/inkscape.cpp | 23 +++----------------- src/ui/themes.cpp | 35 ++++++++++++++++++++++++++++-- src/ui/themes.h | 3 +++ 7 files changed, 98 insertions(+), 32 deletions(-) create mode 100644 share/ui/highlight-colors-dark.css create mode 100644 share/ui/highlight-colors.css delete mode 100644 share/ui/highlight-colors.ini diff --git a/share/ui/CMakeLists.txt b/share/ui/CMakeLists.txt index 4e1843894d..149d76e5e6 100644 --- a/share/ui/CMakeLists.txt +++ b/share/ui/CMakeLists.txt @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-or-later -file(GLOB _FILES "*.xml" "*.rc" "*.css" "*.ui" "*.glade" "*.svg" "*.ini") +file(GLOB _FILES "*.xml" "*.rc" "*.css" "*.ui" "*.glade" "*.svg") install(FILES ${_FILES} DESTINATION ${INKSCAPE_SHARE_INSTALL}/ui) file(GLOB _RESOURCES "resources/*.png" "resources/*.svg") diff --git a/share/ui/highlight-colors-dark.css b/share/ui/highlight-colors-dark.css new file mode 100644 index 0000000000..0ac7e0bbf9 --- /dev/null +++ b/share/ui/highlight-colors-dark.css @@ -0,0 +1,29 @@ +/* default highlight colors; variant for dark backgrounds + * + * gray, blue, yellow, red, green, orange, cyan, purple + */ + +.highlight-color-1 { + color: #b1b5ad; +} +.highlight-color-2 { + color: #3b80ee; +} +.highlight-color-3 { + color: #c3e33e; +} +.highlight-color-4 { + color: #f3215a; +} +.highlight-color-5 { + color: #36a949; +} +.highlight-color-6 { + color: #f37f35; +} +.highlight-color-7 { + color: #3be3c2; +} +.highlight-color-8 { + color: #b85ac9; +} diff --git a/share/ui/highlight-colors.css b/share/ui/highlight-colors.css new file mode 100644 index 0000000000..3581bdad04 --- /dev/null +++ b/share/ui/highlight-colors.css @@ -0,0 +1,29 @@ +/* default highlight colors; variant for light backgrounds + * + * gray, blue, yellow, red, green, orange, cyan, purple + */ + +.highlight-color-1 { + color: #babdb6; +} +.highlight-color-2 { + color: #729fcf; +} +.highlight-color-3 { + color: #edd400; +} +.highlight-color-4 { + color: #eb486a; +} +.highlight-color-5 { + color: #73b92f; +} +.highlight-color-6 { + color: #fcaf3e; +} +.highlight-color-7 { + color: #54d5ba; +} +.highlight-color-8 { + color: #ad7fa8; +} diff --git a/share/ui/highlight-colors.ini b/share/ui/highlight-colors.ini deleted file mode 100644 index d6de707f19..0000000000 --- a/share/ui/highlight-colors.ini +++ /dev/null @@ -1,9 +0,0 @@ -# default highlight colors -# two corresponding variants for light and dark backgrounds: -# gray, blue, yellow, red, green, orange, cyan, purple - -[light-theme] -highlights = babdb6ff; 729fcfff; edd400ff; eb486aff; 73b92fff; fcaf3eff; 54d5baff; ad7fa8ff - -[dark-theme] -highlights = b1b5adff; 3b80eeff; c3e33eff; f3215aff; 36a936ff; f37f35ff; 3be3c2ff; b85ac9ff diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 1d55701032..9073d4cfbd 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -19,7 +19,6 @@ #include -#include #include #include @@ -257,25 +256,9 @@ Application::Application(bool use_gui) : trackalt(guint(prefs->getInt("/options/trackalt/value", 0))); themecontext->getChangeThemeSignal().connect([=](){ - try { - auto desktop = active_desktop(); - bool dark = desktop ? themecontext->isCurrentThemeDark(desktop->getToplevel()) : false; - Glib::KeyFile file; - file.load_from_file(std::string(get_path(SYSTEM, UIS, "highlight-colors.ini"))); - auto array = file.get_string_list(dark ? "dark-theme" : "light-theme", "highlights"); - std::vector colors; - for (auto&& entry : array) { - guint32 c = std::stoul(entry.c_str(), nullptr, 16); - if (c) colors.push_back(c); - } - set_default_highlight_colors(std::move(colors)); - } - catch (Glib::Error& error) { - g_warning("Error loading default highlight colors: %s", error.what().c_str()); - } - catch (...) { - g_warning("Error loading default highlight colors."); - } + auto desktop = active_desktop(); + bool dark = desktop ? themecontext->isCurrentThemeDark(desktop->getToplevel()) : false; + set_default_highlight_colors(Inkscape::UI::load_highlight_colors(dark)); }); } diff --git a/src/ui/themes.cpp b/src/ui/themes.cpp index 0bbfd888c7..e7b7cd015a 100644 --- a/src/ui/themes.cpp +++ b/src/ui/themes.cpp @@ -462,12 +462,43 @@ bool ThemeContext::isCurrentThemeDark(Gtk::Container *window) } } return dark; - } +std::vector load_highlight_colors(bool dark_theme) { + std::vector colors; + auto css = Gtk::CssProvider::create(); + auto path = Inkscape::IO::Resource::get_filename(Inkscape::IO::Resource::UIS, dark_theme ? "highlight-colors-dark.css" : "highlight-colors.css"); + if (css->load_from_path(path)) { + auto widget = std::make_unique(); + auto ctx = widget->get_style_context(); + // extract colors from CSS + ctx->add_provider(css, GTK_STYLE_PROVIDER_PRIORITY_USER); + + Glib::ustring name = "highlight-color-"; + // 8 colors with no easy way to detect number of classes + for (int i = 1; i <= 8; ++i) { + auto class_name = name + Glib::ustring::format(i); + ctx->add_class(class_name); + auto color = ctx->get_color(); + guint32 rgba = + gint32(0xff * color.get_red()) << 24 | + gint32(0xff * color.get_green()) << 16 | + gint32(0xff * color.get_blue()) << 8 | + gint32(0xff * color.get_alpha()); + colors.push_back(rgba); + ctx->remove_class(class_name); + } + } + else { + g_warning("Error loading highlight colors from %s", path.c_str()); + } + return colors; } -} + +} // UI +} // Inkscape + /* Local Variables: mode:c++ diff --git a/src/ui/themes.h b/src/ui/themes.h index 9a427dfb92..56c493e267 100644 --- a/src/ui/themes.h +++ b/src/ui/themes.h @@ -65,6 +65,9 @@ private: std::unique_ptr _spinbutton_observer; }; +// load default highlight colors (for dark or light theme) +std::vector load_highlight_colors(bool dark_theme); + } } #endif /* !UI_THEMES_H_SEEN */ -- GitLab From e918c8841d64ff775375a9f24dc0fa88cc77fc74 Mon Sep 17 00:00:00 2001 From: mike kowalski Date: Thu, 28 Oct 2021 19:26:06 -0700 Subject: [PATCH 6/9] highlight colors migrated to style.css --- share/ui/highlight-colors-dark.css | 29 ------------------- share/ui/highlight-colors.css | 46 ++++++++++++++++++++++++------ share/ui/style.css | 1 + src/ui/themes.cpp | 10 ++++++- 4 files changed, 48 insertions(+), 38 deletions(-) delete mode 100644 share/ui/highlight-colors-dark.css diff --git a/share/ui/highlight-colors-dark.css b/share/ui/highlight-colors-dark.css deleted file mode 100644 index 0ac7e0bbf9..0000000000 --- a/share/ui/highlight-colors-dark.css +++ /dev/null @@ -1,29 +0,0 @@ -/* default highlight colors; variant for dark backgrounds - * - * gray, blue, yellow, red, green, orange, cyan, purple - */ - -.highlight-color-1 { - color: #b1b5ad; -} -.highlight-color-2 { - color: #3b80ee; -} -.highlight-color-3 { - color: #c3e33e; -} -.highlight-color-4 { - color: #f3215a; -} -.highlight-color-5 { - color: #36a949; -} -.highlight-color-6 { - color: #f37f35; -} -.highlight-color-7 { - color: #3be3c2; -} -.highlight-color-8 { - color: #b85ac9; -} diff --git a/share/ui/highlight-colors.css b/share/ui/highlight-colors.css index 3581bdad04..1703d184ea 100644 --- a/share/ui/highlight-colors.css +++ b/share/ui/highlight-colors.css @@ -3,27 +3,57 @@ * gray, blue, yellow, red, green, orange, cyan, purple */ -.highlight-color-1 { +.light .highlight-color-1 { color: #babdb6; } -.highlight-color-2 { +.light .highlight-color-2 { color: #729fcf; } -.highlight-color-3 { +.light .highlight-color-3 { color: #edd400; } -.highlight-color-4 { +.light .highlight-color-4 { color: #eb486a; } -.highlight-color-5 { +.light .highlight-color-5 { color: #73b92f; } -.highlight-color-6 { +.light .highlight-color-6 { color: #fcaf3e; } -.highlight-color-7 { +.light .highlight-color-7 { color: #54d5ba; } -.highlight-color-8 { +.light .highlight-color-8 { color: #ad7fa8; } + +/* default highlight colors; variant for dark backgrounds + * + * gray, blue, yellow, red, green, orange, cyan, purple + */ + +.dark .highlight-color-1 { + color: #b1b5ad; +} +.dark .highlight-color-2 { + color: #3b80ee; +} +.dark .highlight-color-3 { + color: #c3e33e; +} +.dark .highlight-color-4 { + color: #f3215a; +} +.dark .highlight-color-5 { + color: #36a949; +} +.dark .highlight-color-6 { + color: #f37f35; +} +.dark .highlight-color-7 { + color: #3be3c2; +} +.dark .highlight-color-8 { + color: #b85ac9; +} diff --git a/share/ui/style.css b/share/ui/style.css index 1e1541f553..e47a41507a 100644 --- a/share/ui/style.css +++ b/share/ui/style.css @@ -54,6 +54,7 @@ /* Black */ +@import url("highlight-colors.css"); /* Inkscape CSS helper * to add a class to a widget do some thing like diff --git a/src/ui/themes.cpp b/src/ui/themes.cpp index e7b7cd015a..617a6e21f8 100644 --- a/src/ui/themes.cpp +++ b/src/ui/themes.cpp @@ -464,14 +464,21 @@ bool ThemeContext::isCurrentThemeDark(Gtk::Container *window) return dark; } +// extract "default" highlight colors from style.css std::vector load_highlight_colors(bool dark_theme) { std::vector colors; auto css = Gtk::CssProvider::create(); - auto path = Inkscape::IO::Resource::get_filename(Inkscape::IO::Resource::UIS, dark_theme ? "highlight-colors-dark.css" : "highlight-colors.css"); + auto path = Inkscape::IO::Resource::get_filename(Inkscape::IO::Resource::UIS, "style.css"); if (css->load_from_path(path)) { + auto parent = std::make_unique(); + auto parent_ctx = parent->get_style_context(); + parent_ctx->add_class(dark_theme ? "dark" : "light"); + auto widget = std::make_unique(); + parent->pack_start(*widget); auto ctx = widget->get_style_context(); + // extract colors from CSS ctx->add_provider(css, GTK_STYLE_PROVIDER_PRIORITY_USER); @@ -493,6 +500,7 @@ std::vector load_highlight_colors(bool dark_theme) { else { g_warning("Error loading highlight colors from %s", path.c_str()); } + return colors; } -- GitLab From ed9dcd8850059c320df1323c30e6a5564599e67b Mon Sep 17 00:00:00 2001 From: mike kowalski Date: Sat, 30 Oct 2021 18:42:25 -0700 Subject: [PATCH 7/9] ctx menu fixes for layers --- share/ui/highlight-colors.css | 16 +- src/inkscape.cpp | 7 +- src/ui/contextmenu.cpp | 397 +++++++++++++++++------------ src/ui/contextmenu.h | 14 +- src/ui/dialog/layer-properties.cpp | 7 +- src/ui/dialog/objects.cpp | 74 ++++-- src/ui/dialog/objects.h | 6 +- src/ui/themes.cpp | 55 ++-- src/ui/themes.h | 5 +- 9 files changed, 345 insertions(+), 236 deletions(-) diff --git a/share/ui/highlight-colors.css b/share/ui/highlight-colors.css index 1703d184ea..1739d45ed0 100644 --- a/share/ui/highlight-colors.css +++ b/share/ui/highlight-colors.css @@ -3,28 +3,28 @@ * gray, blue, yellow, red, green, orange, cyan, purple */ -.light .highlight-color-1 { +.bright .highlight-color-1 { color: #babdb6; } -.light .highlight-color-2 { +.bright .highlight-color-2 { color: #729fcf; } -.light .highlight-color-3 { +.bright .highlight-color-3 { color: #edd400; } -.light .highlight-color-4 { +.bright .highlight-color-4 { color: #eb486a; } -.light .highlight-color-5 { +.bright .highlight-color-5 { color: #73b92f; } -.light .highlight-color-6 { +.bright .highlight-color-6 { color: #fcaf3e; } -.light .highlight-color-7 { +.bright .highlight-color-7 { color: #54d5ba; } -.light .highlight-color-8 { +.bright .highlight-color-8 { color: #ad7fa8; } diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 9073d4cfbd..4fbfef8582 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -255,10 +255,11 @@ Application::Application(bool use_gui) : mapalt(guint(prefs->getInt("/options/mapalt/value", 0))); trackalt(guint(prefs->getInt("/options/trackalt/value", 0))); + /* update highlight colors when theme changes */ themecontext->getChangeThemeSignal().connect([=](){ - auto desktop = active_desktop(); - bool dark = desktop ? themecontext->isCurrentThemeDark(desktop->getToplevel()) : false; - set_default_highlight_colors(Inkscape::UI::load_highlight_colors(dark)); + if (auto desktop = active_desktop()) { + set_default_highlight_colors(themecontext->getHighlightColors(desktop->getToplevel())); + } }); } diff --git a/src/ui/contextmenu.cpp b/src/ui/contextmenu.cpp index d12698d7c6..4e4dde48c8 100644 --- a/src/ui/contextmenu.cpp +++ b/src/ui/contextmenu.cpp @@ -58,7 +58,6 @@ #include "object/sp-text.h" #include "ui/desktop/menu-icon-shift.h" -//#include "ui/dialog/dialog-manager.h" #include "ui/dialog/dialog-container.h" #include "ui/dialog/layer-properties.h" #include "ui/icon-loader.h" @@ -68,6 +67,24 @@ using Inkscape::DocumentUndo; static bool temporarily_block_actions = false; +SPGroup* get_layer(SPObject* object) { + if (auto group = dynamic_cast(object)) { + if (group->layerMode() == SPGroup::LAYER) { + return group; + } + } + return nullptr; +} + +SPGroup* get_group(SPObject* object) { + if (auto group = dynamic_cast(object)) { + if (group->layerMode() == SPGroup::GROUP) { + return group; + } + } + return nullptr; +} + ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : _item(item), MIGroup(), @@ -79,17 +96,26 @@ ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : _desktop = desktop; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool show_icons = prefs->getInt("/theme/menuIcons_canvas", true); + _show_icons = prefs->getInt("/theme/menuIcons_canvas", true); + auto layer = get_layer(_object); - AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_UNDO), show_icons); - AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_REDO), show_icons); - AddSeparator(); - AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_CUT), show_icons); - AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_COPY), show_icons); - AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_PASTE), show_icons); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_UNDO)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_REDO)); AddSeparator(); - AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_DUPLICATE), show_icons); - AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_DELETE), show_icons); + if (!layer) { + // don't bother adding copy/paste/cut when clicking on a layer; it won't work unless layer is *selected* + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_CUT)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_COPY)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_PASTE)); + AddSeparator(); + } + // when clicking an a current layer, show layer-specific duplicate action; + // layer has it's own "duplicate" action which varies from "selection duplicate" for better or worse + auto duplicate = layer ? SP_VERB_LAYER_DUPLICATE : SP_VERB_EDIT_DUPLICATE; + AppendItemFromVerb(Inkscape::Verb::get(duplicate)); + // layer-specific delete action + auto del = layer ? SP_VERB_LAYER_DELETE : SP_VERB_EDIT_DELETE; + AppendItemFromVerb(Inkscape::Verb::get(del)); positionOfLastDialog = 10; // 9 in front + 1 for the separator in the next if; used to position the dialog menu entries below each other /* Item menu */ @@ -145,42 +171,6 @@ ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : } mi->show(); append(*mi);//insert(*mi,positionOfLastDialog++); - /* layer menu */ - SPGroup *group=nullptr; - if (item) { - if (SP_IS_GROUP(item)) { - group = SP_GROUP(item); - } else if ( item != _desktop->currentRoot() && SP_IS_GROUP(item->parent) ) { - group = SP_GROUP(item->parent); - } - } - - if (( group && group != _desktop->currentLayer() ) || - ( _desktop->currentLayer() != _desktop->currentRoot() && _desktop->currentLayer()->parent != _desktop->currentRoot() ) ) { - AddSeparator(); - } - - if ( group && group != _desktop->currentLayer() ) { - MIGroup.set_label (Glib::ustring::compose(_("Enter group %1"), group->defaultLabel())); - _MIGroup_group = group; - MIGroup.signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ContextMenu::EnterGroup),&MIGroup)); - MIGroup.show(); - append(MIGroup); - } - - if ( _desktop->currentLayer() != _desktop->currentRoot() ) { - if ( _desktop->currentLayer()->parent != _desktop->currentRoot() ) { - MIParent.signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::LeaveGroup)); - MIParent.show(); - append(MIParent); - - /* Pop selection out of group */ - Gtk::MenuItem* miu = Gtk::manage(new Gtk::MenuItem(_("_Pop selection out of group"), true)); - miu->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateUngroupPopSelection)); - miu->show(); - append(*miu); - } - } // Install CSS to shift icons into the space reserved for toggles (i.e. check and radio items). signal_map().connect(sigc::bind(sigc::ptr_fun(shift_icons), this)); @@ -289,7 +279,7 @@ context_menu_item_on_my_deselect(void */*object*/, SPAction *action) // TODO: Update this to allow radio items to be used -void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb, bool show_icon) +void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb) { SPAction *action; SPDesktop *view = _desktop; @@ -313,7 +303,7 @@ void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb, bool show_icon) label->set_accel_widget(*item); // If there is an image associated with the action, then we can add it as an icon for the menu item - if (show_icon && action->image) { + if (_show_icons && action->image) { item->set_name("ImageMenuItem"); // custom name to identify our "ImageMenuItems" auto const icon = Gtk::manage(sp_get_icon_image(action->image, Gtk::ICON_SIZE_MENU)); @@ -347,11 +337,11 @@ void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb, bool show_icon) void ContextMenu::MakeObjectMenu() { if (SP_IS_ITEM(_object)) { - MakeItemMenu(); + MakeItemMenu(get_layer(_object)); } if (SP_IS_GROUP(_object)) { - MakeGroupMenu(); + MakeGroupMenu(SP_GROUP(_object)); } if (SP_IS_ANCHOR(_object)) { @@ -371,7 +361,7 @@ void ContextMenu::MakeObjectMenu() } } -void ContextMenu::MakeItemMenu () +void ContextMenu::MakeItemMenu(SPGroup* layer) { Gtk::MenuItem* mi; @@ -395,50 +385,53 @@ void ContextMenu::MakeItemMenu () append(*mi); } + // several options are not applicable to layers; adding them makes context menu unwieldy, + // so we need to be selective, or else it grows too much + if (!layer) { + mi = Gtk::manage(new Gtk::MenuItem(_("Select Same"))); + mi->show(); + Gtk::Menu *select_same_submenu = Gtk::manage(new Gtk::Menu()); + if (_desktop->selection->isEmpty()) { + mi->set_sensitive(FALSE); + } + mi->set_submenu(*select_same_submenu); + append(*mi); - mi = Gtk::manage(new Gtk::MenuItem(_("Select Same"))); - mi->show(); - Gtk::Menu *select_same_submenu = Gtk::manage(new Gtk::Menu()); - if (_desktop->selection->isEmpty()) { - mi->set_sensitive(FALSE); - } - mi->set_submenu(*select_same_submenu); - append(*mi); - - /* Select same fill and stroke */ - mi = Gtk::manage(new Gtk::MenuItem(_("Fill and Stroke"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameFillStroke)); - mi->set_sensitive(!SP_IS_ANCHOR(_item)); - mi->show(); - select_same_submenu->append(*mi); + /* Select same fill and stroke */ + mi = Gtk::manage(new Gtk::MenuItem(_("Fill and Stroke"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameFillStroke)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); - /* Select same fill color */ - mi = Gtk::manage(new Gtk::MenuItem(_("Fill Color"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameFillColor)); - mi->set_sensitive(!SP_IS_ANCHOR(_item)); - mi->show(); - select_same_submenu->append(*mi); + /* Select same fill color */ + mi = Gtk::manage(new Gtk::MenuItem(_("Fill Color"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameFillColor)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); - /* Select same stroke color */ - mi = Gtk::manage(new Gtk::MenuItem(_("Stroke Color"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameStrokeColor)); - mi->set_sensitive(!SP_IS_ANCHOR(_item)); - mi->show(); - select_same_submenu->append(*mi); + /* Select same stroke color */ + mi = Gtk::manage(new Gtk::MenuItem(_("Stroke Color"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameStrokeColor)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); - /* Select same stroke style */ - mi = Gtk::manage(new Gtk::MenuItem(_("Stroke Style"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameStrokeStyle)); - mi->set_sensitive(!SP_IS_ANCHOR(_item)); - mi->show(); - select_same_submenu->append(*mi); + /* Select same stroke style */ + mi = Gtk::manage(new Gtk::MenuItem(_("Stroke Style"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameStrokeStyle)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); - /* Select same stroke style */ - mi = Gtk::manage(new Gtk::MenuItem(_("Object Type"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameObjectType)); - mi->set_sensitive(!SP_IS_ANCHOR(_item)); - mi->show(); - select_same_submenu->append(*mi); + /* Select same stroke style */ + mi = Gtk::manage(new Gtk::MenuItem(_("Object Type"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameObjectType)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); + } /* Move to layer */ mi = Gtk::manage(new Gtk::MenuItem(_("_Move to Layer..."), true)); @@ -450,82 +443,84 @@ void ContextMenu::MakeItemMenu () mi->show(); append(*mi); - /* Create link */ - mi = Gtk::manage(new Gtk::MenuItem(_("Create _Link"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemCreateLink)); - mi->set_sensitive(!SP_IS_ANCHOR(_item)); - mi->show(); - append(*mi); - - bool ClipRefOK=false; - bool MaskRefOK=false; - if (_item && _item->getClipObject()) { - ClipRefOK = true; - } - if (_item && _item->getMaskObject()) { - MaskRefOK = true; - } - /* Set mask */ - mi = Gtk::manage(new Gtk::MenuItem(_("Set Mask"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetMask)); - if (ClipRefOK || MaskRefOK) { - mi->set_sensitive(FALSE); - } else { - mi->set_sensitive(TRUE); - } - mi->show(); - append(*mi); + if (!layer) { + /* Create link */ + mi = Gtk::manage(new Gtk::MenuItem(_("Create _Link"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemCreateLink)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + append(*mi); - /* Release mask */ - mi = Gtk::manage(new Gtk::MenuItem(_("Release Mask"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseMask)); - if (MaskRefOK) { - mi->set_sensitive(TRUE); - } else { - mi->set_sensitive(FALSE); - } - mi->show(); - append(*mi); + bool ClipRefOK=false; + bool MaskRefOK=false; + if (_item && _item->getClipObject()) { + ClipRefOK = true; + } + if (_item && _item->getMaskObject()) { + MaskRefOK = true; + } + /* Set mask */ + mi = Gtk::manage(new Gtk::MenuItem(_("Set Mask"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetMask)); + if (ClipRefOK || MaskRefOK) { + mi->set_sensitive(FALSE); + } else { + mi->set_sensitive(TRUE); + } + mi->show(); + append(*mi); - /*SSet Clip Group */ - mi = Gtk::manage(new Gtk::MenuItem(_("Create Clip G_roup"),true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::CreateGroupClip)); - mi->set_sensitive(TRUE); - mi->show(); - append(*mi); + /* Release mask */ + mi = Gtk::manage(new Gtk::MenuItem(_("Release Mask"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseMask)); + if (MaskRefOK) { + mi->set_sensitive(TRUE); + } else { + mi->set_sensitive(FALSE); + } + mi->show(); + append(*mi); - /* Set Clip */ - mi = Gtk::manage(new Gtk::MenuItem(_("Set Cl_ip"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetClip)); - if (ClipRefOK || MaskRefOK) { - mi->set_sensitive(FALSE); - } else { + /*SSet Clip Group */ + mi = Gtk::manage(new Gtk::MenuItem(_("Create Clip G_roup"),true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::CreateGroupClip)); mi->set_sensitive(TRUE); - } - mi->show(); - append(*mi); + mi->show(); + append(*mi); - /* Release Clip */ - mi = Gtk::manage(new Gtk::MenuItem(_("Release C_lip"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseClip)); - if (ClipRefOK) { - mi->set_sensitive(TRUE); - } else { - mi->set_sensitive(FALSE); - } - mi->show(); - append(*mi); + /* Set Clip */ + mi = Gtk::manage(new Gtk::MenuItem(_("Set Cl_ip"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetClip)); + if (ClipRefOK || MaskRefOK) { + mi->set_sensitive(FALSE); + } else { + mi->set_sensitive(TRUE); + } + mi->show(); + append(*mi); - /* Group */ - mi = Gtk::manage(new Gtk::MenuItem(_("_Group"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateGroup)); - if (_desktop->selection->isEmpty()) { - mi->set_sensitive(FALSE); - } else { - mi->set_sensitive(TRUE); + /* Release Clip */ + mi = Gtk::manage(new Gtk::MenuItem(_("Release C_lip"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseClip)); + if (ClipRefOK) { + mi->set_sensitive(TRUE); + } else { + mi->set_sensitive(FALSE); + } + mi->show(); + append(*mi); + + /* Group */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Group"), true)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateGroup)); + if (_desktop->selection->isEmpty()) { + mi->set_sensitive(FALSE); + } else { + mi->set_sensitive(TRUE); + } + mi->show(); + append(*mi); } - mi->show(); - append(*mi); } void ContextMenu::SelectSameFillStroke() @@ -622,13 +617,87 @@ void ContextMenu::ReleaseClip() _desktop->selection->unsetMask(true); } -void ContextMenu::MakeGroupMenu() -{ - /* Ungroup */ - Gtk::MenuItem* mi = Gtk::manage(new Gtk::MenuItem(_("_Ungroup"), true)); - mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateUngroup)); +void sp_group_layer_transform(SPDocument* document, SPGroup* group, SPGroup::LayerMode mode) { + if (!group) return; + + group->setLayerMode(mode); + group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + if (document) { + DocumentUndo::done(document, SP_VERB_DIALOG_OBJECTS, mode == SPGroup::GROUP ? _("Layer to group") : _("Group to layer")); + } +} + +Glib::SignalProxy ContextMenu::append_item(const char* label, bool mnemonic) { + auto mi = Gtk::make_managed(label, mnemonic); mi->show(); append(*mi); + return mi->signal_activate(); +} + +void ContextMenu::fireAction(unsigned int code) { + if (Inkscape::Verb* verb = Inkscape::Verb::get(code)) { + if (SPAction* action = verb->get_action(Inkscape::ActionContext(_desktop))) { + sp_action_perform(action, nullptr); + } + } +} + +// group and layer menu +void ContextMenu::MakeGroupMenu(SPGroup* item) +{ + if (auto layer = get_layer(item)) { + // layer-specific commands + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_NEW)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_RENAME)); + AddSeparator(); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_SOLO)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_SHOW_ALL)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_HIDE_ALL)); + AddSeparator(); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_LOCK_OTHERS)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_LOCK_ALL)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_UNLOCK_ALL)); + AddSeparator(); + + // transform layer into group + append_item(_("Layer to group"), false).connect([=]() { sp_group_layer_transform(_desktop->doc(), layer, SPGroup::GROUP); }); + } + else if (auto group = get_group(item)) { + /* Ungroup */ + append_item(_("_Ungroup"), true).connect(sigc::mem_fun(*this, &ContextMenu::ActivateUngroup)); + + if (auto parent = get_layer(group->parent)) { + // transform group into layer + append_item(_("Group to layer"), false).connect([=](){ sp_group_layer_transform(_desktop->doc(), group, SPGroup::LAYER); }); + } + + // enter group + if (group != _desktop->currentLayer()) { + MIGroup.set_label(Glib::ustring::compose(_("Enter group %1"), group->defaultLabel())); + _MIGroup_group = group; + MIGroup.signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ContextMenu::EnterGroup),&MIGroup)); + MIGroup.show(); + append(MIGroup); + } + + if (_desktop->currentLayer() != _desktop->currentRoot()) { + if (_desktop->currentLayer()->parent != _desktop->currentRoot()) { + MIParent.signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::LeaveGroup)); + MIParent.show(); + append(MIParent); + + /* Pop selection out of group */ + Gtk::MenuItem* miu = Gtk::manage(new Gtk::MenuItem(_("_Pop selection out of group"), true)); + miu->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateUngroupPopSelection)); + miu->show(); + append(*miu); + } + } + } + else { + // not a plain group and not a layer; a mask helper? + // no special operations here so far + } } void ContextMenu::ActivateGroup() diff --git a/src/ui/contextmenu.h b/src/ui/contextmenu.h index 9d83879ecb..4d4270a31a 100644 --- a/src/ui/contextmenu.h +++ b/src/ui/contextmenu.h @@ -22,6 +22,7 @@ class SPDesktop; class SPItem; +class SPGroup; class SPObject; namespace Gtk { @@ -60,13 +61,16 @@ class ContextMenu : public Gtk::Menu SPItem *_item; // pointer to the object selected at the time the ContextMenu is created SPObject *_object; // pointer to the object selected at the time the ContextMenu is created SPDesktop *_desktop; //pointer to the desktop the user was currently working on at the time the ContextMenu is created - + bool _show_icons; int positionOfLastDialog; Gtk::MenuItem MIGroup; //menu entry to enter a group SPObject *_MIGroup_group; // Group to enter when MIGroup is activated Gtk::MenuItem MIParent; //menu entry to leave a group - + + void fireAction(unsigned int code); + Glib::SignalProxy append_item(const char* label, bool mnemonic); + /** * auxiliary function that adds a separator line in the context menu */ @@ -81,7 +85,7 @@ class ContextMenu : public Gtk::Menu * @param show_icon True if an icon should be displayed before the menu item's label * */ - void AppendItemFromVerb(Inkscape::Verb *verb, bool show_icon = false); + void AppendItemFromVerb(Inkscape::Verb *verb); /** * main function which is responsible for creating the context sensitive menu items, @@ -91,11 +95,11 @@ class ContextMenu : public Gtk::Menu /** * creates menu entries for an SP_TYPE_ITEM object */ - void MakeItemMenu (); + void MakeItemMenu(SPGroup* layer); /** * creates menu entries for a grouped object */ - void MakeGroupMenu (); + void MakeGroupMenu (SPGroup* group); /** * creates menu entries for an anchor object */ diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index 63025ef70a..45c8e4cf38 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -24,6 +24,7 @@ #include "document-undo.h" #include "layer-manager.h" #include "message-stack.h" +#include "preferences.h" #include "verbs.h" #include "selection-chemistry.h" @@ -162,6 +163,9 @@ LayerPropertiesDialog::_setup_position_controls() { row->set_value(_dropdown_columns.position, LPOS_CHILD); row->set_value(_dropdown_columns.name, Glib::ustring(_("As sublayer of current"))); + int position = Inkscape::Preferences::get()->getIntLimited("/dialogs/layerProp/addLayerPosition", 0, 0, 2); + _layer_position_combo.set_active(position); + _layer_position_label.set_label(_("Position:")); _layer_position_label.set_halign(Gtk::ALIGN_START); _layer_position_label.set_valign(Gtk::ALIGN_CENTER); @@ -353,10 +357,11 @@ void LayerPropertiesDialog::Create::perform(LayerPropertiesDialog &dialog) { SPDesktop *desktop=dialog._desktop; LayerRelativePosition position = LPOS_ABOVE; - if (dialog._position_visible) { Gtk::ListStore::iterator activeRow(dialog._layer_position_combo.get_active()); position = activeRow->get_value(dialog._dropdown_columns.position); + int index = dialog._layer_position_combo.get_active_row_number(); + Inkscape::Preferences::get()->setInt("/dialogs/layerProp/addLayerPosition", index); } Glib::ustring name(dialog._layer_name_entry.get_text()); if (name.empty()) diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 2c9b6c0cf9..ed64e61134 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -697,26 +697,26 @@ ObjectsPanel::ObjectsPanel() : auto *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( INKSCAPE_ICON("object-hidden"), INKSCAPE_ICON("object-visible"))); int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1; - eyeRenderer->signal_toggled().connect(sigc::mem_fun(*this, &ObjectsPanel::toggleVisible)); if (auto eye = _tree.get_column(visibleColNum)) { eye->add_attribute(eyeRenderer->property_active(), _model->_colInvisible); eye->add_attribute(eyeRenderer->property_cell_background_rgba(), _model->_colBgColor); eye->add_attribute(eyeRenderer->property_activatable(), _model->_colHover); eye->add_attribute(eyeRenderer->property_gossamer(), _model->_colAncestorInvisible); eye->set_fixed_width(icon_col_width); + _eye_column = eye; } // Unlocked icon Inkscape::UI::Widget::ImageToggler * lockRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked"))); int lockedColNum = _tree.append_column("lock", *lockRenderer) - 1; - lockRenderer->signal_toggled().connect(sigc::mem_fun(*this, &ObjectsPanel::toggleLocked)); if (auto lock = _tree.get_column(lockedColNum)) { lock->add_attribute(lockRenderer->property_active(), _model->_colLocked); lock->add_attribute(lockRenderer->property_cell_background_rgba(), _model->_colBgColor); lock->add_attribute(lockRenderer->property_activatable(), _model->_colHover); lock->add_attribute(lockRenderer->property_gossamer(), _model->_colAncestorLocked); lock->set_fixed_width(icon_col_width); + _lock_column = lock; } // hierarchy indicator - using item's layer highlight color @@ -939,11 +939,20 @@ Gtk::Button* ObjectsPanel::_addBarButton(char const* iconName, char const* toolt * Sets visibility of items in the tree * @param iter Current item in the tree */ -void ObjectsPanel::toggleVisible(const Glib::ustring& path) +bool ObjectsPanel::toggleVisible(GdkEventButton* event, Gtk::TreeModel::Row row) { - Gtk::TreeModel::Row row = *_store->get_iter(path); - if (SPItem* item = getItem(row)) - item->setHidden(!row[_model->_colInvisible]); + if (SPItem* item = getItem(row)) { + if (event->state & GDK_SHIFT_MASK) { + // Toggle Visible for layers (hide all other layers) + if (auto desktop = getDesktop()) { + desktop->toggleLayerSolo(item); + DocumentUndo::done(desktop->getDocument(), SP_VERB_LAYER_SOLO, _("Toggle layer solo")); + } + } else { + item->setHidden(!row[_model->_colInvisible]); + } + } + return true; } /** @@ -951,11 +960,20 @@ void ObjectsPanel::toggleVisible(const Glib::ustring& path) * @param iter Current item in the tree * @param locked Whether the item should be locked */ -void ObjectsPanel::toggleLocked(const Glib::ustring& path) +bool ObjectsPanel::toggleLocked(GdkEventButton* event, Gtk::TreeModel::Row row) { - Gtk::TreeModel::Row row = *_store->get_iter(path); - if (SPItem* item = getItem(row)) - item->setLocked(!row[_model->_colLocked]); + if (SPItem* item = getItem(row)) { + if (event->state & GDK_SHIFT_MASK) { + // Toggle lock for layers (lock all other layers) + if (auto desktop = getDesktop()) { + desktop->toggleLockOtherLayers(item); + DocumentUndo::done(desktop->getDocument(), SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); + } + } else { + item->setHidden(!row[_model->_colInvisible]); + } + } + return true; } /** @@ -1031,6 +1049,15 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) Gtk::TreeViewColumn* col = nullptr; int x, y; if (_tree.get_path_at_pos((int)event->x, (int)event->y, path, col, x, y)) { + if (auto row = *_store->get_iter(path)) { + if (event->type == GDK_BUTTON_RELEASE) { + if (col == _eye_column) { + return toggleVisible(event, row); + } else if (col == _lock_column) { + return toggleLocked(event, row); + } + } + } // Only the label reacts to clicks, nothing else, only need to test horz Gdk::Rectangle r; _tree.get_cell_area(path, *_name_column, r); @@ -1052,23 +1079,26 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) SPGroup *group = SP_GROUP(item); // Load the right click menu - if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - ContextMenu* menu = new ContextMenu(getDesktop(), item); - menu->show(); - menu->popup_at_pointer(nullptr); - return true; - } + const bool context_menu = event->type == GDK_BUTTON_PRESS && event->button == 3; - // Select items on button release to not confuse drag - if (!_is_editing && event->type == GDK_BUTTON_RELEASE) { + // Select items on button release to not confuse drag (unless it's a right-click) + // Right-click selects too to set up the stage for context menu which frequently relies on current selection! + if (!_is_editing && (event->type == GDK_BUTTON_RELEASE || context_menu)) { if (event->state & GDK_SHIFT_MASK) { // Select everything between this row and the already seleced item selection->setBetween(item); } else if (event->state & GDK_CONTROL_MASK) { selection->toggle(item); } else if (group && group->layerMode() == SPGroup::LAYER) { + // if right-clicking on a layer, make it current for context menu actions to work correctly + if (context_menu) { + if (getDesktop()->currentLayer() != item) { + selection->clear(); + getDesktop()->setCurrentLayer(item); + } + } // Clicking on layers firstly switches to that layer. - if(selection->includes(item)) { + else if (selection->includes(item)) { selection->clear(); } else if (_layer != item) { selection->clear(); @@ -1079,6 +1109,12 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) } else { selection->set(item); } + + if (context_menu) { + ContextMenu *menu = new ContextMenu(getDesktop(), item); + menu->show(); + menu->popup_at_pointer(nullptr); + } return true; } else { // Remember the item for we are about to drag it! diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h index 729acb718a..54382a3dcd 100644 --- a/src/ui/dialog/objects.h +++ b/src/ui/dialog/objects.h @@ -107,6 +107,8 @@ private: Gtk::TreeView _tree; Gtk::CellRendererText *_text_renderer; Gtk::TreeView::Column *_name_column; + Gtk::TreeView::Column *_eye_column = nullptr; + Gtk::TreeView::Column *_lock_column = nullptr; Gtk::Box _buttonsRow; Gtk::Box _buttonsPrimary; Gtk::Box _buttonsSecondary; @@ -123,8 +125,8 @@ private: void _fireAction( unsigned int code ); void _objects_toggle(); - void toggleVisible(const Glib::ustring& path); - void toggleLocked(const Glib::ustring& path); + bool toggleVisible(GdkEventButton* event, Gtk::TreeModel::Row row); + bool toggleLocked(GdkEventButton* event, Gtk::TreeModel::Row row); bool _handleButtonEvent(GdkEventButton *event); bool _handleKeyEvent(GdkEventKey *event); diff --git a/src/ui/themes.cpp b/src/ui/themes.cpp index 617a6e21f8..ffb616cae8 100644 --- a/src/ui/themes.cpp +++ b/src/ui/themes.cpp @@ -464,43 +464,36 @@ bool ThemeContext::isCurrentThemeDark(Gtk::Container *window) return dark; } -// extract "default" highlight colors from style.css -std::vector load_highlight_colors(bool dark_theme) { +/** + * Load the highlight colours from the current theme. If the theme changes + * you can call this function again to refresh the list. + */ +std::vector ThemeContext::getHighlightColors(Gtk::Window *window) +{ std::vector colors; - auto css = Gtk::CssProvider::create(); - auto path = Inkscape::IO::Resource::get_filename(Inkscape::IO::Resource::UIS, "style.css"); + if (!window) return colors; - if (css->load_from_path(path)) { - auto parent = std::make_unique(); - auto parent_ctx = parent->get_style_context(); - parent_ctx->add_class(dark_theme ? "dark" : "light"); + Glib::ustring name = "highlight-color-"; - auto widget = std::make_unique(); - parent->pack_start(*widget); - auto ctx = widget->get_style_context(); + for (int i = 1; i <= 8; ++i) { + auto context = Gtk::StyleContext::create(); - // extract colors from CSS - ctx->add_provider(css, GTK_STYLE_PROVIDER_PRIORITY_USER); + // The highlight colors will be attached to a GtkWidget + // but it isn't neccessary to use this in the .css file. + auto path = window->get_style_context()->get_path(); + path.path_append_type(Gtk::Widget::get_type()); + path.iter_add_class(-1, name + Glib::ustring::format(i)); + context->set_path(path); - Glib::ustring name = "highlight-color-"; - // 8 colors with no easy way to detect number of classes - for (int i = 1; i <= 8; ++i) { - auto class_name = name + Glib::ustring::format(i); - ctx->add_class(class_name); - auto color = ctx->get_color(); - guint32 rgba = - gint32(0xff * color.get_red()) << 24 | - gint32(0xff * color.get_green()) << 16 | - gint32(0xff * color.get_blue()) << 8 | - gint32(0xff * color.get_alpha()); - colors.push_back(rgba); - ctx->remove_class(class_name); - } - } - else { - g_warning("Error loading highlight colors from %s", path.c_str()); + // Get the color from the new context + auto color = context->get_color(); + guint32 rgba = + gint32(0xff * color.get_red()) << 24 | + gint32(0xff * color.get_green()) << 16 | + gint32(0xff * color.get_blue()) << 8 | + gint32(0xff * color.get_alpha()); + colors.push_back(rgba); } - return colors; } diff --git a/src/ui/themes.h b/src/ui/themes.h index 56c493e267..bf080e61bb 100644 --- a/src/ui/themes.h +++ b/src/ui/themes.h @@ -54,6 +54,8 @@ sigc::signal getChangeThemeSignal() { return _signal_change_theme;} // True if current theme (applied one) is dark bool isCurrentThemeDark(Gtk::Container *window); +static std::vector getHighlightColors(Gtk::Window *window); + private: // user change theme sigc::signal _signal_change_theme; @@ -65,9 +67,6 @@ private: std::unique_ptr _spinbutton_observer; }; -// load default highlight colors (for dark or light theme) -std::vector load_highlight_colors(bool dark_theme); - } } #endif /* !UI_THEMES_H_SEEN */ -- GitLab From 287c7c8eaf90fbf90f68c6a567f3a04d8a319e3a Mon Sep 17 00:00:00 2001 From: mike kowalski Date: Sat, 30 Oct 2021 18:57:02 -0700 Subject: [PATCH 8/9] label editing fix --- src/ui/dialog/objects.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index ed64e61134..9b83b526f5 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -995,6 +995,11 @@ bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) return true; } break; + + // space and return enter label editing mode; leave them for the tree to handle + case GDK_KEY_Return: + case GDK_KEY_space: + return false; } // invoke user defined shortcuts first -- GitLab From 87f304c9c54e526247ef16fa19ee41fe7ae1b586 Mon Sep 17 00:00:00 2001 From: mike kowalski Date: Sun, 31 Oct 2021 08:41:42 -0700 Subject: [PATCH 9/9] another label editing fix --- src/object/sp-item-group.cpp | 18 ++++++++++++++++++ src/object/sp-item-group.h | 11 +++++++++++ src/ui/contextmenu.cpp | 28 +++++----------------------- src/ui/dialog/objects.cpp | 9 +++++++++ 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index 571f394460..c42d59591d 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -1050,6 +1050,24 @@ void set_default_highlight_colors(std::vector colors) { std::swap(default_highlights, colors); } +SPGroup* sp_item_get_layer(SPObject* item) { + if (auto group = dynamic_cast(item)) { + if (group->layerMode() == SPGroup::LAYER) { + return group; + } + } + return nullptr; +} + +SPGroup* sp_item_get_group(SPObject* item) { + if (auto group = dynamic_cast(item)) { + if (group->layerMode() == SPGroup::GROUP) { + return group; + } + } + return nullptr; +} + /* Local Variables: mode:c++ diff --git a/src/object/sp-item-group.h b/src/object/sp-item-group.h index fe2e8a54eb..e1a2879868 100644 --- a/src/object/sp-item-group.h +++ b/src/object/sp-item-group.h @@ -115,6 +115,17 @@ inline bool SP_IS_LAYER(SPObject const *obj) return group && group->layerMode() == SPGroup::LAYER; } +/** + * return group object if it represents a layer or null otherwise + */ +SPGroup* sp_item_get_layer(SPObject* item); + +/** + * return group object if it represents a group that is not marked as layer or mask helper + */ +SPGroup* sp_item_get_group(SPObject* item); + + void set_default_highlight_colors(std::vector colors); #endif diff --git a/src/ui/contextmenu.cpp b/src/ui/contextmenu.cpp index 4e4dde48c8..0e1b7acdcc 100644 --- a/src/ui/contextmenu.cpp +++ b/src/ui/contextmenu.cpp @@ -67,24 +67,6 @@ using Inkscape::DocumentUndo; static bool temporarily_block_actions = false; -SPGroup* get_layer(SPObject* object) { - if (auto group = dynamic_cast(object)) { - if (group->layerMode() == SPGroup::LAYER) { - return group; - } - } - return nullptr; -} - -SPGroup* get_group(SPObject* object) { - if (auto group = dynamic_cast(object)) { - if (group->layerMode() == SPGroup::GROUP) { - return group; - } - } - return nullptr; -} - ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : _item(item), MIGroup(), @@ -97,7 +79,7 @@ ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : Inkscape::Preferences *prefs = Inkscape::Preferences::get(); _show_icons = prefs->getInt("/theme/menuIcons_canvas", true); - auto layer = get_layer(_object); + auto layer = sp_item_get_layer(_object); AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_UNDO)); AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_REDO)); @@ -337,7 +319,7 @@ void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb) void ContextMenu::MakeObjectMenu() { if (SP_IS_ITEM(_object)) { - MakeItemMenu(get_layer(_object)); + MakeItemMenu(sp_item_get_layer(_object)); } if (SP_IS_GROUP(_object)) { @@ -645,7 +627,7 @@ void ContextMenu::fireAction(unsigned int code) { // group and layer menu void ContextMenu::MakeGroupMenu(SPGroup* item) { - if (auto layer = get_layer(item)) { + if (auto layer = sp_item_get_layer(item)) { // layer-specific commands AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_NEW)); AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_LAYER_RENAME)); @@ -662,11 +644,11 @@ void ContextMenu::MakeGroupMenu(SPGroup* item) // transform layer into group append_item(_("Layer to group"), false).connect([=]() { sp_group_layer_transform(_desktop->doc(), layer, SPGroup::GROUP); }); } - else if (auto group = get_group(item)) { + else if (auto group = sp_item_get_group(item)) { /* Ungroup */ append_item(_("_Ungroup"), true).connect(sigc::mem_fun(*this, &ContextMenu::ActivateUngroup)); - if (auto parent = get_layer(group->parent)) { + if (auto parent = sp_item_get_layer(group->parent)) { // transform group into layer append_item(_("Group to layer"), false).connect([=](){ sp_group_layer_transform(_desktop->doc(), group, SPGroup::LAYER); }); } diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 9b83b526f5..4116ba75fb 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -677,6 +677,15 @@ ObjectsPanel::ObjectsPanel() : _text_renderer = Gtk::manage(new Gtk::CellRendererText()); _text_renderer->property_editable() = true; _text_renderer->property_ellipsize().set_value(Pango::ELLIPSIZE_END); + _text_renderer->signal_editing_started().connect([=](Gtk::CellEditable*,const Glib::ustring&){ + _is_editing = true; + }); + _text_renderer->signal_editing_canceled().connect([=](){ + _is_editing = false; + }); + _text_renderer->signal_edited().connect([=](const Glib::ustring&,const Glib::ustring&){ + _is_editing = false; + }); const int icon_col_width = 24; auto icon_renderer = Gtk::manage(new Inkscape::UI::Widget::CellRendererItemIcon()); -- GitLab