mirror of
https://github.com/exyte/Macaw.git
synced 2024-11-13 05:07:24 +03:00
Buildable example
This commit is contained in:
parent
0a54ff615c
commit
0c471cfc09
@ -180,7 +180,7 @@ class DiagramExampleView: MacawView {
|
||||
|
||||
var groupContents = [Node]()
|
||||
groupContents.append(baseRect)
|
||||
groupContents.appendContentsOf(lines)
|
||||
groupContents.append(contentsOf: lines)
|
||||
groupContents.append(blueLineShape)
|
||||
groupContents.append(redLineShape)
|
||||
groupContents.append(outerCircleShape)
|
||||
|
@ -63,50 +63,50 @@ class PathExampleView: MacawView {
|
||||
|
||||
let cloud2Shape = Shape(
|
||||
form: cloud2(),
|
||||
place: Transform.scale(sx: 1.5, sy: 1.5).move(dx: 0, dy: -100),
|
||||
fill: Color(val: 0x60636e),
|
||||
stroke: Stroke(
|
||||
fill: Color(val: 0x7e8087),
|
||||
width: 2,
|
||||
cap: .round,
|
||||
join: .round
|
||||
)
|
||||
fill: Color(val: 0x7e8087),
|
||||
width: 2,
|
||||
cap: .round,
|
||||
join: .round
|
||||
),
|
||||
place: Transform.scale(sx: 1.5, sy: 1.5).move(dx: 0, dy: -100)
|
||||
)
|
||||
|
||||
let lightningShape = Shape(
|
||||
form: lightning(),
|
||||
place: Transform.move(dx: 375, dy: 390).scale(sx: 3, sy: 3),
|
||||
fill: LinearGradient(
|
||||
stops: [
|
||||
Stop(offset: 0, color: Color.rgb(r: 250, g: 220, b: 0)),
|
||||
Stop(offset: 1, color: Color(val: 0xeb6405))
|
||||
],
|
||||
y2: 1
|
||||
)
|
||||
y2: 1,
|
||||
stops: [
|
||||
Stop(offset: 0, color: Color.rgb(r: 250, g: 220, b: 0)),
|
||||
Stop(offset: 1, color: Color(val: 0xeb6405))
|
||||
]
|
||||
),
|
||||
place: Transform.move(dx: 375, dy: 390).scale(sx: 3, sy: 3)
|
||||
)
|
||||
|
||||
let cloud1Shape = Shape(
|
||||
form: cloud1(),
|
||||
place: .move(dx: 120, dy: 120),
|
||||
fill: LinearGradient(
|
||||
stops: [
|
||||
Stop(offset: 0, color: Color(val: 0x2f3036)),
|
||||
Stop(offset: 1, color: Color.rgba(r: 47, g: 48, b: 54, a: 0.1))
|
||||
],
|
||||
y2: 1
|
||||
)
|
||||
y2: 1,
|
||||
stops: [
|
||||
Stop(offset: 0, color: Color(val: 0x2f3036)),
|
||||
Stop(offset: 1, color: Color.rgba(r: 47, g: 48, b: 54, a: 0.1))
|
||||
]
|
||||
),
|
||||
place: .move(dx: 120, dy: 120)
|
||||
)
|
||||
|
||||
let cloud1Shape2 = Shape(
|
||||
form: cloud1(),
|
||||
place: .move(dx: 120, dy: 100),
|
||||
fill: Color(val: 0x7b808c),
|
||||
stroke: Stroke(
|
||||
fill: Color(val: 0xaaacb3),
|
||||
width: 1,
|
||||
cap: .round,
|
||||
join: .round
|
||||
)
|
||||
fill: Color(val: 0xaaacb3),
|
||||
width: 1,
|
||||
cap: .round,
|
||||
join: .round
|
||||
),
|
||||
place: .move(dx: 120, dy: 100)
|
||||
)
|
||||
|
||||
return Group(
|
||||
|
@ -74,7 +74,7 @@ class ShapesExampleView: MacawView {
|
||||
}
|
||||
|
||||
fileprivate static func newText(_ text: String, _ place: Transform, baseline: Baseline = .bottom) -> Text {
|
||||
return Text(text: text, fill: Color.black, baseline: baseline, align: .mid, place: place)
|
||||
return Text(text: text, fill: Color.black, align: .mid, baseline: baseline, place: place)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ internal class TransformAnimation: AnimationImpl<Transform> {
|
||||
self.init(animatedNode: animatedNode, valueFunc: interpolationFunc, animationDuration: animationDuration, delay: delay, autostart: autostart, fps: fps)
|
||||
}
|
||||
|
||||
init(animatedNode: Node, valueFunc: (Double) -> Transform, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
||||
init(animatedNode: Node, valueFunc: @escaping (Double) -> Transform, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
||||
super.init(observableValue: animatedNode.placeVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
|
||||
type = .affineTransformation
|
||||
node = animatedNode
|
||||
@ -21,7 +21,7 @@ internal class TransformAnimation: AnimationImpl<Transform> {
|
||||
}
|
||||
}
|
||||
|
||||
init(animatedNode: Node, factory: ((Node) -> ((Double) -> Transform)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
||||
init(animatedNode: Node, factory: @escaping ((Node) -> ((Double) -> Transform)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
||||
super.init(observableValue: animatedNode.placeVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
|
||||
type = .affineTransformation
|
||||
node = animatedNode
|
||||
@ -75,7 +75,7 @@ public extension AnimatableVariable where T: TransformInterpolation {
|
||||
return TransformAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay)
|
||||
}
|
||||
|
||||
public func animation(_ f: (Double) -> Transform, during: Double, delay: Double = 0.0) -> Animation {
|
||||
public func animation(_ f: @escaping (Double) -> Transform, during: Double, delay: Double = 0.0) -> Animation {
|
||||
return TransformAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ extension ObservableArray: Indexable {
|
||||
}
|
||||
|
||||
public func index(after i: Int) -> Int {
|
||||
elements.index(after: i)
|
||||
return elements.index(after: i)
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,13 +159,13 @@ extension ObservableArray: RangeReplaceableCollection {
|
||||
public mutating func replaceSubrange<C : Collection>(_ subRange: Range<Int>, with newCollection: C) where C.Iterator.Element == Element {
|
||||
let oldCount = elements.count
|
||||
elements.replaceSubrange(subRange, with: newCollection)
|
||||
guard let first = subRange.first else {
|
||||
return
|
||||
}
|
||||
let newCount = elements.count
|
||||
let end = first + (newCount - oldCount) + subRange.count
|
||||
arrayDidChange(ArrayChangeEvent(inserted: Array(first..<end),
|
||||
deleted: Array(subRange)))
|
||||
// guard let first = subRange.first else {
|
||||
// return
|
||||
// }
|
||||
// let newCount = elements.count
|
||||
// let end = first + (newCount - oldCount) + subRange.count
|
||||
// arrayDidChange(ArrayChangeEvent(inserted: Array(first..<end),
|
||||
// deleted: Array(subRange)))
|
||||
}
|
||||
|
||||
public mutating func popLast() -> Element? {
|
||||
@ -210,11 +210,11 @@ extension ObservableArray: Collection {
|
||||
}
|
||||
set {
|
||||
elements[bounds] = newValue
|
||||
guard let first = bounds.first else {
|
||||
return
|
||||
}
|
||||
arrayDidChange(ArrayChangeEvent(inserted: Array(first..<first + newValue.count),
|
||||
deleted: Array(bounds)))
|
||||
// guard let first = bounds.first else {
|
||||
// return
|
||||
// }
|
||||
// arrayDidChange(ArrayChangeEvent(inserted: Array(first..<first + newValue.count),
|
||||
// deleted: Array(bounds)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class RenderUtils {
|
||||
}
|
||||
|
||||
class func mapDash(_ dashes: [Double]) -> UnsafeMutablePointer<CGFloat> {
|
||||
let p = UnsafeMutablePointer<CGFloat>(calloc(dashes.count, sizeof(CGFloat)))
|
||||
let p = UnsafeMutablePointer<CGFloat>.allocate(capacity:dashes.count * MemoryLayout<CGFloat>.size)
|
||||
for (index, item) in dashes.enumerated() {
|
||||
p[index] = CGFloat(item)
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ class ShapeRenderer: NodeRenderer {
|
||||
let path = CGMutablePath()
|
||||
var t = CGAffineTransform(translationX: CGFloat(ellipse.cx), y: CGFloat(ellipse.cy))
|
||||
t = CGAffineTransform(scaleX: 1.0, y: scale).concatenating(t);
|
||||
CGPathAddArc(path, &t, 0, 0, r, startAngle, endAngle, false)
|
||||
path.addArc(center: CGPoint.zero, radius: r, startAngle: startAngle, endAngle: endAngle, clockwise: false, transform: t)
|
||||
ctx.addPath(path)
|
||||
}
|
||||
} else if let point = locus as? Point {
|
||||
@ -488,9 +488,12 @@ class ShapeRenderer: NodeRenderer {
|
||||
ctx!.setLineCap(RenderUtils.mapLineCap(stroke.cap))
|
||||
let dashes = stroke.dashes
|
||||
if !dashes.isEmpty {
|
||||
let dashPointer = RenderUtils.mapDash(dashes)
|
||||
CGContextSetLineDash(ctx!, 0, dashPointer, dashes.count)
|
||||
dashPointer.deallocateCapacity(dashes.count)
|
||||
var floatDashes = [CGFloat]()
|
||||
dashes.forEach { dash in
|
||||
floatDashes.append(CGFloat(dash))
|
||||
}
|
||||
|
||||
ctx?.setLineDash(phase: 0.0, lengths: floatDashes)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,9 +284,10 @@ open class SVGParser {
|
||||
fileprivate func getStyleAttributes(_ groupAttributes: [String: String], element: XMLElement) -> [String: String] {
|
||||
var styleAttributes: [String: String] = groupAttributes
|
||||
if let style = element.attributes["style"] {
|
||||
let styleParts = style.stringByReplacingOccurrencesOfString(" ", withString: "").componentsSeparatedByString(";")
|
||||
|
||||
let styleParts = style.replacingOccurrences(of: " ", with: "").components(separatedBy: ";")
|
||||
styleParts.forEach { styleAttribute in
|
||||
let currentStyle = styleAttribute.componentsSeparatedByString(":")
|
||||
let currentStyle = styleAttribute.components(separatedBy: ":")
|
||||
if currentStyle.count == 2 {
|
||||
styleAttributes.updateValue(currentStyle[1], forKey: currentStyle[0])
|
||||
}
|
||||
@ -416,9 +417,9 @@ open class SVGParser {
|
||||
fileprivate func getStrokeDashes(_ styleParts: [String: String]) -> [Double] {
|
||||
var dashes = [Double]()
|
||||
if let strokeDashes = styleParts["stroke-dasharray"] {
|
||||
let characterSet = NSMutableCharacterSet()
|
||||
characterSet.addCharacters(in: " ")
|
||||
characterSet.addCharacters(in: ",")
|
||||
var characterSet = CharacterSet()
|
||||
characterSet.insert(" ")
|
||||
characterSet.insert(",")
|
||||
let separatedValues = strokeDashes.components(separatedBy: characterSet)
|
||||
separatedValues.forEach { value in
|
||||
if let doubleValue = Double(value) {
|
||||
@ -671,7 +672,7 @@ open class SVGParser {
|
||||
}
|
||||
var id = link
|
||||
if id.hasPrefix("#") {
|
||||
id = id.stringByReplacingOccurrencesOfString("#", withString: "")
|
||||
id = id.replacingOccurrences(of: "#", with: "")
|
||||
}
|
||||
guard let referenceNode = self.defNodes[id], let node = copyNode(referenceNode) else {
|
||||
return .none
|
||||
@ -701,10 +702,10 @@ open class SVGParser {
|
||||
return .none
|
||||
}
|
||||
var parentGradient: LinearGradient?
|
||||
if let link = element.attributes["xlink:href"]?.stringByReplacingOccurrencesOfString(" ", withString: "")
|
||||
if let link = element.attributes["xlink:href"]?.replacingOccurrences(of: " ", with: "")
|
||||
, link.hasPrefix("#") {
|
||||
|
||||
let id = link.stringByReplacingOccurrencesOfString("#", withString: "")
|
||||
let id = link.replacingOccurrences(of: "#", with: "")
|
||||
parentGradient = defFills[id] as? LinearGradient
|
||||
}
|
||||
|
||||
@ -746,10 +747,10 @@ open class SVGParser {
|
||||
return .none
|
||||
}
|
||||
var parentGradient: RadialGradient?
|
||||
if let link = element.attributes["xlink:href"]?.stringByReplacingOccurrencesOfString(" ", withString: "")
|
||||
if let link = element.attributes["xlink:href"]?.replacingOccurrences(of: " ", with: "")
|
||||
, link.hasPrefix("#") {
|
||||
|
||||
let id = link.stringByReplacingOccurrencesOfString("#", withString: "")
|
||||
let id = link.replacingOccurrences(of: "#", with: "")
|
||||
parentGradient = defFills[id] as? RadialGradient
|
||||
}
|
||||
|
||||
@ -802,10 +803,10 @@ open class SVGParser {
|
||||
return .none
|
||||
}
|
||||
|
||||
var offset = getDoubleValueFromPercentage(element, attribute: "offset")
|
||||
guard let _ = offset else {
|
||||
guard var offset = getDoubleValueFromPercentage(element, attribute: "offset") else {
|
||||
return .none
|
||||
}
|
||||
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
} else if offset > 1 {
|
||||
@ -817,11 +818,10 @@ open class SVGParser {
|
||||
}
|
||||
var color = Color.black
|
||||
if let stopColor = getStyleAttributes([:], element: element)["stop-color"] {
|
||||
color = createColor(stopColor
|
||||
.stringByReplacingOccurrencesOfString(" ", withString: ""), opacity: opacity)
|
||||
color = createColor(stopColor.replacingOccurrences(of: " ", with: ""), opacity: opacity)
|
||||
}
|
||||
|
||||
return Stop(offset: offset!, color: color)
|
||||
return Stop(offset: offset, color: color)
|
||||
}
|
||||
|
||||
fileprivate func parsePath(_ path: XMLIndexer) -> Path? {
|
||||
@ -885,9 +885,9 @@ open class SVGParser {
|
||||
}
|
||||
|
||||
fileprivate func parseCommand(_ command: PathCommand) -> PathSegment? {
|
||||
let characterSet = NSMutableCharacterSet()
|
||||
characterSet.addCharacters(in: " ")
|
||||
characterSet.addCharacters(in: ",")
|
||||
var characterSet = CharacterSet()
|
||||
characterSet.insert(" ")
|
||||
characterSet.insert(",")
|
||||
let commandParams = command.expression.components(separatedBy: characterSet)
|
||||
var separatedValues = [String]()
|
||||
commandParams.forEach { param in
|
||||
@ -1123,10 +1123,10 @@ open class SVGParser {
|
||||
guard let attributeValue = element.attributes[attribute] else {
|
||||
return .none
|
||||
}
|
||||
if !attributeValue.containsString("%") {
|
||||
if !attributeValue.contains("%") {
|
||||
return self.getDoubleValue(element, attribute: attribute)
|
||||
} else {
|
||||
let value = attributeValue.stringByReplacingOccurrencesOfString("%", withString: "")
|
||||
let value = attributeValue.replacingOccurrences(of: "%", with: "")
|
||||
if let doubleValue = Double(value) {
|
||||
return doubleValue / 100
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user