ActivityView.swift 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. //
  2. // ActivityButton.swift
  3. // KdanAuto
  4. //
  5. // Created by 朱东勇 on 2022/12/7.
  6. //
  7. import Foundation
  8. import AppKit
  9. enum ActivityStatus : Int {
  10. case Normal = 0
  11. case Wait = 1
  12. case Process = 2
  13. case Finished = 3
  14. }
  15. class ActivityView : NSView {
  16. var _status : ActivityStatus = ActivityStatus(rawValue: 0) ?? .Normal
  17. var _timer : Timer = Timer()
  18. var _titleLbl : NSTextField = NSTextField()
  19. let kActivityTitleHeight = 25.0
  20. var _activityView : NSProgressIndicator = NSProgressIndicator()
  21. // var _activityView : NSView = NSView()
  22. // var _angle : CGFloat = 0
  23. // var _shapeLayer : CAShapeLayer = CAShapeLayer()
  24. var _degree : Double = 0
  25. public override init(frame frameRect: NSRect) {
  26. super.init(frame: frameRect)
  27. if (self != nil) {
  28. loadSubviews()
  29. }
  30. }
  31. public required init?(coder: NSCoder) {
  32. super.init(coder: coder)
  33. if (self != nil) {
  34. loadSubviews()
  35. }
  36. }
  37. override func awakeFromNib() {
  38. super.awakeFromNib()
  39. loadSubviews()
  40. updateStatus()
  41. }
  42. override func layout() {
  43. reloadSubviews()
  44. }
  45. // Reload subviews
  46. func loadSubviews() {
  47. reloadSubviews()
  48. }
  49. func reloadSubviews() {
  50. self.wantsLayer = true
  51. self.layer?.backgroundColor = NSColor.clear.cgColor
  52. let width = self.frame.width
  53. let height = self.frame.height
  54. if nil == _titleLbl {
  55. _titleLbl = NSTextField.init(frame: self.frame)
  56. }
  57. _titleLbl.isSelectable = false
  58. _titleLbl.isEditable = false
  59. if nil == _titleLbl.superview {
  60. self.addSubview(_titleLbl)
  61. }
  62. _titleLbl.wantsLayer = true
  63. _titleLbl.frame = NSMakeRect(0, (height - kActivityTitleHeight) / 2.0, width, kActivityTitleHeight)
  64. _titleLbl.backgroundColor = NSColor.clear
  65. _titleLbl.font = NSFont.systemFont(ofSize: 12.0)
  66. _titleLbl.layer?.backgroundColor = NSColor.clear.cgColor
  67. _titleLbl.autoresizingMask = .width.union(.minXMargin).union(.maxXMargin).union(.height)
  68. _titleLbl.alignment = .center
  69. _titleLbl.layer?.borderWidth = 1
  70. _titleLbl.layer?.cornerRadius = 4
  71. if nil == _activityView {
  72. _activityView = NSProgressIndicator.init(frame: self.bounds)
  73. }
  74. _activityView.controlSize = .small
  75. _activityView.style = .spinning
  76. if nil == _activityView.superview {
  77. self.addSubview(_activityView)
  78. }
  79. _activityView.startAnimation(self)
  80. let activitySize = kActivityTitleHeight
  81. // min(_activityView.frame.width, _activityView.frame.height)
  82. _activityView.frame = NSMakeRect((width - activitySize)/2.0,
  83. (height - activitySize)/2.0,
  84. activitySize,
  85. activitySize)
  86. //
  87. // if nil == _shapeLayer {
  88. // _shapeLayer = CAShapeLayer()
  89. // }
  90. // _shapeLayer.frame = _activityView.bounds
  91. // _activityView.wantsLayer = true;
  92. // _activityView.layer?.addSublayer(_shapeLayer)
  93. //
  94. // var mulPath = CGMutablePath()
  95. // let inRadius = activitySize/2 - 3
  96. // let outRadius = activitySize/2
  97. // let endRage = _angle - Double.pi / 3.0
  98. // mulPath.move(to: CGPointMake(activitySize/2.0 + inRadius*sin(_angle),
  99. // activitySize/2.0 + inRadius * cos(_angle)))
  100. // mulPath.addLine(to: CGPointMake(activitySize/2.0 + outRadius*sin(_angle),
  101. // activitySize/2.0 + outRadius * cos(_angle)))
  102. // mulPath.addArc(center: CGPoint(x: activitySize/2.0, y: activitySize/2.0),
  103. // radius: outRadius,
  104. // startAngle: _angle, endAngle: endRage, clockwise: true)
  105. // mulPath.addLine(to: CGPointMake(activitySize/2 + inRadius*sin(endRage),
  106. // activitySize/2 + inRadius * cos(endRage)))
  107. // mulPath.addArc(center: CGPoint(x: activitySize/2.0, y: activitySize/2.0),
  108. // radius: inRadius,
  109. // startAngle: endRage, endAngle: _angle, clockwise: false)
  110. // _shapeLayer.path = mulPath
  111. //// _shapeLayer.lineWidth = 5;
  112. //// _shapeLayer.lineJoin = .bevel
  113. //// _shapeLayer.lineCap = .square
  114. //// _shapeLayer.fillRule = .nonZero
  115. // _shapeLayer.fillColor = NSColor.blue.cgColor
  116. }
  117. /// Update Status
  118. func updateStatus() {
  119. _titleLbl.isHidden = (_status == .Normal || _status == .Process)
  120. // _titleLbl.layer?.opacity = (_status == .Normal || _status == .Process) ? 0:1
  121. _activityView.isHidden = (_status == .Normal || _status == .Wait || _status == .Finished)
  122. // _activityView.layer?.opacity = (_status == .Normal || _status == .Wait || _status == .Finished) ? 0:1
  123. switch _status {
  124. case .Wait: do {
  125. _titleLbl.textColor = NSColor.gray
  126. _titleLbl.layer?.borderColor = NSColor.lightGray.cgColor
  127. _titleLbl.stringValue = "等待中..."
  128. _timer.invalidate()
  129. _timer = Timer()
  130. }
  131. case .Process: do {
  132. // _timer = Timer.scheduledTimer(timeInterval: 1.0/30,
  133. // target: self,
  134. // selector: #selector(updateAnge),
  135. // userInfo: nil, repeats: true)
  136. }
  137. case .Finished: do {
  138. NSLog("_degree=\(_degree)")
  139. _titleLbl.stringValue = NSString(format: "完成 %.0f%%", _degree) as String
  140. if fabs(_degree-100)>=0.1 {
  141. _titleLbl.textColor = NSColor.red
  142. _titleLbl.layer?.borderColor = NSColor.red.cgColor
  143. }else {
  144. _titleLbl.textColor = NSColor.blue
  145. _titleLbl.layer?.borderColor = NSColor.blue.cgColor
  146. }
  147. _timer.invalidate()
  148. _timer = Timer()
  149. }
  150. default: do {
  151. _titleLbl.stringValue = ""
  152. _timer.invalidate()
  153. _timer = Timer()
  154. }
  155. }
  156. }
  157. /// Setter & Getter
  158. ///
  159. func setActivityStatus(_ status:ActivityStatus) {
  160. // if (_status != status) {
  161. _status = status
  162. updateStatus()
  163. // }
  164. }
  165. func activityStatus() -> ActivityStatus {
  166. return _status
  167. }
  168. func setDegree(_ degree:Double) {
  169. _degree = degree;
  170. updateStatus()
  171. }
  172. }