Skip to content
23 changes: 17 additions & 6 deletions Sources/GameWidget/BarChart/BarChart.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,24 @@ extension HorizontalSingleBarChart: Widget {
public typealias Context = HorizontalSingleBarChartContext

public func node(context: HorizontalSingleBarChartContext) -> SKNode {
let result = SKSpriteNode(color: context.backgroundColor, size: CGSize(width: context.length, height: context.width))
let bar = SKSpriteNode(color: context.color, size: CGSize(width: context.length, height: context.width))
result.anchorPoint = context.alignment.anchorPoint()

let bar = HorizontalBarChartNode(color: context.color, size: CGSize(width: context.length, height: context.width))

bar.alpha = context.alpha
bar.maxWidth = context.length
bar.registerTo(center: HorizontalBarChartNode.center, id: self.name)
bar.anchorPoint = context.alignment.anchorPoint()
result.position = context.position
result.addChild(bar)
return result
bar.position = context.position
bar.zPosition = context.zPosition

if let backgroundColor = context.backgroundColor {
let backgound = SKSpriteNode(color: backgroundColor, size: CGSize(width: context.length, height: context.width))
backgound.anchorPoint = context.alignment.anchorPoint()
backgound.zPosition = context.zPosition - 0.01
bar.addChild(backgound)
}

return bar
}

}
11 changes: 9 additions & 2 deletions Sources/GameWidget/BarChart/BarChartModifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,22 @@

import SpriteKit

public struct HorizontalSingleBarChartContext: PositionContextProtocol, ColorizableContextProtocol {
public struct HorizontalSingleBarChartContext:
PositionContextProtocol,
ColorizableContextProtocol,
AlphaContextProtocol,
ZPositionContextProtocol {

public init() {}

public var position = CGPoint.zero
public var color = SKColor.systemGreen
public var alpha: CGFloat = 1
public var zPosition: CGFloat = .zero
var width = CGFloat(10)
var length = CGFloat(100)
var alignment = HorizontalBarChartAlignmentMode.right
var backgroundColor = SKColor.gray
var backgroundColor: SKColor?
}

public enum HorizontalSingleBarChartModiifers {
Expand Down
36 changes: 36 additions & 0 deletions Sources/GameWidget/BarChart/BarChartNode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// BarChartNode.swift
//
//
// Created by rrbox on 2022/11/28.
//

import SpriteKit

class HorizontalBarChartNode: SKSpriteNode {
static let center = NotificationCenter()
var maxWidth: CGFloat = .zero

@objc func receiveValue(notification: Notification) {
self.size.width = (notification.userInfo?["value"] as! CGFloat)
}

@objc func receiveRate(notification: Notification) {
self.size.width = (notification.userInfo?["rate"] as! CGFloat) * self.maxWidth
}

@objc func receiveValueWithAnimation(notification: Notification) {
self.run(.resize(toWidth: (notification.userInfo?["value"] as! CGFloat), duration: 0.5))
}

@objc func receiveRateWithAnimation(notification: Notification) {
self.run(.resize(toWidth: (notification.userInfo?["rate"] as! CGFloat) * self.maxWidth, duration: 0.5))
}

func registerTo(center: NotificationCenter, id: HorizontalSingleBarChart.ID) {
center.addObserver(self, selector: #selector(receiveValue(notification:)), name: .barChartPostValue(id: id), object: nil)
center.addObserver(self, selector: #selector(receiveRate(notification:)), name: .barChartPostRate(id: id), object: nil)
center.addObserver(self, selector: #selector(receiveValueWithAnimation(notification:)), name: .barChartPostValueWithAnimation(id: id), object: nil)
center.addObserver(self, selector: #selector(receiveRateWithAnimation(notification:)), name: .barChartPostRateWithAnimation(id: id), object: nil)
}
}
46 changes: 46 additions & 0 deletions Sources/GameWidget/BarChart/BarChartOutput.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// BarChartOutput.swift
//
//
// Created by rrbox on 2022/11/28.
//

import Foundation

extension Notification.Name {
static func barChartPostRate(id: HorizontalSingleBarChart.ID) -> Self {
.init("barChartPostRate_\(id)")
}
static func barChartPostValue(id: HorizontalSingleBarChart.ID) -> Self {
.init("barChartPostValue_\(id)")
}
static func barChartPostRateWithAnimation(id: HorizontalSingleBarChart.ID) -> Self {
.init("barChartPostRateWithAnimation_\(id)")
}
static func barChartPostValueWithAnimation(id: HorizontalSingleBarChart.ID) -> Self {
.init("barChartPostValueWithAnimation_\(id)")
}
}

public protocol SingleBarChartDrawable {

func send(value: CGFloat, id: HorizontalSingleBarChart.ID)
func send(rate: CGFloat, id: HorizontalSingleBarChart.ID)

}

public extension SingleBarChartDrawable {
func send(value: CGFloat, id: HorizontalSingleBarChart.ID) {
HorizontalBarChartNode.center.post(name: .barChartPostValue(id: id), object: nil, userInfo: ["value": value])
}
func send(rate: CGFloat, id: HorizontalSingleBarChart.ID) {
HorizontalBarChartNode.center.post(name: .barChartPostRate(id: id), object: nil, userInfo: ["rate": rate])
}

func sendForAnimation(value: CGFloat, id: HorizontalSingleBarChart.ID) {
HorizontalBarChartNode.center.post(name: .barChartPostValueWithAnimation(id: id), object: nil, userInfo: ["value": value])
}
func sendForAnimation(rate: CGFloat, id: HorizontalSingleBarChart.ID) {
HorizontalBarChartNode.center.post(name: .barChartPostRateWithAnimation(id: id), object: nil, userInfo: ["rate": rate])
}
}
17 changes: 17 additions & 0 deletions Sources/GameWidget/Commons/Modifiers/ForAllNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,20 @@ public extension ModifiableWidget where Context: ZPositionContextProtocol {
self.modifier(mod: ZPosition(value: value))
}
}

public protocol AlphaContextProtocol: ContextProtocol {
var alpha: CGFloat { get set }
}

public struct Alpha<Context: AlphaContextProtocol>: Modifier {
var value: CGFloat
public func mod(context: inout Context) {
context.alpha = self.value
}
}

public extension ModifiableWidget where Context: AlphaContextProtocol {
func alpha(_ value: CGFloat) -> Next<Alpha<Context>> {
self.modifier(mod: Alpha(value: value))
}
}
15 changes: 10 additions & 5 deletions Tests/GameWidgetTests/BarChartTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,26 @@ final class BarChartTests: XCTestCase {
.length(90)
.alignment(.center)
.backgroundColor(.blue)
.alpha(0.5)
.zPosition(2)
.node()

guard let barChart = barChart as? SKSpriteNode,
let bar = barChart.children[0] as? SKSpriteNode else {
let background = barChart.children[0] as? SKSpriteNode else {
XCTFail()
return
}

XCTAssertEqual(barChart.position, CGPoint(x: 1, y: 1))
XCTAssertEqual(barChart.color.cgColor.components, SKColor.blue.cgColor.components)
XCTAssertEqual(barChart.color.cgColor.components, SKColor.red.cgColor.components)
XCTAssertEqual(barChart.size, CGSize(width: 90, height: 90))
XCTAssertEqual(barChart.alpha, 0.5)
XCTAssertEqual(barChart.zPosition, 2)

XCTAssertEqual(bar.color.cgColor.components, SKColor.red.cgColor.components)
XCTAssertEqual(bar.size, CGSize(width: 90, height: 90))
XCTAssertEqual(bar.anchorPoint, CGPoint(x: 0.5, y: 0.5))
XCTAssertEqual(background.color.cgColor.components, SKColor.blue.cgColor.components)
XCTAssertEqual(background.size, CGSize(width: 90, height: 90))
XCTAssertEqual(background.anchorPoint, CGPoint(x: 0.5, y: 0.5))
XCTAssertEqual(CGFloat(Int(background.zPosition*100))/100, 2 - 0.01)

}
}