1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-11 13:15:35 +03:00

Buildable example

This commit is contained in:
Victor Sukochev 2016-09-29 17:17:59 +06:00
parent 0a54ff615c
commit 0c471cfc09
8 changed files with 72 additions and 69 deletions

View File

@ -180,7 +180,7 @@ class DiagramExampleView: MacawView {
var groupContents = [Node]() var groupContents = [Node]()
groupContents.append(baseRect) groupContents.append(baseRect)
groupContents.appendContentsOf(lines) groupContents.append(contentsOf: lines)
groupContents.append(blueLineShape) groupContents.append(blueLineShape)
groupContents.append(redLineShape) groupContents.append(redLineShape)
groupContents.append(outerCircleShape) groupContents.append(outerCircleShape)

View File

@ -63,50 +63,50 @@ class PathExampleView: MacawView {
let cloud2Shape = Shape( let cloud2Shape = Shape(
form: cloud2(), form: cloud2(),
place: Transform.scale(sx: 1.5, sy: 1.5).move(dx: 0, dy: -100),
fill: Color(val: 0x60636e), fill: Color(val: 0x60636e),
stroke: Stroke( stroke: Stroke(
fill: Color(val: 0x7e8087), fill: Color(val: 0x7e8087),
width: 2, width: 2,
cap: .round, cap: .round,
join: .round join: .round
) ),
place: Transform.scale(sx: 1.5, sy: 1.5).move(dx: 0, dy: -100)
) )
let lightningShape = Shape( let lightningShape = Shape(
form: lightning(), form: lightning(),
place: Transform.move(dx: 375, dy: 390).scale(sx: 3, sy: 3),
fill: LinearGradient( fill: LinearGradient(
stops: [ y2: 1,
Stop(offset: 0, color: Color.rgb(r: 250, g: 220, b: 0)), stops: [
Stop(offset: 1, color: Color(val: 0xeb6405)) Stop(offset: 0, color: Color.rgb(r: 250, g: 220, b: 0)),
], Stop(offset: 1, color: Color(val: 0xeb6405))
y2: 1 ]
) ),
place: Transform.move(dx: 375, dy: 390).scale(sx: 3, sy: 3)
) )
let cloud1Shape = Shape( let cloud1Shape = Shape(
form: cloud1(), form: cloud1(),
place: .move(dx: 120, dy: 120),
fill: LinearGradient( fill: LinearGradient(
stops: [ y2: 1,
Stop(offset: 0, color: Color(val: 0x2f3036)), stops: [
Stop(offset: 1, color: Color.rgba(r: 47, g: 48, b: 54, a: 0.1)) Stop(offset: 0, color: Color(val: 0x2f3036)),
], Stop(offset: 1, color: Color.rgba(r: 47, g: 48, b: 54, a: 0.1))
y2: 1 ]
) ),
place: .move(dx: 120, dy: 120)
) )
let cloud1Shape2 = Shape( let cloud1Shape2 = Shape(
form: cloud1(), form: cloud1(),
place: .move(dx: 120, dy: 100),
fill: Color(val: 0x7b808c), fill: Color(val: 0x7b808c),
stroke: Stroke( stroke: Stroke(
fill: Color(val: 0xaaacb3), fill: Color(val: 0xaaacb3),
width: 1, width: 1,
cap: .round, cap: .round,
join: .round join: .round
) ),
place: .move(dx: 120, dy: 100)
) )
return Group( return Group(

View File

@ -74,7 +74,7 @@ class ShapesExampleView: MacawView {
} }
fileprivate static func newText(_ text: String, _ place: Transform, baseline: Baseline = .bottom) -> Text { 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)
} }
} }

View File

@ -11,7 +11,7 @@ internal class TransformAnimation: AnimationImpl<Transform> {
self.init(animatedNode: animatedNode, valueFunc: interpolationFunc, animationDuration: animationDuration, delay: delay, autostart: autostart, fps: fps) 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) super.init(observableValue: animatedNode.placeVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
type = .affineTransformation type = .affineTransformation
node = animatedNode 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) super.init(observableValue: animatedNode.placeVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
type = .affineTransformation type = .affineTransformation
node = animatedNode node = animatedNode
@ -75,7 +75,7 @@ public extension AnimatableVariable where T: TransformInterpolation {
return TransformAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay) 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) return TransformAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
} }

View File

@ -86,7 +86,7 @@ extension ObservableArray: Indexable {
} }
public func index(after i: Int) -> Int { 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 { public mutating func replaceSubrange<C : Collection>(_ subRange: Range<Int>, with newCollection: C) where C.Iterator.Element == Element {
let oldCount = elements.count let oldCount = elements.count
elements.replaceSubrange(subRange, with: newCollection) elements.replaceSubrange(subRange, with: newCollection)
guard let first = subRange.first else { // guard let first = subRange.first else {
return // return
} // }
let newCount = elements.count // let newCount = elements.count
let end = first + (newCount - oldCount) + subRange.count // let end = first + (newCount - oldCount) + subRange.count
arrayDidChange(ArrayChangeEvent(inserted: Array(first..<end), // arrayDidChange(ArrayChangeEvent(inserted: Array(first..<end),
deleted: Array(subRange))) // deleted: Array(subRange)))
} }
public mutating func popLast() -> Element? { public mutating func popLast() -> Element? {
@ -210,11 +210,11 @@ extension ObservableArray: Collection {
} }
set { set {
elements[bounds] = newValue elements[bounds] = newValue
guard let first = bounds.first else { // guard let first = bounds.first else {
return // return
} // }
arrayDidChange(ArrayChangeEvent(inserted: Array(first..<first + newValue.count), // arrayDidChange(ArrayChangeEvent(inserted: Array(first..<first + newValue.count),
deleted: Array(bounds))) // deleted: Array(bounds)))
} }
} }
} }

View File

@ -32,7 +32,7 @@ class RenderUtils {
} }
class func mapDash(_ dashes: [Double]) -> UnsafeMutablePointer<CGFloat> { 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() { for (index, item) in dashes.enumerated() {
p[index] = CGFloat(item) p[index] = CGFloat(item)
} }

View File

@ -88,7 +88,7 @@ class ShapeRenderer: NodeRenderer {
let path = CGMutablePath() let path = CGMutablePath()
var t = CGAffineTransform(translationX: CGFloat(ellipse.cx), y: CGFloat(ellipse.cy)) var t = CGAffineTransform(translationX: CGFloat(ellipse.cx), y: CGFloat(ellipse.cy))
t = CGAffineTransform(scaleX: 1.0, y: scale).concatenating(t); 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) ctx.addPath(path)
} }
} else if let point = locus as? Point { } else if let point = locus as? Point {
@ -488,9 +488,12 @@ class ShapeRenderer: NodeRenderer {
ctx!.setLineCap(RenderUtils.mapLineCap(stroke.cap)) ctx!.setLineCap(RenderUtils.mapLineCap(stroke.cap))
let dashes = stroke.dashes let dashes = stroke.dashes
if !dashes.isEmpty { if !dashes.isEmpty {
let dashPointer = RenderUtils.mapDash(dashes) var floatDashes = [CGFloat]()
CGContextSetLineDash(ctx!, 0, dashPointer, dashes.count) dashes.forEach { dash in
dashPointer.deallocateCapacity(dashes.count) floatDashes.append(CGFloat(dash))
}
ctx?.setLineDash(phase: 0.0, lengths: floatDashes)
} }
} }

View File

@ -284,9 +284,10 @@ open class SVGParser {
fileprivate func getStyleAttributes(_ groupAttributes: [String: String], element: XMLElement) -> [String: String] { fileprivate func getStyleAttributes(_ groupAttributes: [String: String], element: XMLElement) -> [String: String] {
var styleAttributes: [String: String] = groupAttributes var styleAttributes: [String: String] = groupAttributes
if let style = element.attributes["style"] { if let style = element.attributes["style"] {
let styleParts = style.stringByReplacingOccurrencesOfString(" ", withString: "").componentsSeparatedByString(";")
let styleParts = style.replacingOccurrences(of: " ", with: "").components(separatedBy: ";")
styleParts.forEach { styleAttribute in styleParts.forEach { styleAttribute in
let currentStyle = styleAttribute.componentsSeparatedByString(":") let currentStyle = styleAttribute.components(separatedBy: ":")
if currentStyle.count == 2 { if currentStyle.count == 2 {
styleAttributes.updateValue(currentStyle[1], forKey: currentStyle[0]) styleAttributes.updateValue(currentStyle[1], forKey: currentStyle[0])
} }
@ -416,9 +417,9 @@ open class SVGParser {
fileprivate func getStrokeDashes(_ styleParts: [String: String]) -> [Double] { fileprivate func getStrokeDashes(_ styleParts: [String: String]) -> [Double] {
var dashes = [Double]() var dashes = [Double]()
if let strokeDashes = styleParts["stroke-dasharray"] { if let strokeDashes = styleParts["stroke-dasharray"] {
let characterSet = NSMutableCharacterSet() var characterSet = CharacterSet()
characterSet.addCharacters(in: " ") characterSet.insert(" ")
characterSet.addCharacters(in: ",") characterSet.insert(",")
let separatedValues = strokeDashes.components(separatedBy: characterSet) let separatedValues = strokeDashes.components(separatedBy: characterSet)
separatedValues.forEach { value in separatedValues.forEach { value in
if let doubleValue = Double(value) { if let doubleValue = Double(value) {
@ -671,7 +672,7 @@ open class SVGParser {
} }
var id = link var id = link
if id.hasPrefix("#") { if id.hasPrefix("#") {
id = id.stringByReplacingOccurrencesOfString("#", withString: "") id = id.replacingOccurrences(of: "#", with: "")
} }
guard let referenceNode = self.defNodes[id], let node = copyNode(referenceNode) else { guard let referenceNode = self.defNodes[id], let node = copyNode(referenceNode) else {
return .none return .none
@ -701,10 +702,10 @@ open class SVGParser {
return .none return .none
} }
var parentGradient: LinearGradient? var parentGradient: LinearGradient?
if let link = element.attributes["xlink:href"]?.stringByReplacingOccurrencesOfString(" ", withString: "") if let link = element.attributes["xlink:href"]?.replacingOccurrences(of: " ", with: "")
, link.hasPrefix("#") { , link.hasPrefix("#") {
let id = link.stringByReplacingOccurrencesOfString("#", withString: "") let id = link.replacingOccurrences(of: "#", with: "")
parentGradient = defFills[id] as? LinearGradient parentGradient = defFills[id] as? LinearGradient
} }
@ -746,10 +747,10 @@ open class SVGParser {
return .none return .none
} }
var parentGradient: RadialGradient? var parentGradient: RadialGradient?
if let link = element.attributes["xlink:href"]?.stringByReplacingOccurrencesOfString(" ", withString: "") if let link = element.attributes["xlink:href"]?.replacingOccurrences(of: " ", with: "")
, link.hasPrefix("#") { , link.hasPrefix("#") {
let id = link.stringByReplacingOccurrencesOfString("#", withString: "") let id = link.replacingOccurrences(of: "#", with: "")
parentGradient = defFills[id] as? RadialGradient parentGradient = defFills[id] as? RadialGradient
} }
@ -802,10 +803,10 @@ open class SVGParser {
return .none return .none
} }
var offset = getDoubleValueFromPercentage(element, attribute: "offset") guard var offset = getDoubleValueFromPercentage(element, attribute: "offset") else {
guard let _ = offset else {
return .none return .none
} }
if offset < 0 { if offset < 0 {
offset = 0 offset = 0
} else if offset > 1 { } else if offset > 1 {
@ -817,11 +818,10 @@ open class SVGParser {
} }
var color = Color.black var color = Color.black
if let stopColor = getStyleAttributes([:], element: element)["stop-color"] { if let stopColor = getStyleAttributes([:], element: element)["stop-color"] {
color = createColor(stopColor color = createColor(stopColor.replacingOccurrences(of: " ", with: ""), opacity: opacity)
.stringByReplacingOccurrencesOfString(" ", withString: ""), opacity: opacity)
} }
return Stop(offset: offset!, color: color) return Stop(offset: offset, color: color)
} }
fileprivate func parsePath(_ path: XMLIndexer) -> Path? { fileprivate func parsePath(_ path: XMLIndexer) -> Path? {
@ -885,9 +885,9 @@ open class SVGParser {
} }
fileprivate func parseCommand(_ command: PathCommand) -> PathSegment? { fileprivate func parseCommand(_ command: PathCommand) -> PathSegment? {
let characterSet = NSMutableCharacterSet() var characterSet = CharacterSet()
characterSet.addCharacters(in: " ") characterSet.insert(" ")
characterSet.addCharacters(in: ",") characterSet.insert(",")
let commandParams = command.expression.components(separatedBy: characterSet) let commandParams = command.expression.components(separatedBy: characterSet)
var separatedValues = [String]() var separatedValues = [String]()
commandParams.forEach { param in commandParams.forEach { param in
@ -1123,10 +1123,10 @@ open class SVGParser {
guard let attributeValue = element.attributes[attribute] else { guard let attributeValue = element.attributes[attribute] else {
return .none return .none
} }
if !attributeValue.containsString("%") { if !attributeValue.contains("%") {
return self.getDoubleValue(element, attribute: attribute) return self.getDoubleValue(element, attribute: attribute)
} else { } else {
let value = attributeValue.stringByReplacingOccurrencesOfString("%", withString: "") let value = attributeValue.replacingOccurrences(of: "%", with: "")
if let doubleValue = Double(value) { if let doubleValue = Double(value) {
return doubleValue / 100 return doubleValue / 100
} }