mirror of
https://github.com/exyte/Macaw.git
synced 2024-09-11 13:15:35 +03:00
node id #477
This commit is contained in:
parent
a32e814dfd
commit
d690e118cc
@ -23,7 +23,7 @@ open class Group: Node {
|
||||
}
|
||||
}
|
||||
|
||||
public init(contents: [Node] = [], place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||
public init(contents: [Node] = [], place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
|
||||
self.contentsVar = AnimatableVariable<[Node]>(contents)
|
||||
super.init(
|
||||
place: place,
|
||||
@ -33,6 +33,7 @@ open class Group: Node {
|
||||
mask: mask,
|
||||
effect: effect,
|
||||
visible: visible,
|
||||
nodeId: nodeId,
|
||||
tag: tag
|
||||
)
|
||||
|
||||
@ -151,7 +152,7 @@ open class Group: Node {
|
||||
}
|
||||
|
||||
public extension Array where Element: Node {
|
||||
public func group( place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) -> Group {
|
||||
return Group(contents: self, place: place, opaque: opaque, opacity: opacity, clip: clip, effect: effect, visible: visible, tag: tag)
|
||||
public func group( place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) -> Group {
|
||||
return Group(contents: self, place: place, opaque: opaque, opacity: opacity, clip: clip, effect: effect, visible: visible, nodeId: nodeId, tag: tag)
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ open class Image: Node {
|
||||
|
||||
private var mImage: MImage?
|
||||
|
||||
public init(src: String, xAlign: Align = .min, yAlign: Align = .min, aspectRatio: AspectRatio = .none, w: Int = 0, h: Int = 0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||
public init(src: String, xAlign: Align = .min, yAlign: Align = .min, aspectRatio: AspectRatio = .none, w: Int = 0, h: Int = 0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
|
||||
self.srcVar = Variable<String>(src)
|
||||
self.xAlignVar = Variable<Align>(xAlign)
|
||||
self.yAlignVar = Variable<Align>(yAlign)
|
||||
@ -61,11 +61,12 @@ open class Image: Node {
|
||||
mask: mask,
|
||||
effect: effect,
|
||||
visible: visible,
|
||||
nodeId: nodeId,
|
||||
tag: tag
|
||||
)
|
||||
}
|
||||
|
||||
public init(image: MImage, xAlign: Align = .min, yAlign: Align = .min, aspectRatio: AspectRatio = .none, w: Int = 0, h: Int = 0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||
public init(image: MImage, xAlign: Align = .min, yAlign: Align = .min, aspectRatio: AspectRatio = .none, w: Int = 0, h: Int = 0, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
|
||||
|
||||
var oldId: String?
|
||||
for key in imagesMap.keys where image === imagesMap[key] {
|
||||
@ -88,6 +89,7 @@ open class Image: Node {
|
||||
clip: clip,
|
||||
effect: effect,
|
||||
visible: visible,
|
||||
nodeId: nodeId,
|
||||
tag: tag
|
||||
)
|
||||
}
|
||||
|
@ -38,6 +38,12 @@ open class Node: Drawable {
|
||||
set(val) { effectVar.value = val }
|
||||
}
|
||||
|
||||
public let nodeIdVar: Variable<String?>
|
||||
open var nodeId: String? {
|
||||
get { return nodeIdVar.value }
|
||||
set(val) { nodeIdVar.value = val }
|
||||
}
|
||||
|
||||
internal var id: String {
|
||||
didSet {
|
||||
Node.map.removeObject(forKey: id as NSString)
|
||||
@ -300,7 +306,7 @@ open class Node: Drawable {
|
||||
return !pinchHandlers.isEmpty
|
||||
}
|
||||
|
||||
public init(place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||
public init(place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
|
||||
self.placeVar = AnimatableVariable<Transform>(place)
|
||||
self.opaqueVar = Variable<Bool>(opaque)
|
||||
self.opacityVar = AnimatableVariable<Double>(opacity)
|
||||
@ -308,6 +314,7 @@ open class Node: Drawable {
|
||||
self.maskVar = Variable<Node?>(mask)
|
||||
self.effectVar = Variable<Effect?>(effect)
|
||||
self.id = NSUUID().uuidString
|
||||
self.nodeIdVar = Variable<String?>(nodeId)
|
||||
|
||||
super.init(
|
||||
visible: visible,
|
||||
|
@ -24,7 +24,7 @@ open class Shape: Node {
|
||||
set(val) { strokeVar.value = val }
|
||||
}
|
||||
|
||||
public init(form: Locus, fill: Fill? = nil, stroke: Stroke? = nil, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||
public init(form: Locus, fill: Fill? = nil, stroke: Stroke? = nil, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
|
||||
self.formVar = AnimatableVariable<Locus>(form)
|
||||
self.fillVar = AnimatableVariable<Fill?>(fill)
|
||||
self.strokeVar = AnimatableVariable<Stroke?>(stroke)
|
||||
@ -36,6 +36,7 @@ open class Shape: Node {
|
||||
mask: mask,
|
||||
effect: effect,
|
||||
visible: visible,
|
||||
nodeId: nodeId,
|
||||
tag: tag
|
||||
)
|
||||
|
||||
|
@ -42,7 +42,7 @@ open class Text: Node {
|
||||
set(val) { baselineVar.value = val }
|
||||
}
|
||||
|
||||
public init(text: String, font: Font? = nil, fill: Fill = Color.black, stroke: Stroke? = nil, align: Align = .min, baseline: Baseline = .top, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||
public init(text: String, font: Font? = nil, fill: Fill = Color.black, stroke: Stroke? = nil, align: Align = .min, baseline: Baseline = .top, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, mask: Node? = nil, effect: Effect? = nil, visible: Bool = true, nodeId: String? = nil, tag: [String] = []) {
|
||||
self.textVar = Variable<String>(text)
|
||||
self.fontVar = Variable<Font?>(font)
|
||||
self.fillVar = Variable<Fill>(fill)
|
||||
@ -57,6 +57,7 @@ open class Text: Node {
|
||||
mask: mask,
|
||||
effect: effect,
|
||||
visible: visible,
|
||||
nodeId: nodeId,
|
||||
tag: tag
|
||||
)
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ open class SVGParser {
|
||||
case "g":
|
||||
result = parseGroup(node, groupStyle: groupStyle)
|
||||
case "clipPath":
|
||||
if let id = element.allAttributes["id"]?.text, let clip = parseClip(node) {
|
||||
if let id = element.idAttribute, let clip = parseClip(node) {
|
||||
self.defClip[id] = clip
|
||||
}
|
||||
case "style", "defs":
|
||||
@ -271,7 +271,7 @@ open class SVGParser {
|
||||
}
|
||||
|
||||
private func parseDefinition(_ child: XMLIndexer) {
|
||||
guard let id = child.element?.allAttributes["id"]?.text, let element = child.element else {
|
||||
guard let id = child.element?.idAttribute, let element = child.element else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -313,8 +313,8 @@ open class SVGParser {
|
||||
guard let element = node.element else {
|
||||
return .none
|
||||
}
|
||||
let id = node.element?.allAttributes["id"]?.text
|
||||
|
||||
let id = element.idAttribute
|
||||
let styleAttributes = groupStyle
|
||||
let position = getPosition(element)
|
||||
switch element.name {
|
||||
@ -323,31 +323,31 @@ open class SVGParser {
|
||||
if let rule = getFillRule(styleAttributes) {
|
||||
path = Path(segments: path.segments, fillRule: rule)
|
||||
}
|
||||
return Shape(form: path, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: path), mask: getMask(styleAttributes, locus: path), tag: getTag(element))
|
||||
return Shape(form: path, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: path), mask: getMask(styleAttributes, locus: path), nodeId: id, tag: getTag(element))
|
||||
}
|
||||
case "line":
|
||||
if let line = parseLine(node) {
|
||||
return Shape(form: line, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: line), mask: getMask(styleAttributes, locus: line), tag: getTag(element))
|
||||
return Shape(form: line, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: line), mask: getMask(styleAttributes, locus: line), nodeId: id, tag: getTag(element))
|
||||
}
|
||||
case "rect":
|
||||
if let rect = parseRect(node) {
|
||||
return Shape(form: rect, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: rect), mask: getMask(styleAttributes, locus: rect), tag: getTag(element))
|
||||
return Shape(form: rect, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: rect), mask: getMask(styleAttributes, locus: rect), nodeId: id, tag: getTag(element))
|
||||
}
|
||||
case "circle":
|
||||
if let circle = parseCircle(node) {
|
||||
return Shape(form: circle, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: circle), mask: getMask(styleAttributes, locus: circle), tag: getTag(element))
|
||||
return Shape(form: circle, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: circle), mask: getMask(styleAttributes, locus: circle), nodeId: id, tag: getTag(element))
|
||||
}
|
||||
case "ellipse":
|
||||
if let ellipse = parseEllipse(node) {
|
||||
return Shape(form: ellipse, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: ellipse), mask: getMask(styleAttributes, locus: ellipse), tag: getTag(element))
|
||||
return Shape(form: ellipse, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: ellipse), mask: getMask(styleAttributes, locus: ellipse), nodeId: id, tag: getTag(element))
|
||||
}
|
||||
case "polygon":
|
||||
if let polygon = parsePolygon(node) {
|
||||
return Shape(form: polygon, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: polygon), mask: getMask(styleAttributes, locus: polygon), tag: getTag(element))
|
||||
return Shape(form: polygon, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: polygon), mask: getMask(styleAttributes, locus: polygon), nodeId: id, tag: getTag(element))
|
||||
}
|
||||
case "polyline":
|
||||
if let polyline = parsePolyline(node) {
|
||||
return Shape(form: polyline, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: polyline), mask: getMask(styleAttributes, locus: polyline), tag: getTag(element))
|
||||
return Shape(form: polyline, fill: getFillColor(styleAttributes, groupStyle: styleAttributes), stroke: getStroke(styleAttributes, groupStyle: styleAttributes), place: position, opacity: getOpacity(styleAttributes), clip: getClipPath(styleAttributes, locus: polyline), mask: getMask(styleAttributes, locus: polyline), nodeId: id, tag: getTag(element))
|
||||
}
|
||||
case "image":
|
||||
return parseImage(node, opacity: getOpacity(styleAttributes), pos: position, clip: getClipPath(styleAttributes, locus: nil))
|
||||
@ -404,7 +404,13 @@ open class SVGParser {
|
||||
groupNodes.append(node)
|
||||
}
|
||||
}
|
||||
return Group(contents: groupNodes, place: getPosition(element), tag: getTag(element))
|
||||
|
||||
return Group(
|
||||
contents: groupNodes,
|
||||
place: getPosition(element),
|
||||
nodeId: element.idAttribute,
|
||||
tag: getTag(element)
|
||||
)
|
||||
}
|
||||
|
||||
fileprivate func getPosition(_ element: SWXMLHash.XMLElement) -> Transform {
|
||||
@ -763,7 +769,7 @@ open class SVGParser {
|
||||
}
|
||||
|
||||
fileprivate func getTag(_ element: SWXMLHash.XMLElement) -> [String] {
|
||||
let id = element.allAttributes["id"]?.text
|
||||
let id = element.idAttribute
|
||||
return id != nil ? [id!] : []
|
||||
}
|
||||
|
||||
@ -876,7 +882,7 @@ open class SVGParser {
|
||||
return .none
|
||||
}
|
||||
let position = pos.move(dx: getDoubleValue(element, attribute: "x") ?? 0, dy: getDoubleValue(element, attribute: "y") ?? 0)
|
||||
return Image(src: link, w: getIntValue(element, attribute: "width") ?? 0, h: getIntValue(element, attribute: "height") ?? 0, place: position, clip: clip, tag: getTag(element))
|
||||
return Image(src: link, w: getIntValue(element, attribute: "width") ?? 0, h: getIntValue(element, attribute: "height") ?? 0, place: position, clip: clip, nodeId: element.idAttribute, tag: getTag(element))
|
||||
}
|
||||
|
||||
fileprivate func parseText(_ text: XMLIndexer, textAnchor: String?, fill: Fill?, stroke: Stroke?, opacity: Double, fontName: String?, fontSize: Int?, fontWeight: String?, pos: Transform = Transform()) -> Node? {
|
||||
@ -894,7 +900,7 @@ open class SVGParser {
|
||||
if let match = matcher.firstMatch(in: elementString, options: .reportCompletion, range: fullRange) {
|
||||
let tspans = (elementString as NSString).substring(with: match.range(at: 1))
|
||||
return Group(contents: collectTspans(tspans, textAnchor: textAnchor, fill: fill, stroke: stroke, opacity: opacity, fontName: fontName, fontSize: fontSize, fontWeight: fontWeight, bounds: Rect(x: getDoubleValue(element, attribute: "x") ?? 0, y: getDoubleValue(element, attribute: "y") ?? 0)),
|
||||
place: pos, tag: getTag(element))
|
||||
place: pos, nodeId: element.idAttribute, tag: getTag(element))
|
||||
}
|
||||
}
|
||||
return .none
|
||||
@ -915,7 +921,7 @@ open class SVGParser {
|
||||
let string = text.text
|
||||
let position = pos.move(dx: getDoubleValue(text, attribute: "x") ?? 0, dy: getDoubleValue(text, attribute: "y") ?? 0)
|
||||
|
||||
return Text(text: string, font: getFont(fontName: fontName, fontWeight: fontWeight, fontSize: fontSize), fill: fill ?? Color.black, stroke: stroke, align: anchorToAlign(textAnchor), baseline: .bottom, place: position, opacity: opacity, tag: getTag(text))
|
||||
return Text(text: string, font: getFont(fontName: fontName, fontWeight: fontWeight, fontSize: fontSize), fill: fill ?? Color.black, stroke: stroke, align: anchorToAlign(textAnchor), baseline: .bottom, place: position, opacity: opacity, nodeId: text.idAttribute, tag: getTag(text))
|
||||
}
|
||||
|
||||
// REFACTOR
|
||||
@ -988,7 +994,7 @@ open class SVGParser {
|
||||
return Text(text: text, font: getFont(attributes, fontName: fontName, fontWeight: fontWeight, fontSize: fontSize),
|
||||
fill: ((attributes["fill"] != nil) ? getFillColor(attributes)! : fill) ?? Color.black, stroke: stroke ?? getStroke(attributes),
|
||||
align: anchorToAlign(textAnchor ?? getTextAnchor(attributes)), baseline: .alphabetic,
|
||||
place: pos, opacity: getOpacity(attributes), tag: getTag(element))
|
||||
place: pos, opacity: getOpacity(attributes), nodeId: element.idAttribute, tag: getTag(element))
|
||||
}
|
||||
|
||||
fileprivate func getFont(_ attributes: [String: String] = [:], fontName: String?, fontWeight: String?, fontSize: Int?) -> Font {
|
||||
@ -1531,15 +1537,16 @@ open class SVGParser {
|
||||
let visible = referenceNode.visible
|
||||
let clip = referenceNode.clip
|
||||
let tag = referenceNode.tag
|
||||
let nodeId = referenceNode.nodeId
|
||||
|
||||
if let shape = referenceNode as? Shape {
|
||||
return Shape(form: shape.form, fill: shape.fill, stroke: shape.stroke, place: pos, opaque: opaque, clip: clip, visible: visible, tag: tag)
|
||||
return Shape(form: shape.form, fill: shape.fill, stroke: shape.stroke, place: pos, opaque: opaque, clip: clip, visible: visible, nodeId: nodeId, tag: tag)
|
||||
}
|
||||
if let text = referenceNode as? Text {
|
||||
return Text(text: text.text, font: text.font, fill: text.fill, stroke: text.stroke, align: text.align, baseline: text.baseline, place: pos, opaque: opaque, clip: clip, visible: visible, tag: tag)
|
||||
return Text(text: text.text, font: text.font, fill: text.fill, stroke: text.stroke, align: text.align, baseline: text.baseline, place: pos, opaque: opaque, clip: clip, visible: visible, nodeId: nodeId, tag: tag)
|
||||
}
|
||||
if let image = referenceNode as? Image {
|
||||
return Image(src: image.src, xAlign: image.xAlign, yAlign: image.yAlign, aspectRatio: image.aspectRatio, w: image.w, h: image.h, place: pos, opaque: opaque, clip: clip, visible: visible, tag: tag)
|
||||
return Image(src: image.src, xAlign: image.xAlign, yAlign: image.yAlign, aspectRatio: image.aspectRatio, w: image.w, h: image.h, place: pos, opaque: opaque, clip: clip, visible: visible, nodeId: nodeId, tag: tag)
|
||||
}
|
||||
if let group = referenceNode as? Group {
|
||||
var contents = [Node]()
|
||||
@ -1548,7 +1555,7 @@ open class SVGParser {
|
||||
contents.append(copy)
|
||||
}
|
||||
}
|
||||
return Group(contents: contents, place: pos, opaque: opaque, clip: clip, visible: visible, tag: tag)
|
||||
return Group(contents: contents, place: pos, opaque: opaque, clip: clip, visible: visible, nodeId: nodeId, tag: tag)
|
||||
}
|
||||
return .none
|
||||
}
|
||||
@ -1795,3 +1802,9 @@ fileprivate class UserSpaceNode {
|
||||
self.userSpace = userSpace
|
||||
}
|
||||
}
|
||||
|
||||
private extension XMLElement {
|
||||
var idAttribute: String? {
|
||||
return allAttributes["id"]?.text
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user