20#include <glibmm/i18n.h>
21#include <gtkmm/button.h>
22#include <gtkmm/comboboxtext.h>
23#include <gtkmm/togglebutton.h>
57 && (is_fill ? style->fill.isPaintserver() : style->
stroke.isPaintserver())
61 if (is<SPLinearGradient>(server)) {
63 }
else if ( is<SPRadialGradient>(server) ) {
66 }
else if (initialMode ==
mode) {
86 if (drag && !drag->
selected.empty()) {
87 auto dragger = *drag->
selected.begin();
88 for(
auto draggable : dragger->draggables) {
89 gr_apply_gradient_to_item(draggable->item, gr, initialType, initialMode, draggable->fill_or_stroke);
96 gr_apply_gradient_to_item(
item, gr, initialType, initialMode, initialMode);
101 bool selection_empty,
SPGradient *gr_selected,
bool gr_multi)
107 std::vector<SPObject *> gradients = document->
getResourceList(
"gradient" );
108 std::map<Glib::ustring, SPGradient *> labels_gradients;
109 for (
auto gradient : gradients) {
110 auto grad = cast<SPGradient>(gradient);
111 if ( grad->hasStops() && !grad->isSolid() ) {
118 Gtk::TreeModel::Row row;
120 if (labels_gradients.empty()) {
122 row = *(
store->append());
123 row[columns.
col_label ] = _(
"No gradient");
131 if (selection_empty) {
133 row = *(
store->append());
134 row[columns.
col_label ] = _(
"Nothing selected");
144 if (gr_selected ==
nullptr) {
145 row = *(
store->append());
146 row[columns.
col_label ] = _(
"No gradient");
154 row = *(
store->append());
155 row[columns.
col_label ] = _(
"Multiple gradients");
163 for (
auto const &[
label, gradient] : labels_gradients) {
166 row = *(
store->append());
174 if (gradient == gr_selected) {
191void gr_get_dt_selected_gradient(
Inkscape::Selection *selection, std::vector<SPGradient *> &gr_selected)
195 auto itemlist= selection->
items();
196 for(
auto i=itemlist.begin();i!=itemlist.end();++i){
201 if (style && (style->
fill.isPaintserver())) {
204 if (style && (style->
stroke.isPaintserver())) {
208 if ( is<SPGradient>(server) ) {
209 gradient = cast<SPGradient>(server);
211 if (gradient && gradient->
isSolid()) {
216 gr_selected.push_back(gradient);
231 if (drag && !drag->
selected.empty()) {
234 for(
auto draggable : dragger->draggables) {
238 if (gradient && gradient->
isSolid()) {
242 if (gradient && (gradient != gr_selected)) {
246 gr_selected = gradient;
249 if (spread != spr_selected) {
253 spr_selected = spread;
261 auto itemlist= selection->
items();
262 for(
auto i=itemlist.begin();i!=itemlist.end();++i){
266 if (style && (style->
fill.isPaintserver())) {
268 if ( is<SPGradient>(server) ) {
269 auto gradient = cast<SPGradient>(server)->
getVector();
272 if (gradient && gradient->
isSolid()) {
276 if (gradient && (gradient != gr_selected)) {
280 gr_selected = gradient;
283 if (spread != spr_selected) {
287 spr_selected = spread;
292 if (style && (style->
stroke.isPaintserver())) {
294 if ( is<SPGradient>(server) ) {
295 auto gradient = cast<SPGradient>(server)->
getVector();
298 if (gradient && gradient->
isSolid()) {
302 if (gradient && (gradient != gr_selected)) {
306 gr_selected = gradient;
309 if (spread != spr_selected) {
313 spr_selected = spread;
346 auto &btn =
dynamic_cast<Gtk::ToggleButton &
>(
item);
357 auto &btn =
dynamic_cast<Gtk::ToggleButton &
>(
item);
359 btn.signal_clicked().connect(
370 auto store = Gtk::ListStore::create(columns);
371 Gtk::TreeModel::Row row;
372 row = *(
store->append());
373 row[columns.
col_label ] = _(
"No gradient");
395 bool linkedmode = prefs->getBool(
"/options/forkgradientvectors/value",
true);
405 Glib::RefPtr<Gtk::ListStore>
store = Gtk::ListStore::create(columns);
407 std::vector<gchar*> spread_dropdown_items_list = {
408 const_cast<gchar *
>(C_(
"Gradient repeat type",
"None")),
413 for (
auto item: spread_dropdown_items_list) {
414 Gtk::TreeModel::Row row = *(
store->append());
421 _(
"Whether to fill with flat color beyond the ends of the gradient vector "
422 "(spreadMethod=\"pad\"), or repeat the gradient in the same direction "
423 "(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite "
424 "directions (spreadMethod=\"reflect\")"),
439 auto store = Gtk::ListStore::create(columns);
441 Gtk::TreeModel::Row row;
443 row = *(
store->append());
509 auto const path =
"/tools/gradient/" +
name;
510 auto const val = prefs->getDouble(path, default_value);
512 auto adj = btn.get_adjustment();
517 btn.set_sensitive(
false);
557 gr_apply_gradient(selection, ev ? ev->get_drag() :
nullptr, gr);
570 auto row =
store->children()[active];
573 void* pointer = row[columns.
col_data];
591 std::vector<SPGradient *> gradientList;
592 gr_get_dt_selected_gradient(selection, gradientList);
596 if (!gradientList.empty()) {
597 for (
auto item : gradientList) {
598 item->setSpread(spread);
622 std::cerr <<
"select_dragger_by_stop: should be blocked!" << std::endl;
625 if (!ev || !gradient) {
647 auto row =
store->children()[active];
649 void* pointer = row[columns.
col_data];
650 return static_cast<SPStop *
>(pointer);
661 std::cerr <<
"gr_stop_set_offset: should be blocked!" << std::endl;
673 adj->set_lower(prev !=
nullptr ? prev->
offset : 0);
677 adj->set_lower(next !=
nullptr ? next->
offset : 1.0);
678 adj->set_value(stop->offset);
698 stop->offset =
_offset_item.get_adjustment()->get_value();
700 stop->getRepr()->setAttributeCssDouble(
"offset", stop->offset);
702 DocumentUndo::maybeDone(stop->document,
"gradient:stop:offset", _(
"Change gradient stop offset"), INKSCAPE_ICON(
"color-gradient"));
720 gt->add_stops_between_selected_stops();
743 auto drag = ev->get_drag();
765 _linked_btn.set_image_from_icon_name(INKSCAPE_ICON(
"object-locked"));
767 _linked_btn.set_image_from_icon_name(INKSCAPE_ICON(
"object-unlocked"));
804 bool gr_multi =
false;
805 bool spr_multi =
false;
807 gr_read_selection(selection, drag, gr_selected, gr_multi, spr_selected, spr_multi);
831 _stop_cb->set_sensitive(gr_selected && !gr_multi);
845 std::cerr <<
"update_stop_list should be blocked!" << std::endl;
857 Gtk::TreeModel::Row row;
860 row = *(
store->append());
861 row[columns.
col_label ] = _(
"Multiple gradients");
872 row = *(
store->append());
873 row[columns.
col_label ] = _(
"No gradient");
880 row = *(
store->append());
881 row[columns.
col_label ] = _(
"No stops in gradient");
888 for (
auto& ochild: gradient->
children) {
889 if (is<SPStop>(&ochild)) {
891 auto stop = cast<SPStop>(&ochild);
897 row = *(
store->append());
921 for (
auto& ochild: gradient->
children) {
922 if (is<SPStop>(&ochild)) {
923 if (&ochild == new_stop) {
938 std::cerr <<
"select_stop_by_draggers should be blocked!" << std::endl;
941 if (!ev || !gradient)
950 if (!drag || drag->
selected.empty()) {
961 for(
auto dragger : drag->
selected) {
973 switch (draggable->point_type) {
999 auto row = *(
store->prepend());
1000 row[columns.
col_label ] = _(
"Multiple stops");
1002 row[columns.
col_icon ] =
"NotUsed";
bool is(S const *s)
Equivalent to the boolean value of dynamic_cast<T const*>(...).
This is the root class of the gradient dragging machinery.
void selectByStop(SPStop *stop, bool add_to_selection=true, bool override=true)
Select draggers by stop.
std::set< GrDragger * > selected
void deleteSelected(bool just_one=false)
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
static void maybeDone(SPDocument *document, const gchar *keyconst, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
SPItemRange items()
Returns a range of selected SPItems.
bool isEmpty()
Returns true if no items are selected.
static Preferences * get()
Access the singleton Preferences object.
void setInt(Glib::ustring const &pref_path, int value)
Set an integer value.
void setBool(Glib::ustring const &pref_path, bool value)
Set a Boolean value.
The set of selected SPObjects for a given document and layer model.
Interface for refcounted XML nodes.
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
To do: update description of desktop.
SPDocument * getDocument() const
sigc::connection connect_gradient_stop_selected(sigc::slot< void(SPStop *)> const &slot)
Inkscape::Selection * getSelection() const
Inkscape::UI::Tools::ToolBase * getTool() const
Typed SVG document implementation.
std::vector< SPObject * > const getResourceList(char const *key)
sigc::connection connectModified(ModifiedSignal::slot_type slot)
SPDefs * getDefs()
Return the main defs object for the document.
SPGradientSpread fetchSpread() const
Returns the effective spread of given gradient (climbing up the refs chain if needed).
SPGradient * getVector(bool force_private=false)
Returns private vector of given gradient (the gradient at the end of the href chain which has stops),...
Base class for visual SVG elements.
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
sigc::connection connectRelease(sigc::slot< void(SPObject *)> slot)
Connects to the release request signal.
Inkscape::XML::Node * updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT)
Updates the object's repr based on the object's state.
sigc::connection connectModified(sigc::slot< void(SPObject *, unsigned int)> slot)
Connects to the modification notification signal.
SPStop * getNextStop()
Virtual write: write object attributes to repr.
SPPaintServer * getFillPaintServer()
T< SPAttr::FILL, SPIPaint > fill
fill
T< SPAttr::STROKE, SPIPaint > stroke
stroke
SPPaintServer * getStrokePaintServer()
Editable view implementation.
TODO: insert short description here.
SPStop * sp_get_stop_i(SPGradient *gradient, guint stop_i)
void sp_gradient_reverse_selected_gradients(SPDesktop *desktop)
SPGradient * sp_item_gradient_get_vector(SPItem *item, Inkscape::PaintTarget fill_or_stroke)
SPStop * sp_last_stop(SPGradient *gradient)
SPGradient * sp_gradient_ensure_vector_normalized(SPGradient *gr)
Either normalizes given gradient to vector, or returns fresh normalized vector - in latter case,...
SPGradientSpread sp_item_gradient_get_spread(SPItem *item, Inkscape::PaintTarget fill_or_stroke)
SPGradient * sp_item_set_gradient(SPItem *item, SPGradient *gr, SPGradientType type, Inkscape::PaintTarget fill_or_stroke)
Sets item fill or stroke to the gradient of the specified type with given vector, creating new privat...
Glib::RefPtr< Gdk::Pixbuf > sp_gradstop_to_pixbuf_ref(SPStop *stop, int width, int height)
Glib::RefPtr< Gdk::Pixbuf > sp_gradient_to_pixbuf_ref(SPGradient *gr, int width, int height)
Glib::ustring gr_ellipsize_text(Glib::ustring const &src, size_t maxlen)
Glib::ustring gr_prepare_label(SPObject *obj)
Macro for icon names used in Inkscape.
W & get_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id)
Gtk::Widget * for_each_child(Gtk::Widget &widget, Func &&func, bool const plus_self=false, bool const recurse=false, int const level=0)
Call Func with a reference to each child of parent, until it returns _break.
W & get_derived_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id, Args &&... args)
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
Helper class to stream background task notifications as a series of messages.
@ SP_GRADIENT_SPREAD_UNDEFINED
@ SP_GRADIENT_TYPE_LINEAR
@ SP_GRADIENT_TYPE_RADIAL
TODO: insert short description here.
TODO: insert short description here.
TODO: insert short description here.
This class holds together a visible on-canvas knot and a list of draggables that need to be moved whe...
std::vector< GrDraggable * > draggables
SPStyle - a style object for SPItem objects.
Glib::RefPtr< Gtk::Builder > builder