diff --git a/share/ui/dialog-objects.glade b/share/ui/dialog-objects.glade index c0e9fbce5d4ca42ab9002884163079f722d9e43d..e9022d9e4c54a764614872b2feda1f44973b6a78 100644 --- a/share/ui/dialog-objects.glade +++ b/share/ui/dialog-objects.glade @@ -94,7 +94,7 @@ True True True - win.layer-new + win.layer-new-above none diff --git a/share/ui/style.css b/share/ui/style.css index 1988114fdc1018c7f3429a434fc30a1d54266f0e..4978ebdfa788f84289e80d0bdc329d054f136009 100644 --- a/share/ui/style.css +++ b/share/ui/style.css @@ -1276,4 +1276,9 @@ frame.flat > border { #ToolToolbar flowboxchild:selected { background-color:transparent; background-image:image(@theme_bg_color); -} \ No newline at end of file +} + +/* Adding some margins for popup dialogs, so the content is not touching the window borders */ +.popup-dialog-margins { + margin: 0.75em; +} diff --git a/src/actions/actions-layer.cpp b/src/actions/actions-layer.cpp index 9f77a1a9250459b850e1bbb93caf0fccabf2c982..68065ad549df0346d91d2bdc333a4b1d77ed86fa 100644 --- a/src/actions/actions-layer.cpp +++ b/src/actions/actions-layer.cpp @@ -21,12 +21,16 @@ #include "actions-helper.h" #include "desktop.h" #include "document-undo.h" +#include "document.h" #include "inkscape-application.h" #include "inkscape-window.h" #include "message-stack.h" #include "selection.h" #include "ui/icon-names.h" #include "ui/dialog/layer-properties.h" +#include "document-undo.h" +#include "layer-manager.h" +#include "object/sp-root.h" /* * A layer is a group element with a special Inkscape attribute (Inkscape:groupMode) set to @@ -47,6 +51,20 @@ layer_new(InkscapeWindow* win) Inkscape::UI::Dialog::LayerPropertiesDialog::showCreate(dt, dt->layerManager().currentLayer()); } +void +layer_new_above(InkscapeWindow* win) +{ + auto desktop = win->get_desktop(); + auto document = desktop->getDocument(); + auto current_layer = desktop->layerManager().currentLayer(); + auto new_layer = Inkscape::create_layer(document->getRoot(), current_layer, Inkscape::LPOS_ABOVE); + desktop->layerManager().renameLayer(new_layer, current_layer->label(), true); + desktop->getSelection()->clear(); + desktop->layerManager().setCurrentLayer(new_layer); + Inkscape::DocumentUndo::done(document, _("Add layer"), INKSCAPE_ICON("layer-new")); + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("New layer created.")); +} + void layer_duplicate (InkscapeWindow* win) { @@ -460,6 +478,7 @@ std::vector> raw_data_layer = { // clang-format off {"win.layer-new", N_("Add Layer"), "Layer", N_("Create a new layer")}, + {"win.layer-new-above", N_("Add Layer Above"), "Layer", N_("Create a new layer above current")}, {"win.layer-duplicate", N_("Duplicate Current Layer"), "Layer", N_("Duplicate the current layer")}, {"win.layer-delete", N_("Delete Current Layer"), "Layer", N_("Delete the current layer")}, {"win.layer-rename", N_("Rename Layer"), "Layer", N_("Rename the current layer")}, @@ -493,6 +512,7 @@ add_actions_layer(InkscapeWindow* win) { // clang-format off win->add_action("layer-new", sigc::bind(sigc::ptr_fun(&layer_new), win)); + win->add_action("layer-new-above", sigc::bind(sigc::ptr_fun(&layer_new_above), win)); win->add_action("layer-duplicate", sigc::bind(sigc::ptr_fun(&layer_duplicate), win)); win->add_action("layer-delete", sigc::bind(sigc::ptr_fun(&layer_delete), win)); win->add_action("layer-rename", sigc::bind(sigc::ptr_fun(&layer_rename), win)); diff --git a/src/layer-manager.h b/src/layer-manager.h index f0fb03b4182001036b7ad83bdfdf8a1bb33b77a9..e4b27e2415a33f893a309ca90c0abb117a5b6c25 100644 --- a/src/layer-manager.h +++ b/src/layer-manager.h @@ -81,8 +81,8 @@ private: enum LayerRelativePosition { LPOS_ABOVE, - LPOS_BELOW, LPOS_CHILD, + LPOS_BELOW, }; SPObject *create_layer(SPObject *root, SPObject *layer, LayerRelativePosition position); diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index 12c7f703084271225c39301809fb392c579923e7..eca8fbad609f75b385a93f689f64f60330b64dd1 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -42,7 +42,8 @@ LayerPropertiesDialog::LayerPropertiesDialog(LayerPropertiesDialogType type) , _close_button(_("_Cancel"), true) { auto mainVBox = get_content_area(); - _layout_table.set_row_spacing(4); + mainVBox->get_style_context()->add_class("popup-dialog-margins"); + _layout_table.set_row_spacing(8); _layout_table.set_column_spacing(4); // Layer name widgets @@ -58,7 +59,7 @@ LayerPropertiesDialog::LayerPropertiesDialog(LayerPropertiesDialogType type) _layer_name_entry.set_hexpand(); _layout_table.attach(_layer_name_entry, 1, 0, 1, 1); - UI::pack_start(*mainVBox, _layout_table, true, true, 4); + UI::pack_start(*mainVBox, _layout_table, true, true, 8); // Buttons _close_button.set_can_default(); @@ -138,12 +139,19 @@ void LayerPropertiesDialog::_close() void LayerPropertiesDialog::_doCreate() { LayerRelativePosition position = LPOS_ABOVE; + if (_position_visible) { - Gtk::ListStore::iterator activeRow(_layer_position_combo.get_active()); - position = activeRow->get_value(_dropdown_columns.position); - int index = _layer_position_combo.get_active_row_number(); + int index = 0; + if (_layer_position_radio[1].get_active()) { + position = LPOS_CHILD; + index = 1; + } else if (_layer_position_radio[2].get_active()) { + position = LPOS_BELOW; + index = 2; + } Preferences::get()->setInt("/dialogs/layerProp/addLayerPosition", index); } + Glib::ustring name(_layer_name_entry.get_text()); if (name.empty()) { return; @@ -228,44 +236,37 @@ void LayerPropertiesDialog::_setup() void LayerPropertiesDialog::_setup_position_controls() { if (!_layer || _desktop->getDocument()->getRoot() == _layer) { - // no layers yet, so option above/below/sublayer is useless + // no layers yet, so option above/below/sublayer is not applicable return; } _position_visible = true; - _dropdown_list = Gtk::ListStore::create(_dropdown_columns); - _layer_position_combo.set_model(_dropdown_list); - _layer_position_combo.pack_start(_label_renderer); - _layer_position_combo.set_cell_data_func(_label_renderer, - [=](Gtk::TreeModel::const_iterator const &row) { - _prepareLabelRenderer(row); - }); - - Gtk::ListStore::iterator row; - row = _dropdown_list->append(); - row->set_value(_dropdown_columns.position, LPOS_ABOVE); - row->set_value(_dropdown_columns.name, Glib::ustring(_("Above current"))); - _layer_position_combo.set_active(row); - row = _dropdown_list->append(); - row->set_value(_dropdown_columns.position, LPOS_BELOW); - row->set_value(_dropdown_columns.name, Glib::ustring(_("Below current"))); - row = _dropdown_list->append(); - row->set_value(_dropdown_columns.position, LPOS_CHILD); - row->set_value(_dropdown_columns.name, Glib::ustring(_("As sublayer of current"))); - - int position = 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); + _layer_position_label.set_valign(Gtk::ALIGN_START); + _layout_table.attach(_layer_position_label, 0, 1, 1, 1); - _layer_position_combo.set_halign(Gtk::ALIGN_FILL); - _layer_position_combo.set_valign(Gtk::ALIGN_FILL); - _layer_position_combo.set_hexpand(); - _layout_table.attach(_layer_position_combo, 1, 1, 1, 1); + int position = Preferences::get()->getIntLimited("/dialogs/layerProp/addLayerPosition", 0, 0, 2); - _layout_table.attach(_layer_position_label, 0, 1, 1, 1); + Gtk::RadioButtonGroup group; + _layer_position_radio[0].set_group(group); + _layer_position_radio[1].set_group(group); + _layer_position_radio[2].set_group(group); + _layer_position_radio[0].set_label(_("Above current")); + _layer_position_radio[1].set_label(_("As sublayer of current")); + _layer_position_radio[1].get_style_context()->add_class("indent"); + _layer_position_radio[2].set_label(_("Below current")); + _layer_position_radio[0].set_active(position == LPOS_ABOVE); + _layer_position_radio[1].set_active(position == LPOS_CHILD); + _layer_position_radio[2].set_active(position == LPOS_BELOW); + + auto& vbox = *Gtk::make_managed(Gtk::ORIENTATION_VERTICAL, 3); + UI::pack_start(vbox, _layer_position_radio[0], false, false); + UI::pack_start(vbox, _layer_position_radio[1], false, false); + UI::pack_start(vbox, _layer_position_radio[2], false, false); + + _layout_table.attach(vbox, 1, 1, 1, 1); show_all_children(); } diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h index 9ab3fe6cf39e9cb72ef849dd7fc64ce53556d197..c4527201470ec4f2fff96905aa5eefdbd6ca9a66 100644 --- a/src/ui/dialog/layer-properties.h +++ b/src/ui/dialog/layer-properties.h @@ -22,6 +22,8 @@ #include // Gtk::EventSequenceState #include #include +#include +#include #include #include #include @@ -84,7 +86,7 @@ private: Gtk::Label _layer_name_label; Gtk::Entry _layer_name_entry; Gtk::Label _layer_position_label; - Gtk::ComboBox _layer_position_combo; + Gtk::RadioButton _layer_position_radio[3]; Gtk::Grid _layout_table; bool _position_visible = false; @@ -114,7 +116,6 @@ private: PositionDropdownColumns _dropdown_columns; Gtk::CellRendererText _label_renderer; - Glib::RefPtr _dropdown_list; Gtk::Button _close_button; Gtk::Button _apply_button; diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 812ea383bdb3c5f8b4267462d701680f56fb3cef..27aaab96d2fe572a0d665ca144aea1f1627f0e48 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -963,6 +963,15 @@ ObjectsPanel::ObjectsPanel() { selection_color = get_color_with_class(_tree.get_style_context(), "theme_selected_bg_color"); }; set_selection_color(); + auto enter_layer_label_editing_mode = [=]() { + layerChanged(getDesktop()->layerManager().currentLayer()); + auto path = getWatcher(_layer->getRepr())->getTreePath(); + _tree.set_cursor(path, *_tree.get_column(0), true /* start_editing */); + _is_editing = true; + }; + auto& add_layer_btn = get_widget(_builder, "insert-layer"); + add_layer_btn.signal_clicked().connect(enter_layer_label_editing_mode); + _tree_style = _tree.signal_style_updated().connect([=](){ set_selection_color(); @@ -1638,7 +1647,8 @@ Gtk::EventSequenceState ObjectsPanel::on_click(Gtk::GestureMultiPress const &ges // true == hide menu item for opening this dialog! auto menu = std::make_shared(getDesktop(), item, true); - UI::popup_at(*menu, *this, ex, ey); + // popup context menu pointing to the clicked tree row: + UI::popup_at(*menu, _tree, ex, ey); UI::on_hide_reset(std::move(menu)); } else if (should_set_current_layer()) { getDesktop()->layerManager().setCurrentLayer(item, true);