// SPDX-License-Identifier: GPL-2.0-or-later /** * @file * Dialog for adding a live path effect. * * Author: * * Copyright (C) 2012 Authors * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ #include "livepatheffect-add.h" #include #include #include "desktop.h" #include "io/resource.h" #include "live_effects/effect.h" #include "object/sp-clippath.h" #include "object/sp-item-group.h" #include "object/sp-mask.h" #include "object/sp-path.h" #include "object/sp-shape.h" #include "preferences.h" #include "ui/widget/canvas.h" #include "ui/themes.h" #include "ui/util.h" namespace Inkscape { namespace UI { namespace Dialog { bool sp_has_fav(Glib::ustring effect) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring favlist = prefs->getString("/dialogs/livepatheffect/favs"); size_t pos = favlist.find(effect); if (pos != std::string::npos) { return true; } return false; } void sp_add_fav(Glib::ustring effect) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring favlist = prefs->getString("/dialogs/livepatheffect/favs"); if (!sp_has_fav(effect)) { prefs->setString("/dialogs/livepatheffect/favs", favlist + effect + ";"); } } void sp_remove_fav(Glib::ustring effect) { if (sp_has_fav(effect)) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring favlist = prefs->getString("/dialogs/livepatheffect/favs"); effect += ";"; size_t pos = favlist.find(effect); if (pos != std::string::npos) { favlist.erase(pos, effect.length()); prefs->setString("/dialogs/livepatheffect/favs", favlist); } } } void sp_add_top_window_classes_callback(Gtk::Widget *widg) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { Gtk::Widget *canvas = desktop->canvas; Gtk::Window *toplevel_window = dynamic_cast(canvas->get_toplevel()); if (toplevel_window) { Gtk::Window *current_window = dynamic_cast(widg); if (!current_window) { current_window = dynamic_cast(widg->get_toplevel()); } if (current_window) { if (toplevel_window->get_style_context()->has_class("dark")) { current_window->get_style_context()->add_class("dark"); current_window->get_style_context()->remove_class("bright"); } else { current_window->get_style_context()->add_class("bright"); current_window->get_style_context()->remove_class("dark"); } if (toplevel_window->get_style_context()->has_class("symbolic")) { current_window->get_style_context()->add_class("symbolic"); current_window->get_style_context()->remove_class("regular"); } else { current_window->get_style_context()->remove_class("symbolic"); current_window->get_style_context()->add_class("regular"); } } } } } void sp_add_top_window_classes(Gtk::Widget *widg) { if (!widg) { return; } if (!widg->get_realized()) { widg->signal_realize().connect(sigc::bind(sigc::ptr_fun(&sp_add_top_window_classes_callback), widg)); } else { sp_add_top_window_classes_callback(widg); } } bool LivePathEffectAdd::mouseover(GdkEventCrossing *evt, GtkWidget *wdg) { GdkDisplay *display = gdk_display_get_default(); GdkCursor *cursor = gdk_cursor_new_for_display(display, GDK_HAND2); GdkWindow *window = gtk_widget_get_window(wdg); gdk_window_set_cursor(window, cursor); g_object_unref(cursor); return true; } bool LivePathEffectAdd::mouseout(GdkEventCrossing *evt, GtkWidget *wdg) { GdkWindow *window = gtk_widget_get_window(wdg); gdk_window_set_cursor(window, nullptr); hide_pop_description(evt); return true; } LivePathEffectAdd::LivePathEffectAdd() : converter(Inkscape::LivePathEffect::LPETypeConverter) , _applied(false) , _showfavs(false) { auto gladefile = get_filename_string(Inkscape::IO::Resource::UIS, "dialog-livepatheffect-add.glade"); try { _builder = Gtk::Builder::create_from_file(gladefile); } catch (const Glib::Error &ex) { g_warning("Glade file loading failed for path effect dialog"); return; } _builder->get_widget("LPEDialogSelector", _LPEDialogSelector); _builder->get_widget("LPESelectorFlowBox", _LPESelectorFlowBox); _builder->get_widget("LPESelectorEffectInfoPop", _LPESelectorEffectInfoPop); _builder->get_widget("LPEFilter", _LPEFilter); _builder->get_widget("LPEInfo", _LPEInfo); _builder->get_widget("LPEExperimental", _LPEExperimental); _builder->get_widget("LPEScrolled", _LPEScrolled); _builder->get_widget("LPESelectorEffectEventFavShow", _LPESelectorEffectEventFavShow); _builder->get_widget("LPESelectorEffectInfoEventBox", _LPESelectorEffectInfoEventBox); _builder->get_widget("LPESelectorEffectRadioPackLess", _LPESelectorEffectRadioPackLess); _builder->get_widget("LPESelectorEffectRadioPackMore", _LPESelectorEffectRadioPackMore); _builder->get_widget("LPESelectorEffectRadioList", _LPESelectorEffectRadioList); _LPEFilter->signal_search_changed().connect(sigc::mem_fun(*this, &LivePathEffectAdd::on_search)); _LPEDialogSelector->add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK | Gdk::KEY_PRESS_MASK); _LPESelectorFlowBox->signal_set_focus_child().connect(sigc::mem_fun(*this, &LivePathEffectAdd::on_focus)); gladefile = get_filename_string(Inkscape::IO::Resource::UIS, "dialog-livepatheffect-effect.glade"); for (int i = 0; i < static_cast(converter._length); ++i) { Glib::RefPtr builder_effect; try { builder_effect = Gtk::Builder::create_from_file(gladefile); } catch (const Glib::Error &ex) { g_warning("Glade file loading failed for filter effect dialog"); return; } const LivePathEffect::EnumEffectData *data = &converter.data(i); Gtk::EventBox *LPESelectorEffect; builder_effect->get_widget("LPESelectorEffect", LPESelectorEffect); LPESelectorEffect->signal_button_press_event().connect( sigc::bind, const LivePathEffect::EnumEffectData *>( sigc::mem_fun(*this, &LivePathEffectAdd::apply), builder_effect, &converter.data(i))); Gtk::EventBox *LPESelectorEffectEventExpander; builder_effect->get_widget("LPESelectorEffectEventExpander", LPESelectorEffectEventExpander); LPESelectorEffectEventExpander->signal_button_press_event().connect( sigc::bind>(sigc::mem_fun(*this, &LivePathEffectAdd::expand), builder_effect)); LPESelectorEffectEventExpander->signal_enter_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseover), GTK_WIDGET(LPESelectorEffect->gobj()))); LPESelectorEffectEventExpander->signal_leave_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseout), GTK_WIDGET(LPESelectorEffect->gobj()))); Gtk::Label *LPEName; builder_effect->get_widget("LPEName", LPEName); const Glib::ustring label = g_dpgettext2(nullptr, "path effect", converter.get_label(data->id).c_str()); const Glib::ustring untranslated_label = converter.get_label(data->id); if (untranslated_label == label) { LPEName->set_text(label); } else { LPEName->set_markup((label + "\n" + untranslated_label + "").c_str()); } Gtk::Label *LPEDescription; builder_effect->get_widget("LPEDescription", LPEDescription); const Glib::ustring description = _(converter.get_description(data->id).c_str()); LPEDescription->set_text(description); Gtk::ToggleButton *LPEExperimentalToggle; builder_effect->get_widget("LPEExperimentalToggle", LPEExperimentalToggle); bool active = converter.get_experimental(data->id) ? true : false; LPEExperimentalToggle->set_active(active); Gtk::Image *LPEIcon; builder_effect->get_widget("LPEIcon", LPEIcon); LPEIcon->set_from_icon_name(converter.get_icon(data->id), Gtk::IconSize(Gtk::ICON_SIZE_DIALOG)); Gtk::EventBox *LPESelectorEffectEventInfo; builder_effect->get_widget("LPESelectorEffectEventInfo", LPESelectorEffectEventInfo); LPESelectorEffectEventInfo->signal_enter_notify_event().connect(sigc::bind>( sigc::mem_fun(*this, &LivePathEffectAdd::pop_description), builder_effect)); Gtk::EventBox *LPESelectorEffectEventFav; builder_effect->get_widget("LPESelectorEffectEventFav", LPESelectorEffectEventFav); Gtk::Image *fav = dynamic_cast(LPESelectorEffectEventFav->get_child()); if (sp_has_fav(LPEName->get_text())) { fav->set_from_icon_name("draw-star", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); } else { fav->set_from_icon_name("draw-star-outline", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); } Gtk::EventBox *LPESelectorEffectEventFavTop; builder_effect->get_widget("LPESelectorEffectEventFavTop", LPESelectorEffectEventFavTop); LPESelectorEffectEventFav->signal_button_press_event().connect(sigc::bind>( sigc::mem_fun(*this, &LivePathEffectAdd::fav_toggler), builder_effect)); LPESelectorEffectEventFavTop->signal_button_press_event().connect(sigc::bind>( sigc::mem_fun(*this, &LivePathEffectAdd::fav_toggler), builder_effect)); Gtk::Image *favtop = dynamic_cast(LPESelectorEffectEventFavTop->get_child()); if (sp_has_fav(LPEName->get_text())) { favtop->set_from_icon_name("draw-star", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); } else { favtop->set_from_icon_name("draw-star-outline", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); } Gtk::EventBox *LPESelectorEffectEventApply; builder_effect->get_widget("LPESelectorEffectEventApply", LPESelectorEffectEventApply); LPESelectorEffectEventApply->signal_button_press_event().connect( sigc::bind, const LivePathEffect::EnumEffectData *>( sigc::mem_fun(*this, &LivePathEffectAdd::apply), builder_effect, &converter.data(i))); LPESelectorEffectEventApply->signal_enter_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseover), GTK_WIDGET(LPESelectorEffectEventApply->gobj()))); LPESelectorEffectEventApply->signal_leave_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseout), GTK_WIDGET(LPESelectorEffectEventApply->gobj()))); Gtk::ButtonBox *LPESelectorButtonBox; builder_effect->get_widget("LPESelectorButtonBox", LPESelectorButtonBox); LPESelectorButtonBox->signal_enter_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseover), GTK_WIDGET(LPESelectorEffect->gobj()))); LPESelectorButtonBox->signal_leave_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseout), GTK_WIDGET(LPESelectorEffect->gobj()))); LPESelectorEffect->signal_enter_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseover), GTK_WIDGET(LPESelectorEffect->gobj()))); LPESelectorEffect->signal_leave_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseout), GTK_WIDGET(LPESelectorEffect->gobj()))); _LPESelectorFlowBox->insert(*LPESelectorEffect, i); LPESelectorEffect->get_parent()->signal_key_press_event().connect( sigc::bind, const LivePathEffect::EnumEffectData *>( sigc::mem_fun(*this, &LivePathEffectAdd::on_press_enter), builder_effect, &converter.data(i))); LPESelectorEffect->get_parent()->get_style_context()->add_class( ("LPEIndex" + Glib::ustring::format(i)).c_str()); } _LPESelectorFlowBox->set_activate_on_single_click(false); _visiblelpe = _LPESelectorFlowBox->get_children().size(); _LPEInfo->set_visible(false); _LPESelectorEffectRadioPackLess->signal_clicked().connect( sigc::bind(sigc::mem_fun(*this, &LivePathEffectAdd::viewChanged), 0)); _LPESelectorEffectRadioPackMore->signal_clicked().connect( sigc::bind(sigc::mem_fun(*this, &LivePathEffectAdd::viewChanged), 1)); _LPESelectorEffectRadioList->signal_clicked().connect( sigc::bind(sigc::mem_fun(*this, &LivePathEffectAdd::viewChanged), 2)); _LPESelectorEffectEventFavShow->signal_enter_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseover), GTK_WIDGET(_LPESelectorEffectEventFavShow->gobj()))); _LPESelectorEffectEventFavShow->signal_leave_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseout), GTK_WIDGET(_LPESelectorEffectEventFavShow->gobj()))); _LPESelectorEffectEventFavShow->signal_button_press_event().connect( sigc::mem_fun(*this, &LivePathEffectAdd::show_fav_toggler)); _LPESelectorEffectInfoEventBox->signal_leave_notify_event().connect( sigc::mem_fun(*this, &LivePathEffectAdd::hide_pop_description)); _LPESelectorEffectInfoEventBox->signal_enter_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseover), GTK_WIDGET(_LPESelectorEffectInfoEventBox->gobj()))); _LPESelectorEffectInfoEventBox->signal_leave_notify_event().connect(sigc::bind( sigc::mem_fun(*this, &LivePathEffectAdd::mouseout), GTK_WIDGET(_LPESelectorEffectInfoEventBox->gobj()))); _LPEExperimental->property_active().signal_changed().connect( sigc::mem_fun(*this, &LivePathEffectAdd::reload_effect_list)); Gtk::Window *window = SP_ACTIVE_DESKTOP->getToplevel(); int width; int height; window->get_size(width, height); _LPEDialogSelector->resize(std::min(width - 300, 1440), std::min(height - 300, 900)); _LPESelectorFlowBox->set_focus_vadjustment(_LPEScrolled->get_vadjustment()); _LPEDialogSelector->show_all_children(); _lasteffect = nullptr; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint mode = prefs->getInt("/dialogs/livepatheffect/dialogmode", 0); switch (mode) { case 0: _LPESelectorEffectRadioPackLess->set_active(); viewChanged(0); break; case 1: _LPESelectorEffectRadioPackMore->set_active(); viewChanged(1); break; default: _LPESelectorEffectRadioList->set_active(); viewChanged(2); } Gtk::Widget *widg = dynamic_cast(_LPEDialogSelector); INKSCAPE.themecontext->getChangeThemeSignal().connect(sigc::bind(sigc::ptr_fun(sp_add_top_window_classes), widg)); sp_add_top_window_classes(widg); } const LivePathEffect::EnumEffectData *LivePathEffectAdd::getActiveData() { return instance()._to_add; } void LivePathEffectAdd::viewChanged(gint mode) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool changed = false; if (mode == 2 && !_LPEDialogSelector->get_style_context()->has_class("LPEList")) { _LPEDialogSelector->get_style_context()->add_class("LPEList"); _LPEDialogSelector->get_style_context()->remove_class("LPEPackLess"); _LPEDialogSelector->get_style_context()->remove_class("LPEPackMore"); _LPESelectorFlowBox->set_max_children_per_line(1); changed = true; } else if (mode == 1 && !_LPEDialogSelector->get_style_context()->has_class("LPEPackMore")) { _LPEDialogSelector->get_style_context()->remove_class("LPEList"); _LPEDialogSelector->get_style_context()->remove_class("LPEPackLess"); _LPEDialogSelector->get_style_context()->add_class("LPEPackMore"); _LPESelectorFlowBox->set_max_children_per_line(30); changed = true; } else if (mode == 0 && !_LPEDialogSelector->get_style_context()->has_class("LPEPackLess")) { _LPEDialogSelector->get_style_context()->remove_class("LPEList"); _LPEDialogSelector->get_style_context()->add_class("LPEPackLess"); _LPEDialogSelector->get_style_context()->remove_class("LPEPackMore"); _LPESelectorFlowBox->set_max_children_per_line(30); changed = true; } prefs->setInt("/dialogs/livepatheffect/dialogmode", mode); if (changed) { _LPESelectorFlowBox->unset_sort_func(); _LPESelectorFlowBox->set_sort_func(sigc::mem_fun(this, &LivePathEffectAdd::on_sort)); std::vector selected = _LPESelectorFlowBox->get_selected_children(); if (selected.size() == 1) { _LPESelectorFlowBox->get_selected_children()[0]->grab_focus(); } } } void LivePathEffectAdd::on_focus(Gtk::Widget *widget) { Gtk::FlowBoxChild *child = dynamic_cast(widget); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint mode = prefs->getInt("/dialogs/livepatheffect/dialogmode", 0); if (child && mode != 2) { for (auto i : _LPESelectorFlowBox->get_children()) { Gtk::FlowBoxChild *leitem = dynamic_cast(i); Gtk::EventBox *eventbox = dynamic_cast(leitem->get_child()); if (eventbox) { Gtk::Box *box = dynamic_cast(eventbox->get_child()); if (box) { std::vector contents = box->get_children(); Gtk::Box *actions = dynamic_cast(contents[5]); if (actions) { actions->set_visible(false); } Gtk::EventBox *expander = dynamic_cast(contents[4]); if (expander) { expander->set_visible(true); } } } } Gtk::EventBox *eventbox = dynamic_cast(child->get_child()); if (eventbox) { Gtk::Box *box = dynamic_cast(eventbox->get_child()); if (box) { std::vector contents = box->get_children(); Gtk::EventBox *expander = dynamic_cast(contents[4]); if (expander) { expander->set_visible(false); } } } child->show_all_children(); _LPESelectorFlowBox->select_child(*child); } } bool LivePathEffectAdd::pop_description(GdkEventCrossing *evt, Glib::RefPtr builder_effect) { Gtk::Image *LPESelectorEffectInfo; builder_effect->get_widget("LPESelectorEffectInfo", LPESelectorEffectInfo); _LPESelectorEffectInfoPop->set_relative_to(*LPESelectorEffectInfo); Gtk::Label *LPEName; builder_effect->get_widget("LPEName", LPEName); Gtk::Label *LPEDescription; builder_effect->get_widget("LPEDescription", LPEDescription); Gtk::Image *LPEIcon; builder_effect->get_widget("LPEIcon", LPEIcon); Gtk::Image *LPESelectorEffectInfoIcon; _builder->get_widget("LPESelectorEffectInfoIcon", LPESelectorEffectInfoIcon); LPESelectorEffectInfoIcon->set_from_icon_name(LPEIcon->get_icon_name(), Gtk::IconSize(Gtk::ICON_SIZE_DIALOG)); Gtk::Label *LPESelectorEffectInfoName; _builder->get_widget("LPESelectorEffectInfoName", LPESelectorEffectInfoName); LPESelectorEffectInfoName->set_text(LPEName->get_text()); Gtk::Label *LPESelectorEffectInfoDescription; _builder->get_widget("LPESelectorEffectInfoDescription", LPESelectorEffectInfoDescription); LPESelectorEffectInfoDescription->set_text(LPEDescription->get_text()); _LPESelectorEffectInfoPop->show(); return true; } bool LivePathEffectAdd::hide_pop_description(GdkEventCrossing *evt) { _LPESelectorEffectInfoPop->hide(); return true; } bool LivePathEffectAdd::fav_toggler(GdkEventButton *evt, Glib::RefPtr builder_effect) { Gtk::EventBox *LPESelectorEffect; builder_effect->get_widget("LPESelectorEffect", LPESelectorEffect); Gtk::Label *LPEName; builder_effect->get_widget("LPEName", LPEName); Gtk::Image *LPESelectorEffectFav; builder_effect->get_widget("LPESelectorEffectFav", LPESelectorEffectFav); Gtk::Image *LPESelectorEffectFavTop; builder_effect->get_widget("LPESelectorEffectFavTop", LPESelectorEffectFavTop); Gtk::EventBox *LPESelectorEffectEventFavTop; builder_effect->get_widget("LPESelectorEffectEventFavTop", LPESelectorEffectEventFavTop); if (LPESelectorEffectFav && LPESelectorEffectEventFavTop) { if (sp_has_fav(LPEName->get_text())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint mode = prefs->getInt("/dialogs/livepatheffect/dialogmode", 0); if (mode == 2) { LPESelectorEffectEventFavTop->set_visible(true); LPESelectorEffectEventFavTop->show(); } else { LPESelectorEffectEventFavTop->set_visible(false); LPESelectorEffectEventFavTop->hide(); } LPESelectorEffectFavTop->set_from_icon_name("draw-star-outline", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); LPESelectorEffectFav->set_from_icon_name("draw-star-outline", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); sp_remove_fav(LPEName->get_text()); LPESelectorEffect->get_parent()->get_style_context()->remove_class("lpefav"); LPESelectorEffect->get_parent()->get_style_context()->add_class("lpenormal"); LPESelectorEffect->get_parent()->get_style_context()->add_class("lpe"); if (_showfavs) { reload_effect_list(); } } else { LPESelectorEffectEventFavTop->set_visible(true); LPESelectorEffectEventFavTop->show(); LPESelectorEffectFavTop->set_from_icon_name("draw-star", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); LPESelectorEffectFav->set_from_icon_name("draw-star", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); sp_add_fav(LPEName->get_text()); LPESelectorEffect->get_parent()->get_style_context()->add_class("lpefav"); LPESelectorEffect->get_parent()->get_style_context()->remove_class("lpenormal"); LPESelectorEffect->get_parent()->get_style_context()->add_class("lpe"); } } return true; } bool LivePathEffectAdd::show_fav_toggler(GdkEventButton *evt) { _showfavs = !_showfavs; Gtk::Image *favimage = dynamic_cast(_LPESelectorEffectEventFavShow->get_child()); if (favimage) { if (_showfavs) { favimage->set_from_icon_name("draw-star", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); } else { favimage->set_from_icon_name("draw-star-outline", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); } } reload_effect_list(); return true; } bool LivePathEffectAdd::apply(GdkEventButton *evt, Glib::RefPtr builder_effect, const LivePathEffect::EnumEffectData *to_add) { _to_add = to_add; Gtk::EventBox *LPESelectorEffect; builder_effect->get_widget("LPESelectorEffect", LPESelectorEffect); Gtk::FlowBoxChild *flowboxchild = dynamic_cast(LPESelectorEffect->get_parent()); _LPESelectorFlowBox->select_child(*flowboxchild); if (flowboxchild && flowboxchild->get_style_context()->has_class("lpedisabled")) { return true; } _applied = true; _lasteffect = flowboxchild; _LPEDialogSelector->response(Gtk::RESPONSE_APPLY); _LPEDialogSelector->hide(); return true; } bool LivePathEffectAdd::on_press_enter(GdkEventKey *key, Glib::RefPtr builder_effect, const LivePathEffect::EnumEffectData *to_add) { if (key->keyval == 65293 || key->keyval == 65421) { _to_add = to_add; Gtk::EventBox *LPESelectorEffect; builder_effect->get_widget("LPESelectorEffect", LPESelectorEffect); Gtk::FlowBoxChild *flowboxchild = dynamic_cast(LPESelectorEffect->get_parent()); if (flowboxchild && flowboxchild->get_style_context()->has_class("lpedisabled")) { return true; } _applied = true; _lasteffect = flowboxchild; _LPEDialogSelector->response(Gtk::RESPONSE_APPLY); _LPEDialogSelector->hide(); return true; } return false; } bool LivePathEffectAdd::expand(GdkEventButton *evt, Glib::RefPtr builder_effect) { Gtk::EventBox *LPESelectorEffect; builder_effect->get_widget("LPESelectorEffect", LPESelectorEffect); Gtk::FlowBoxChild *child = dynamic_cast(LPESelectorEffect->get_parent()); if (child) { child->grab_focus(); } return true; } bool LivePathEffectAdd::on_filter(Gtk::FlowBoxChild *child) { std::vector classes = child->get_style_context()->list_classes(); int pos = 0; for (auto childclass : classes) { size_t s = childclass.find("LPEIndex", 0); if (s != -1) { childclass = childclass.erase(0, 8); pos = std::stoi(childclass.raw()); } } const LivePathEffect::EnumEffectData *data = &converter.data(pos); bool disable = false; if (_item_type == "group" && !converter.get_on_group(data->id)) { disable = true; } else if (_item_type == "shape" && !converter.get_on_shape(data->id)) { disable = true; } else if (_item_type == "path" && !converter.get_on_path(data->id)) { disable = true; } if (!_has_clip && data->id == Inkscape::LivePathEffect::POWERCLIP) { disable = true; } if (!_has_mask && data->id == Inkscape::LivePathEffect::POWERMASK) { disable = true; } if (disable) { child->get_style_context()->add_class("lpedisabled"); } else { child->get_style_context()->remove_class("lpedisabled"); } child->set_valign(Gtk::ALIGN_START); Gtk::EventBox *eventbox = dynamic_cast(child->get_child()); if (eventbox) { Gtk::Box *box = dynamic_cast(eventbox->get_child()); if (box) { std::vector contents = box->get_children(); Gtk::Overlay *overlay = dynamic_cast(contents[0]); std::vector content_overlay = overlay->get_children(); Gtk::Label *lpename = dynamic_cast(contents[1]); if (!sp_has_fav(lpename->get_text()) && _showfavs) { return false; } Gtk::ToggleButton *experimental = dynamic_cast(contents[3]); if (experimental) { if (experimental->get_active() && !_LPEExperimental->get_active()) { return false; } } Gtk::Label *lpedesc = dynamic_cast(contents[2]); if (lpedesc) { size_t s = lpedesc->get_text().uppercase().find(_LPEFilter->get_text().uppercase(), 0); if (s != -1) { _visiblelpe++; return true; } } if (_LPEFilter->get_text().length() < 1) { _visiblelpe++; return true; } if (lpename) { size_t s = lpename->get_text().uppercase().find(_LPEFilter->get_text().uppercase(), 0); if (s != -1) { _visiblelpe++; return true; } } } } return false; } void LivePathEffectAdd::reload_effect_list() { /* if(_LPEExperimental->get_active()) { _LPEExperimental->get_style_context()->add_class("active"); } else { _LPEExperimental->get_style_context()->remove_class("active"); } */ _visiblelpe = 0; _LPESelectorFlowBox->invalidate_filter(); if (_showfavs) { if (_visiblelpe == 0) { _LPEInfo->set_text(_("You don't have any favorites yet. Click on the favorites star again to see all LPEs.")); _LPEInfo->set_visible(true); _LPEInfo->get_style_context()->add_class("lpeinfowarn"); } else { _LPEInfo->set_text(_("These are your favorite effects")); _LPEInfo->set_visible(true); _LPEInfo->get_style_context()->add_class("lpeinfowarn"); } } else { _LPEInfo->set_text(_("Nothing found! Please try again with different search terms.")); _LPEInfo->set_visible(false); _LPEInfo->get_style_context()->remove_class("lpeinfowarn"); } } void LivePathEffectAdd::on_search() { _visiblelpe = 0; _LPESelectorFlowBox->invalidate_filter(); if (_showfavs) { if (_visiblelpe == 0) { _LPEInfo->set_text(_("Nothing found! Please try again with different search terms.")); _LPEInfo->set_visible(true); _LPEInfo->get_style_context()->add_class("lpeinfowarn"); } else { _LPEInfo->set_visible(true); _LPEInfo->get_style_context()->add_class("lpeinfowarn"); } } else { if (_visiblelpe == 0) { _LPEInfo->set_text(_("Nothing found! Please try again with different search terms.")); _LPEInfo->set_visible(true); _LPEInfo->get_style_context()->add_class("lpeinfowarn"); } else { _LPEInfo->set_visible(false); _LPEInfo->get_style_context()->remove_class("lpeinfowarn"); } } } int LivePathEffectAdd::on_sort(Gtk::FlowBoxChild *child1, Gtk::FlowBoxChild *child2) { Glib::ustring name1 = ""; Glib::ustring name2 = ""; Gtk::EventBox *eventbox = dynamic_cast(child1->get_child()); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint mode = prefs->getInt("/dialogs/livepatheffect/dialogmode", 0); if (mode == 2) { eventbox->set_halign(Gtk::ALIGN_START); } else { eventbox->set_halign(Gtk::ALIGN_CENTER); } if (eventbox) { Gtk::Box *box = dynamic_cast(eventbox->get_child()); if (mode == 2) { box->set_orientation(Gtk::ORIENTATION_HORIZONTAL); } else { box->set_orientation(Gtk::ORIENTATION_VERTICAL); } if (box) { std::vector contents = box->get_children(); Gtk::Label *lpename = dynamic_cast(contents[1]); name1 = lpename->get_text(); if (lpename) { if (mode == 2) { lpename->set_justify(Gtk::JUSTIFY_LEFT); lpename->set_halign(Gtk::ALIGN_START); lpename->set_valign(Gtk::ALIGN_CENTER); lpename->set_width_chars(-1); lpename->set_max_width_chars(-1); } else { lpename->set_justify(Gtk::JUSTIFY_CENTER); lpename->set_halign(Gtk::ALIGN_CENTER); lpename->set_valign(Gtk::ALIGN_CENTER); lpename->set_width_chars(14); lpename->set_max_width_chars(23); } } Gtk::EventBox *lpemore = dynamic_cast(contents[4]); if (lpemore) { if (mode == 2) { lpemore->hide(); } else { if (child1->is_selected()) { lpemore->hide(); } else { lpemore->show(); } } } Gtk::ButtonBox *lpebuttonbox = dynamic_cast(contents[5]); if (lpebuttonbox) { if (mode == 2) { lpebuttonbox->hide(); } else { if (child1->is_selected()) { lpebuttonbox->show(); } else { lpebuttonbox->hide(); } } } Gtk::Label *lpedesc = dynamic_cast(contents[2]); if (lpedesc) { if (mode == 2) { lpedesc->show(); lpedesc->set_justify(Gtk::JUSTIFY_LEFT); lpedesc->set_halign(Gtk::ALIGN_START); lpedesc->set_valign(Gtk::ALIGN_CENTER); lpedesc->set_ellipsize(Pango::ELLIPSIZE_END); } else { lpedesc->hide(); lpedesc->set_justify(Gtk::JUSTIFY_CENTER); lpedesc->set_halign(Gtk::ALIGN_CENTER); lpedesc->set_valign(Gtk::ALIGN_CENTER); lpedesc->set_ellipsize(Pango::ELLIPSIZE_NONE); } } Gtk::Overlay *overlay = dynamic_cast(contents[0]); if (overlay) { std::vector contents_overlay = overlay->get_children(); Gtk::Image *icon = dynamic_cast(contents_overlay[0]); if (icon) { if (mode == 2) { icon->set_pixel_size(40); icon->set_margin_end(25); overlay->set_margin_end(5); } else { icon->set_pixel_size(60); icon->set_margin_end(0); overlay->set_margin_end(0); } } Gtk::EventBox *LPESelectorEffectEventFavTop = dynamic_cast(contents_overlay[1]); if (LPESelectorEffectEventFavTop) { Gtk::Image *fav = dynamic_cast(LPESelectorEffectEventFavTop->get_child()); if (sp_has_fav(name1)) { fav->set_from_icon_name("draw-star", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); LPESelectorEffectEventFavTop->set_visible(true); LPESelectorEffectEventFavTop->show(); child1->get_style_context()->add_class("lpefav"); child1->get_style_context()->remove_class("lpenormal"); } else if (!sp_has_fav(name1)) { fav->set_from_icon_name("draw-star-outline", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); LPESelectorEffectEventFavTop->set_visible(false); LPESelectorEffectEventFavTop->hide(); child1->get_style_context()->remove_class("lpefav"); child1->get_style_context()->add_class("lpenormal"); } if (mode == 2) { LPESelectorEffectEventFavTop->set_visible(true); LPESelectorEffectEventFavTop->show(); LPESelectorEffectEventFavTop->set_halign(Gtk::ALIGN_END); LPESelectorEffectEventFavTop->set_valign(Gtk::ALIGN_CENTER); } else { LPESelectorEffectEventFavTop->set_halign(Gtk::ALIGN_END); LPESelectorEffectEventFavTop->set_valign(Gtk::ALIGN_START); } child1->get_style_context()->add_class("lpe"); } } } } eventbox = dynamic_cast(child2->get_child()); if (mode == 2) { eventbox->set_halign(Gtk::ALIGN_START); } else { eventbox->set_halign(Gtk::ALIGN_CENTER); } if (eventbox) { Gtk::Box *box = dynamic_cast(eventbox->get_child()); if (mode == 2) { box->set_orientation(Gtk::ORIENTATION_HORIZONTAL); } else { box->set_orientation(Gtk::ORIENTATION_VERTICAL); } if (box) { std::vector contents = box->get_children(); Gtk::Label *lpename = dynamic_cast(contents[1]); name2 = lpename->get_text(); if (lpename) { if (mode == 2) { lpename->set_justify(Gtk::JUSTIFY_LEFT); lpename->set_halign(Gtk::ALIGN_START); lpename->set_valign(Gtk::ALIGN_CENTER); lpename->set_width_chars(-1); lpename->set_max_width_chars(-1); } else { lpename->set_justify(Gtk::JUSTIFY_CENTER); lpename->set_halign(Gtk::ALIGN_CENTER); lpename->set_valign(Gtk::ALIGN_CENTER); lpename->set_width_chars(14); lpename->set_max_width_chars(23); } } Gtk::EventBox *lpemore = dynamic_cast(contents[4]); if (lpemore) { if (mode == 2) { lpemore->hide(); } else { if (child2->is_selected()) { lpemore->hide(); } else { lpemore->show(); } } } Gtk::ButtonBox *lpebuttonbox = dynamic_cast(contents[5]); if (lpebuttonbox) { if (mode == 2) { lpebuttonbox->hide(); } else { if (child2->is_selected()) { lpebuttonbox->show(); } else { lpebuttonbox->hide(); } } } Gtk::Label *lpedesc = dynamic_cast(contents[2]); if (lpedesc) { if (mode == 2) { lpedesc->show(); lpedesc->set_justify(Gtk::JUSTIFY_LEFT); lpedesc->set_halign(Gtk::ALIGN_START); lpedesc->set_valign(Gtk::ALIGN_CENTER); lpedesc->set_ellipsize(Pango::ELLIPSIZE_END); } else { lpedesc->hide(); lpedesc->set_justify(Gtk::JUSTIFY_CENTER); lpedesc->set_halign(Gtk::ALIGN_CENTER); lpedesc->set_valign(Gtk::ALIGN_CENTER); lpedesc->set_ellipsize(Pango::ELLIPSIZE_NONE); } } Gtk::Overlay *overlay = dynamic_cast(contents[0]); if (overlay) { std::vector contents_overlay = overlay->get_children(); Gtk::Image *icon = dynamic_cast(contents_overlay[0]); if (icon) { if (mode == 2) { icon->set_pixel_size(33); icon->set_margin_end(40); } else { icon->set_pixel_size(60); icon->set_margin_end(0); } } Gtk::EventBox *LPESelectorEffectEventFavTop = dynamic_cast(contents_overlay[1]); Gtk::Image *fav = dynamic_cast(LPESelectorEffectEventFavTop->get_child()); if (LPESelectorEffectEventFavTop) { if (sp_has_fav(name2)) { fav->set_from_icon_name("draw-star", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); LPESelectorEffectEventFavTop->set_visible(true); LPESelectorEffectEventFavTop->show(); child2->get_style_context()->add_class("lpefav"); child2->get_style_context()->remove_class("lpenormal"); } else if (!sp_has_fav(name2)) { fav->set_from_icon_name("draw-star-outline", Gtk::IconSize(Gtk::ICON_SIZE_SMALL_TOOLBAR)); LPESelectorEffectEventFavTop->set_visible(false); LPESelectorEffectEventFavTop->hide(); child2->get_style_context()->remove_class("lpefav"); child2->get_style_context()->add_class("lpenormal"); } if (mode == 2) { LPESelectorEffectEventFavTop->set_visible(true); LPESelectorEffectEventFavTop->show(); LPESelectorEffectEventFavTop->set_halign(Gtk::ALIGN_END); LPESelectorEffectEventFavTop->set_valign(Gtk::ALIGN_CENTER); } else { LPESelectorEffectEventFavTop->set_halign(Gtk::ALIGN_END); LPESelectorEffectEventFavTop->set_valign(Gtk::ALIGN_START); } child2->get_style_context()->add_class("lpe"); } } } } std::vector effect; effect.push_back(name1); effect.push_back(name2); sort(effect.begin(), effect.end()); /* if (sp_has_fav(name1) && sp_has_fav(name2)) { return effect[0] == name1?-1:1; } if (sp_has_fav(name1)) { return -1; } */ if (effect[0] == name1) { //&& !sp_has_fav(name2)) { return -1; } return 1; } void LivePathEffectAdd::onClose() { _LPEDialogSelector->hide(); } void LivePathEffectAdd::onKeyEvent(GdkEventKey *evt) { if (evt->keyval == GDK_KEY_Escape) { onClose(); } } void LivePathEffectAdd::show(SPDesktop *desktop) { LivePathEffectAdd &dial = instance(); Inkscape::Selection *sel = desktop->getSelection(); if (sel && !sel->isEmpty()) { SPItem *item = sel->singleItem(); if (item) { SPShape *shape = dynamic_cast(item); SPPath *path = dynamic_cast(item); SPGroup *group = dynamic_cast(item); dial._has_clip = (item->getClipObject() != nullptr); dial._has_mask = (item->getMaskObject() != nullptr); dial._item_type = ""; if (group) { dial._item_type = "group"; } else if (path) { dial._item_type = "path"; } else if (shape) { dial._item_type = "shape"; } else { dial._LPEDialogSelector->hide(); return; } } } dial._applied = false; dial._LPESelectorFlowBox->unset_sort_func(); dial._LPESelectorFlowBox->unset_filter_func(); dial._LPESelectorFlowBox->set_filter_func(sigc::mem_fun(dial, &LivePathEffectAdd::on_filter)); dial._LPESelectorFlowBox->set_sort_func(sigc::mem_fun(dial, &LivePathEffectAdd::on_sort)); Glib::RefPtr vadjust = dial._LPEScrolled->get_vadjustment(); vadjust->set_value(vadjust->get_lower()); Gtk::Window *window = desktop->getToplevel(); dial._LPEDialogSelector->set_transient_for(*window); dial._LPEDialogSelector->show(); int searchlen = dial._LPEFilter->get_text().length(); if (searchlen > 0) { dial._LPEFilter->select_region (0, searchlen); dial._LPESelectorFlowBox->unselect_all(); } else if (dial._lasteffect) { dial._lasteffect->grab_focus(); } dial._LPEDialogSelector->run(); dial._LPEDialogSelector->hide(); } } // namespace Dialog } // namespace UI } // namespace Inkscape /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :