ActivityView.swift 6.6 KB

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