// Create a mask element (using passed elements), add it to <defs> const gchar *SPClipPath::create (GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform) { Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr(); Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("svg:clipPath"); repr->setAttribute("clipPathUnits", "userSpaceOnUse"); defsrepr->appendChild(repr); const gchar *id = repr->attribute("id"); SPObject *clip_path_object = document->getObjectById(id); for (GSList *it = reprs; it != NULL; it = it->next) { Inkscape::XML::Node *node = (Inkscape::XML::Node *)(it->data); SPItem *item = SP_ITEM(clip_path_object->appendChildRepr(node)); if (NULL != applyTransform) { Geom::Affine transform (item->transform); transform *= (*applyTransform); item->doWriteTransform(item->getRepr(), transform); } } Inkscape::GC::release(repr); return id; }
static void sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) { int n_selected = 0; Inkscape::XML::Node *repr = NULL; purge_repr_listener( tbl, tbl ); std::vector<SPItem*> itemlist=selection->itemList(); for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ SPItem *item = *i; if (SP_IS_SPIRAL(item)) { n_selected++; repr = item->getRepr(); } } EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); if (n_selected == 0) { g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL ); } else if (n_selected == 1) { g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); if (repr) { g_object_set_data( tbl, "repr", repr ); Inkscape::GC::anchor(repr); sp_repr_add_listener(repr, &spiral_tb_repr_events, tbl); sp_repr_synthesize_events(repr, &spiral_tb_repr_events, tbl); } } else { // FIXME: implement averaging of all parameters for multiple selected //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>")); g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); } }
/** Returns the bottommost item from the list which is at the point, or NULL if none. */ SPItem* sp_document_item_from_list_at_point_bottom(unsigned int dkey, SPGroup *group, GSList const *list, Geom::Point const p, bool take_insensitive) { g_return_val_if_fail(group, NULL); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0); for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { if (!SP_IS_ITEM(o)) continue; SPItem *item = SP_ITEM(o); NRArenaItem *arenaitem = sp_item_get_arenaitem(item, dkey); if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL && (take_insensitive || item->isVisibleAndUnlocked(dkey))) { if (g_slist_find((GSList *) list, item) != NULL) return item; } if (SP_IS_GROUP(o)) { SPItem *found = sp_document_item_from_list_at_point_bottom(dkey, SP_GROUP(o), list, p, take_insensitive); if (found) return found; } } return NULL; }
/* * Map each gradient to its usage count for both fill and stroke styles */ void gr_get_usage_counts(SPDocument *doc, std::map<SPGradient *, gint> *mapUsageCount ) { if (!doc) return; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive", true); bool ingroups = TRUE; GSList *all_list = get_all_doc_items(NULL, doc->getRoot(), onlyvisible, onlysensitive, ingroups, NULL); for (GSList *i = all_list; i != NULL; i = i->next) { SPItem *item = SP_ITEM(i->data); if (!item->getId()) continue; SPGradient *gr = NULL; gr = gr_item_get_gradient(item, true); // fill if (gr) { mapUsageCount->count(gr) > 0 ? (*mapUsageCount)[gr] += 1 : (*mapUsageCount)[gr] = 1; } gr = gr_item_get_gradient(item, false); // stroke if (gr) { mapUsageCount->count(gr) > 0 ? (*mapUsageCount)[gr] += 1 : (*mapUsageCount)[gr] = 1; } } }
void Equipment::calculateEffects() { healthEffectCached = 0; manaEffectCached = 0; attackEffectCached = 0; defenseEffectCached = 0; damageEffectCached = 0; skillEffectCached = 0; magicEffectCached = 0; healthRegEffectCached = 0; manaRegEffectCached = 0; for (int i=0; i<et_count; i++) { if (items[i].get() != 0) { SPItem it = items[i]; healthEffectCached += it->getHealthEffect(); manaEffectCached += it->getManaEffect(); attackEffectCached += it->getAttackEffect(); defenseEffectCached += it->getDefenseEffect(); damageEffectCached += it->getDamageEffect(); skillEffectCached += it->getSkillEffect(); magicEffectCached += it->getMagicEffect(); healthRegEffectCached += it->getHealthregenerateEffect(); manaRegEffectCached += it->getManaregenerateEffect(); } } }
static bool pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool omittext, bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas, float bleedmargin_px) { doc->ensureUpToDate(); /* Start */ SPItem *base = NULL; bool pageBoundingBox = TRUE; if (exportId && strcmp(exportId, "")) { // we want to export the given item only base = SP_ITEM(doc->getObjectById(exportId)); pageBoundingBox = exportCanvas; } else { // we want to export the entire document from root base = doc->getRoot(); pageBoundingBox = !exportDrawing; } if (!base) { return false; } /* Create new arena */ Inkscape::Drawing drawing; drawing.setExact(true); unsigned dkey = SPItem::display_key_new(1); base->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY); /* Create renderer and context */ CairoRenderer *renderer = new CairoRenderer(); CairoRenderContext *ctx = renderer->createContext(); ctx->setPDFLevel(level); ctx->setTextToPath(texttopath); ctx->setOmitText(omittext); ctx->setFilterToBitmap(filtertobitmap); ctx->setBitmapResolution(resolution); bool ret = ctx->setPdfTarget (filename); if(ret) { /* Render document */ ret = renderer->setupDocument(ctx, doc, pageBoundingBox, bleedmargin_px, base); if (ret) { renderer->renderItem(ctx, base); ret = ctx->finish(); } } base->invoke_hide(dkey); renderer->destroyContext(ctx); delete renderer; return ret; }
void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *tool, guint event_state) { g_return_if_fail(!strcmp(tool, "/tools/freehand/pen") || !strcmp(tool, "/tools/freehand/pencil")); Glib::ustring tool_path = tool; SPDesktop *desktop = ec->desktop; Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); repr->setAttribute("sodipodi:type", "arc"); SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); Inkscape::GC::release(repr); // apply the tool's current style sp_desktop_apply_style_tool(desktop, repr, tool, false); // find out stroke width (TODO: is there an easier way??) double stroke_width = 3.0; gchar const *style_str = repr->attribute("style"); if (style_str) { SPStyle style(SP_ACTIVE_DOCUMENT); style.mergeString(style_str); stroke_width = style.stroke_width.computed; } // unset stroke and set fill color to former stroke color gchar * str; str = g_strdup_printf("fill:#%06x;stroke:none;", sp_desktop_get_color_tool(desktop, tool, false) >> 8); repr->setAttribute("style", str); g_free(str); // put the circle where the mouse click occurred and set the diameter to the // current stroke width, multiplied by the amount specified in the preferences Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Geom::Affine const i2d (item->i2dt_affine ()); Geom::Point pp = pt * i2d.inverse(); double rad = 0.5 * prefs->getDouble(tool_path + "/dot-size", 3.0); if (event_state & GDK_MOD1_MASK) { // TODO: We vary the dot size between 0.5*rad and 1.5*rad, where rad is the dot size // as specified in prefs. Very simple, but it might be sufficient in practice. If not, // we need to devise something more sophisticated. double s = g_random_double_range(-0.5, 0.5); rad *= (1 + s); } if (event_state & GDK_SHIFT_MASK) { // double the point size rad *= 2; } sp_repr_set_svg_double (repr, "sodipodi:cx", pp[Geom::X]); sp_repr_set_svg_double (repr, "sodipodi:cy", pp[Geom::Y]); sp_repr_set_svg_double (repr, "sodipodi:rx", rad * stroke_width); sp_repr_set_svg_double (repr, "sodipodi:ry", rad * stroke_width); item->updateRepr(); desktop->getSelection()->set(item); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating single dot")); DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Create single dot")); }
/** * \param selection should not be NULL. */ static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) { int n_selected = 0; Inkscape::XML::Node *repr = NULL; SPItem *item = NULL; if ( g_object_get_data( tbl, "repr" ) ) { g_object_set_data( tbl, "item", NULL ); } purge_repr_listener( tbl, tbl ); for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { if (SP_IS_RECT(reinterpret_cast<SPItem *>(items->data))) { n_selected++; item = reinterpret_cast<SPItem *>(items->data); repr = item->getRepr(); } } EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); g_object_set_data( tbl, "single", GINT_TO_POINTER(FALSE) ); if (n_selected == 0) { g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL ); GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) ); gtk_action_set_sensitive(w, FALSE); GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) ); gtk_action_set_sensitive(h, FALSE); } else if (n_selected == 1) { g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) ); GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) ); gtk_action_set_sensitive(w, TRUE); GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) ); gtk_action_set_sensitive(h, TRUE); if (repr) { g_object_set_data( tbl, "repr", repr ); g_object_set_data( tbl, "item", item ); Inkscape::GC::anchor(repr); sp_repr_add_listener(repr, &rect_tb_repr_events, tbl); sp_repr_synthesize_events(repr, &rect_tb_repr_events, tbl); } } else { // FIXME: implement averaging of all parameters for multiple selected //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>")); g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); sp_rtb_sensitivize( tbl ); } }
/// \todo fixme. static gint arena_handler(SPCanvasArena */*arena*/, Inkscape::DrawingItem *ai, GdkEvent *event, SPSVGView *svgview) { static gdouble x, y; static gboolean active = FALSE; SPEvent spev; SPItem *spitem = (ai) ? (static_cast<SPItem*>(ai->data())) : 0; switch (event->type) { case GDK_BUTTON_PRESS: if (event->button.button == 1) { active = TRUE; x = event->button.x; y = event->button.y; } break; case GDK_BUTTON_RELEASE: if (event->button.button == 1) { if (active && (event->button.x == x) && (event->button.y == y)) { spev.type = SP_EVENT_ACTIVATE; if ( spitem != 0 ) { spitem->emitEvent (spev); } } } active = FALSE; break; case GDK_MOTION_NOTIFY: active = FALSE; break; case GDK_ENTER_NOTIFY: spev.type = SP_EVENT_MOUSEOVER; spev.data = svgview; if ( spitem != 0 ) { spitem->emitEvent (spev); } break; case GDK_LEAVE_NOTIFY: spev.type = SP_EVENT_MOUSEOUT; spev.data = svgview; if ( spitem != 0 ) { spitem->emitEvent (spev); } break; default: break; } return TRUE; }
Geom::OptRect Selection::documentBounds(SPItem::BBoxType type) const { Geom::OptRect bbox; std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); if (items.empty()) return bbox; for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { SPItem *item = SP_ITEM(*iter); bbox |= item->documentBounds(type); } return bbox; }
// If we have a selection of multiple items, then the center of the first item // will be returned; this is also the case in SelTrans::centerRequest() boost::optional<Geom::Point> Selection::center() const { std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); if (!items.empty()) { SPItem *first = items.back(); // from the first item in selection if (first->isCenterSet()) { // only if set explicitly return first->getCenter(); } } Geom::OptRect bbox = preferredBounds(); if (bbox) { return bbox->midpoint(); } else { return boost::optional<Geom::Point>(); } }
void SPUse::href_changed() { this->_delete_connection.disconnect(); this->_transformed_connection.disconnect(); if (this->child) { this->detach(this->child); this->child = NULL; } if (this->href) { SPItem *refobj = this->ref->getObject(); if (refobj) { Inkscape::XML::Node *childrepr = refobj->getRepr(); SPObject* obj = SPFactory::createObject(NodeTraits::get_type_string(*childrepr)); SPItem *item = dynamic_cast<SPItem *>(obj); if (item) { child = item; this->attach(this->child, this->lastChild()); sp_object_unref(this->child, this); this->child->invoke_build(this->document, childrepr, TRUE); for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingItem *ai = this->child->invoke_show(v->arenaitem->drawing(), v->key, v->flags); if (ai) { v->arenaitem->prependChild(ai); } } } else { delete obj; g_warning("Tried to create svg:use from invalid object"); } this->_delete_connection = refobj->connectDelete( sigc::hide(sigc::mem_fun(this, &SPUse::delete_self)) ); this->_transformed_connection = refobj->connectTransformed( sigc::hide(sigc::mem_fun(this, &SPUse::move_compensate)) ); } } }
void CGroup::hide (unsigned int key) { SPItem * child; GSList *l = g_slist_reverse(_group->childList(false, SPObject::ActionShow)); while (l) { SPObject *o = SP_OBJECT (l->data); if (SP_IS_ITEM (o)) { child = SP_ITEM (o); child->invoke_hide (key); } l = g_slist_remove (l, o); } if (((SPItemClass *) parent_class)->hide) ((SPItemClass *) parent_class)->hide (_group, key); }
void CGroup::_showChildren (Inkscape::Drawing &drawing, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags) { Inkscape::DrawingItem *ac = NULL; SPItem * child = NULL; GSList *l = g_slist_reverse(_group->childList(false, SPObject::ActionShow)); while (l) { SPObject *o = SP_OBJECT (l->data); if (SP_IS_ITEM (o)) { child = SP_ITEM (o); ac = child->invoke_show (drawing, key, flags); if (ac) { ai->appendChild(ac); } } l = g_slist_remove (l, o); } }
Geom::OptRect CGroup::bounds(SPItem::BBoxType type, Geom::Affine const &transform) { Geom::OptRect bbox; GSList *l = _group->childList(false, SPObject::ActionBBox); while (l) { SPObject *o = SP_OBJECT (l->data); if (SP_IS_ITEM(o) && !SP_ITEM(o)->isHidden()) { SPItem *child = SP_ITEM(o); Geom::Affine const ct(child->transform * transform); bbox |= child->bounds(type, ct); } l = g_slist_remove (l, o); } return bbox; }
void LPEMirrorSymmetry::doOnApply (SPLPEItem *lpeitem) { using namespace Geom; SPItem *item = SP_ITEM(lpeitem); Geom::Matrix t = sp_item_i2d_affine(item); Geom::Rect bbox = *item->getBounds(t); // fixme: what happens if getBounds does not return a valid rect? Point A(bbox.left(), bbox.bottom()); Point B(bbox.left(), bbox.top()); A *= t; B *= t; Piecewise<D2<SBasis> > rline = Piecewise<D2<SBasis> >(D2<SBasis>(Linear(A[X], B[X]), Linear(A[Y], B[Y]))); reflection_line.set_new_value(rline, true); }
Equipment::EquipmentType Equipment::getEquipmentType(SPItem item) { unsigned int clientTypeId = item->getClientTypeId(); Equipment::EquipmentType et = et_invalid; if (clientTypeId > 0 && clientTypeId <= et_count) { et = (Equipment::EquipmentType)(clientTypeId); } return et; }
bool Equipment::equip(SPItem item, unsigned int skillBase, unsigned int magicBase, bool checkCanEquip) { if (item->getUsageType() == ItemUsageType::equip && (!checkCanEquip || item->getEquippedStatus() == ItemEquippedStatus::not_equipped)) { // check required skill / magic, check unequip as on client EquipmentType et = getEquipmentType(item); //bool canEquip1 = canEquip(item, skillBase, magicBase); //std::cout << "eq type: " << et << (canEquip1 ? " e ok" : " enok ") << std::endl; if (et != et_invalid && (!checkCanEquip || canEquip(item, skillBase, magicBase))) { if (items[et].get() != 0) { unequip(item, skillBase, magicBase, false); } items[et] = item; item->setEquippedStatus(ItemEquippedStatus::equipped); calculateEffects(); return true; } } return false; }
void sp_item_widget_hidden_toggled(GtkWidget *widget, SPWidget *spw) { if (gtk_object_get_data (GTK_OBJECT (spw), "blocked")) return; SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); g_return_if_fail (item != NULL); gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (TRUE)); item->setExplicitlyHidden(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); sp_document_done (SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))? _("Hide object") : _("Unhide object")); gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (FALSE)); }
bool Equipment::unequip(SPItem item, unsigned int skillBase, unsigned int magicBase, bool removeOnly) { if (item->getUsageType() == ItemUsageType::equip && item->getEquippedStatus() == ItemEquippedStatus::equipped) { // check required skill / magic, check unequip as on client EquipmentType et = getEquipmentType(item); std::cout << "et: " << et << ((items[et].get()!=0) ? " not null" : "null") << std::endl; if (et != et_invalid && items[et].get()!=0 && items[et]->getId() == item->getId()) { if (!removeOnly) { items[et]->setEquippedStatus(ItemEquippedStatus::not_equipped); } items[et] = SPItem(); // null item // check if other items need to be unequipped as a consequence of this item being removed (skill / magic might have dropped) checkUnequipUnsupportedItems(skillBase, magicBase, removeOnly); calculateEffects(); return true; } } return false; }
static void sp_usepath_move_compensate(Geom::Affine const *mp, SPItem *original, SPUsePath *self) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_PARALLEL); if (mode == SP_CLONE_COMPENSATION_NONE) { return; } SPItem *item = SP_ITEM(self->owner); // TODO kill naughty naughty #if 0 #if 0 Geom::Affine m(*mp); if (!(m.is_translation())) { return; } Geom::Affine const t(item->transform); Geom::Affine clone_move = t.inverse() * m * t; // Calculate the compensation matrix and the advertized movement matrix. Geom::Affine advertized_move; if (mode == SP_CLONE_COMPENSATION_PARALLEL) { //clone_move = clone_move.inverse(); advertized_move.set_identity(); } else if (mode == SP_CLONE_COMPENSATION_UNMOVED) { clone_move = clone_move.inverse() * m; advertized_move = m; } else { g_assert_not_reached(); } // Commit the compensation. item->transform *= clone_move; sp_item_write_transform(item, item->getRepr(), item->transform, &advertized_move); #else (void)mp; (void)original; #endif self->sourceDirty = true; item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); }
static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustring const &value_name) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/shapes/spiral/" + value_name, gtk_adjustment_get_value(adj)); } // quit if run by the attr_changed listener if (g_object_get_data( tbl, "freeze" )) { return; } // in turn, prevent listener from responding g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL); bool modmade = false; std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ SPItem *item = *i; if (SP_IS_SPIRAL(item)) { Inkscape::XML::Node *repr = item->getRepr(); sp_repr_set_svg_double( repr, namespaced_name, gtk_adjustment_get_value(adj) ); item->updateRepr(); modmade = true; } } g_free(namespaced_name); if (modmade) { DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_SPIRAL, _("Change spiral")); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); }
void SPTagUse::href_changed(SPObject */*old_ref*/, SPObject */*ref*/) { if (href) { SPItem *refobj = ref->getObject(); if (refobj) { Inkscape::XML::Node *childrepr = refobj->getRepr(); const std::string typeString = NodeTraits::get_type_string(*childrepr); SPObject* child_ = SPFactory::createObject(typeString); if (child_) { child = child_; attach(child_, lastChild()); sp_object_unref(child_, 0); child_->invoke_build(this->document, childrepr, TRUE); } } } }
bool Equipment::canEquip(SPItem item, unsigned int skillBase, unsigned int magicBase) { EquipmentType et = getEquipmentType(item); unsigned int totalCurrentSkill = skillBase + getEffect(Item::at_skill); unsigned int totalCurrentMagic = magicBase + getEffect(Item::at_magic); if (items[et].get() != 0) { // already an iten equipped for this eq slot // we need to consider the effect values without this item as this one will be unequipped before equipping the new one // as this might also have cascading effects, we need to simulate the unequip, and decide afterwards // using a simple temp copy to simulate the unequip Equipment ghost(*this); ghost.unequip(ghost.items[et], skillBase, magicBase, true); return ghost.canEquip(item, skillBase, magicBase); } else { if (totalCurrentSkill >= item->getRequiredSkill() && totalCurrentMagic >= item->getRequiredMagic()) { return true; } else { return false; } } }
Playfield::~Playfield() { // in scheduled items remove from db those tagged to be cleared for (std::vector<SPItem>::iterator it = scheduledItems.begin(); it!=scheduledItems.end(); ) { SPItem item = (*it); if (item->getScheduleType() == Item::st_cleanup) { item->removeFromDB(); it = scheduledItems.erase(it); } else { it++; } } dropCells(); for(std::map<unsigned int, SPItem>::iterator it = allPlayfieldItems.begin(); it!=allPlayfieldItems.end();it++) { world.removeLiveItem(it->second->getId()); } allPlayfieldItems.clear(); scheduledItems.clear(); std::cout << "playfield " << name << " destroyed." << std::endl; }
static GSList *find_items_in_area(GSList *s, SPGroup *group, unsigned int dkey, Geom::Rect const &area, bool (*test)(Geom::Rect const &, Geom::Rect const &), bool take_insensitive = false) { g_return_val_if_fail(SP_IS_GROUP(group), s); for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { if (!SP_IS_ITEM(o)) { continue; } if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER ) { s = find_items_in_area(s, SP_GROUP(o), dkey, area, test); } else { SPItem *child = SP_ITEM(o); Geom::OptRect box = sp_item_bbox_desktop(child); if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { s = g_slist_append(s, child); } } } return s; }
/** Returns the topmost (in z-order) item from the descendants of group (recursively) which is at the point p, or NULL if none. Honors into_groups on whether to recurse into non-layer groups or not. Honors take_insensitive on whether to return insensitive items. If upto != NULL, then if item upto is encountered (at any level), stops searching upwards in z-order and returns what it has found so far (i.e. the found item is guaranteed to be lower than upto). */ SPItem* find_item_at_point(unsigned int dkey, SPGroup *group, Geom::Point const p, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL) { SPItem *seen = NULL, *newseen = NULL; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0); for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { if (!SP_IS_ITEM(o)) continue; if (upto && SP_ITEM(o) == upto) break; if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { // if nothing found yet, recurse into the group newseen = find_item_at_point(dkey, SP_GROUP(o), p, into_groups, take_insensitive, upto); if (newseen) { seen = newseen; newseen = NULL; } if (item_is_in_group(upto, SP_GROUP(o))) break; } else { SPItem *child = SP_ITEM(o); NRArenaItem *arenaitem = sp_item_get_arenaitem(child, dkey); // seen remembers the last (topmost) of items pickable at this point if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { seen = child; } } } return seen; }
static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool("/tools/shapes/arc/open", ege_select_one_action_get_active(act) != 0); } // quit if run by the attr_changed listener if (g_object_get_data( tbl, "freeze" )) { return; } // in turn, prevent listener from responding g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); bool modmade = false; if ( ege_select_one_action_get_active(act) != 0 ) { std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { Inkscape::XML::Node *repr = item->getRepr(); repr->setAttribute("sodipodi:open", "true"); item->updateRepr(); modmade = true; } } } else { std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { Inkscape::XML::Node *repr = item->getRepr(); repr->setAttribute("sodipodi:open", NULL); item->updateRepr(); modmade = true; } } } if (modmade) { DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, _("Arc: Change open/closed")); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); }
void sp_selected_path_combine(SPDesktop *desktop) { Inkscape::Selection *selection = sp_desktop_selection(desktop); SPDocument *doc = sp_desktop_document(desktop); if (g_slist_length((GSList *) selection->itemList()) < 1) { sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to combine.")); return; } desktop->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, _("Combining paths...")); // set "busy" cursor desktop->setWaitingCursor(); GSList *items = g_slist_copy((GSList *) selection->itemList()); items = sp_degroup_list (items); // descend into any groups in selection GSList *to_paths = NULL; for (GSList *i = items; i != NULL; i = i->next) { SPItem *item = (SPItem *) i->data; if (!SP_IS_PATH(item) && !SP_IS_GROUP(item)) to_paths = g_slist_prepend(to_paths, item); } GSList *converted = NULL; bool did = sp_item_list_to_curves(to_paths, &items, &converted); g_slist_free(to_paths); for (GSList *i = converted; i != NULL; i = i->next) items = g_slist_prepend(items, doc->getObjectByRepr((Inkscape::XML::Node*)(i->data))); items = sp_degroup_list (items); // converting to path may have added more groups, descend again items = g_slist_sort(items, (GCompareFunc) sp_item_repr_compare_position); items = g_slist_reverse(items); // remember the position, id, transform and style of the topmost path, they will be assigned to the combined one gint position = 0; char const *id = NULL; char const *transform = NULL; char const *style = NULL; char const *path_effect = NULL; SPCurve* curve = NULL; SPItem *first = NULL; Inkscape::XML::Node *parent = NULL; if (did) { selection->clear(); } for (GSList *i = items; i != NULL; i = i->next) { // going from top to bottom SPItem *item = (SPItem *) i->data; if (!SP_IS_PATH(item)) { continue; } if (!did) { selection->clear(); did = true; } SPCurve *c = SP_PATH(item)->get_curve_for_edit(); if (first == NULL) { // this is the topmost path first = item; parent = first->getRepr()->parent(); position = first->getRepr()->position(); id = first->getRepr()->attribute("id"); transform = first->getRepr()->attribute("transform"); // FIXME: merge styles of combined objects instead of using the first one's style style = first->getRepr()->attribute("style"); path_effect = first->getRepr()->attribute("inkscape:path-effect"); //c->transform(item->transform); curve = c; } else { c->transform(item->getRelativeTransform(first)); curve->append(c, false); c->unref(); // reduce position only if the same parent if (item->getRepr()->parent() == parent) { position--; } // delete the object for real, so that its clones can take appropriate action item->deleteObject(); } } g_slist_free(items); if (did) { first->deleteObject(false); // delete the topmost. Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); // restore id, transform, path effect, and style repr->setAttribute("id", id); if (transform) { repr->setAttribute("transform", transform); } repr->setAttribute("style", style); repr->setAttribute("inkscape:path-effect", path_effect); // set path data corresponding to new curve gchar *dstring = sp_svg_write_path(curve->get_pathvector()); curve->unref(); if (path_effect) { repr->setAttribute("inkscape:original-d", dstring); } else { repr->setAttribute("d", dstring); } g_free(dstring); // add the new group to the parent of the topmost parent->appendChild(repr); // move to the position of the topmost, reduced by the number of deleted items repr->setPosition(position > 0 ? position : 0); DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_COMBINE, _("Combine")); selection->set(repr); Inkscape::GC::release(repr); } else { sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No path(s)</b> to combine in the selection.")); } desktop->clearWaitingCursor(); }
bool sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_select, bool skip_all_lpeitems) { bool did = false; for (; items != NULL; items = items->next) { SPItem *item = SP_ITEM(items->data); SPDocument *document = item->document; if ( skip_all_lpeitems && SP_IS_LPE_ITEM(item) && !SP_IS_GROUP(item) ) // also convert objects in an SPGroup when skip_all_lpeitems is set. { continue; } if (SP_IS_PATH(item) && !SP_SHAPE(item)->_curve_before_lpe) { // remove connector attributes if (item->getAttribute("inkscape:connector-type") != NULL) { item->removeAttribute("inkscape:connection-start"); item->removeAttribute("inkscape:connection-end"); item->removeAttribute("inkscape:connector-type"); item->removeAttribute("inkscape:connector-curvature"); did = true; } continue; // already a path, and no path effect } if (SP_IS_BOX3D(item)) { // convert 3D box to ordinary group of paths; replace the old element in 'selected' with the new group Inkscape::XML::Node *repr = box3d_convert_to_group(SP_BOX3D(item))->getRepr(); if (repr) { *to_select = g_slist_prepend (*to_select, repr); did = true; *selected = g_slist_remove (*selected, item); } continue; } if (SP_IS_GROUP(item)) { SP_LPE_ITEM(item)->removeAllPathEffects(true); GSList *item_list = sp_item_group_item_list(SP_GROUP(item)); GSList *item_to_select = NULL; GSList *item_selected = NULL; if (sp_item_list_to_curves(item_list, &item_selected, &item_to_select)) did = true; g_slist_free(item_list); g_slist_free(item_to_select); g_slist_free(item_selected); continue; } Inkscape::XML::Node *repr = sp_selected_item_to_curved_repr(item, 0); if (!repr) continue; did = true; *selected = g_slist_remove (*selected, item); // remember the position of the item gint pos = item->getRepr()->position(); // remember parent Inkscape::XML::Node *parent = item->getRepr()->parent(); // remember id char const *id = item->getRepr()->attribute("id"); // remember title gchar *title = item->title(); // remember description gchar *desc = item->desc(); // It's going to resurrect, so we delete without notifying listeners. item->deleteObject(false); // restore id repr->setAttribute("id", id); // add the new repr to the parent parent->appendChild(repr); SPObject* newObj = document->getObjectByRepr(repr); if (title && newObj) { newObj->setTitle(title); g_free(title); } if (desc && newObj) { newObj->setDesc(desc); g_free(desc); } // move to the saved position repr->setPosition(pos > 0 ? pos : 0); /* Buglet: We don't re-add the (new version of the) object to the selection of any other * desktops where it was previously selected. */ *to_select = g_slist_prepend (*to_select, repr); Inkscape::GC::release(repr); } return did; }