ViewController.swift 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. //
  2. // ViewController.swift
  3. // MacTerminal
  4. //
  5. // Created by Miguel de Icaza on 3/11/20.
  6. // Copyright © 2020 Miguel de Icaza. All rights reserved.
  7. //
  8. import Cocoa
  9. import SwiftTerm
  10. class ViewController: NSViewController, LocalProcessTerminalViewDelegate, NSUserInterfaceValidations {
  11. @IBOutlet var loggingMenuItem: NSMenuItem?
  12. var changingSize = false
  13. var logging: Bool = false
  14. func sizeChanged(source: LocalProcessTerminalView, newCols: Int, newRows: Int) {
  15. if changingSize {
  16. return
  17. }
  18. changingSize = true
  19. //var border = view.window!.frame - view.frame
  20. var newFrame = terminal.getOptimalFrameSize ()
  21. let windowFrame = view.window!.frame
  22. newFrame = CGRect (x: windowFrame.minX, y: windowFrame.minY, width: newFrame.width, height: windowFrame.height - view.frame.height + newFrame.height)
  23. view.window?.setFrame(newFrame, display: true, animate: true)
  24. changingSize = false
  25. }
  26. func setTerminalTitle(source: LocalProcessTerminalView, title: String) {
  27. view.window?.title = title
  28. }
  29. func processTerminated(source: TerminalView, exitCode: Int32?) {
  30. view.window?.close()
  31. if let e = exitCode {
  32. print ("Process terminated with code: \(e)")
  33. } else {
  34. print ("Process vanished")
  35. }
  36. }
  37. var terminal: LocalProcessTerminalView!
  38. static var lastTerminal: LocalProcessTerminalView!
  39. func updateLogging ()
  40. {
  41. let path = logging ? "/Users/miguel/Downloads/Logs" : nil
  42. terminal.setHostLogging (directory: path)
  43. NSUserDefaultsController.shared.defaults.set (logging, forKey: "LogHostOutput")
  44. }
  45. override func viewDidLoad() {
  46. super.viewDidLoad()
  47. terminal = LocalProcessTerminalView(frame: view.frame)
  48. ViewController.lastTerminal = terminal
  49. terminal.processDelegate = self
  50. terminal.feed(text: "Welcome to SwiftTerm")
  51. terminal.startProcess ()
  52. view.addSubview(terminal)
  53. logging = NSUserDefaultsController.shared.defaults.bool(forKey: "LogHostOutput")
  54. updateLogging ()
  55. }
  56. override func viewDidLayout() {
  57. super.viewDidLayout()
  58. changingSize = true
  59. terminal.frame = view.frame
  60. changingSize = false
  61. terminal.needsLayout = true
  62. }
  63. @objc @IBAction
  64. func set80x25 (_ source: AnyObject)
  65. {
  66. terminal.resize(cols: 80, rows: 25)
  67. }
  68. var lowerCol = 80
  69. var lowerRow = 25
  70. var higherCol = 160
  71. var higherRow = 60
  72. func queueNextSize ()
  73. {
  74. // If they requested a stop
  75. if resizificating == 0 {
  76. return
  77. }
  78. var next = terminal.getTerminal().getDims ()
  79. if resizificating > 0 {
  80. if next.cols < higherCol {
  81. next.cols += 1
  82. }
  83. if next.rows < higherRow {
  84. next.rows += 1
  85. }
  86. } else {
  87. if next.cols > lowerCol {
  88. next.cols -= 1
  89. }
  90. if next.rows > lowerRow {
  91. next.rows -= 1
  92. }
  93. }
  94. terminal.resize (cols: next.cols, rows: next.rows)
  95. var direction = resizificating
  96. if next.rows == higherRow && next.cols == higherCol {
  97. direction = -1
  98. }
  99. if next.rows == lowerRow && next.cols == lowerCol {
  100. direction = 1
  101. }
  102. DispatchQueue.main.asyncAfter(deadline: .now() + 0.03) {
  103. self.resizificating = direction
  104. self.queueNextSize()
  105. }
  106. }
  107. var resizificating = 0
  108. @objc @IBAction
  109. func resizificator (_ source: AnyObject)
  110. {
  111. if resizificating != 1 {
  112. resizificating = 1
  113. queueNextSize ()
  114. } else {
  115. resizificating = 0
  116. }
  117. }
  118. @objc @IBAction
  119. func resizificatorDown (_ source: AnyObject)
  120. {
  121. if resizificating != -1 {
  122. resizificating = -1
  123. queueNextSize ()
  124. } else {
  125. resizificating = 0
  126. }
  127. }
  128. @objc @IBAction
  129. func allowMouseReporting (_ source: AnyObject)
  130. {
  131. terminal.allowMouseReporting.toggle ()
  132. }
  133. @objc @IBAction
  134. func softReset (_ source: AnyObject)
  135. {
  136. terminal.getTerminal().softReset ()
  137. terminal.setNeedsDisplay(terminal.frame)
  138. }
  139. @objc @IBAction
  140. func hardReset (_ source: AnyObject)
  141. {
  142. terminal.getTerminal().resetToInitialState ()
  143. terminal.setNeedsDisplay(terminal.frame)
  144. }
  145. @objc @IBAction
  146. func toggleOptionAsMetaKey (_ source: AnyObject)
  147. {
  148. terminal.optionAsMetaKey.toggle ()
  149. }
  150. @objc @IBAction
  151. func addTab (_ source: AnyObject)
  152. {
  153. // if let win = view.window {
  154. // win.tabbingMode = .preferred
  155. // if let wc = win.windowController {
  156. // if let d = wc.document as? Document {
  157. // do {
  158. // let x = Document()
  159. // x.makeWindowControllers()
  160. //
  161. // try NSDocumentController.shared.newDocument(self)
  162. // } catch {}
  163. // print ("\(d.debugDescription)")
  164. // }
  165. // }
  166. // }
  167. // win.tabbingMode = .preferred
  168. // win.addTabbedWindow(win, ordered: .above)
  169. //
  170. // if let wc = win.windowController {
  171. // wc.newWindowForTab(self()
  172. // wc.showWindow(source)
  173. // }
  174. // }
  175. }
  176. func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool
  177. {
  178. if item.action == #selector(debugToggleHostLogging(_:)) {
  179. if let m = item as? NSMenuItem {
  180. m.state = logging ? NSControl.StateValue.on : NSControl.StateValue.off
  181. }
  182. }
  183. if item.action == #selector(resizificator(_:)) {
  184. if let m = item as? NSMenuItem {
  185. m.state = resizificating == 1 ? NSControl.StateValue.on : NSControl.StateValue.off
  186. }
  187. }
  188. if item.action == #selector(resizificatorDown(_:)) {
  189. if let m = item as? NSMenuItem {
  190. m.state = resizificating == -1 ? NSControl.StateValue.on : NSControl.StateValue.off
  191. }
  192. }
  193. if item.action == #selector(allowMouseReporting(_:)) {
  194. if let m = item as? NSMenuItem {
  195. m.state = terminal.allowMouseReporting ? NSControl.StateValue.on : NSControl.StateValue.off
  196. }
  197. }
  198. if item.action == #selector(toggleOptionAsMetaKey(_:)) {
  199. if let m = item as? NSMenuItem {
  200. m.state = terminal.optionAsMetaKey ? NSControl.StateValue.on : NSControl.StateValue.off
  201. }
  202. }
  203. return true
  204. }
  205. @objc @IBAction
  206. func defaultFontSize (_ source: AnyObject)
  207. {
  208. }
  209. @objc @IBAction
  210. func biggerFontSize (_ source: AnyObject)
  211. {
  212. }
  213. @objc @IBAction
  214. func smallerFontSize (_ source: AnyObject)
  215. {
  216. }
  217. @objc @IBAction
  218. func debugToggleHostLogging (_ source: AnyObject)
  219. {
  220. logging = !logging
  221. updateLogging()
  222. }
  223. }