Эх сурвалжийг харах

Usability: make the TerminalView font settable by the native font, not via our internal font structure; Mac terminal app - hook up the zoom in/out/magnification/reset size events

Miguel de Icaza 5 жил өмнө
parent
commit
e15afadd1c

+ 1 - 1
Package.swift

@@ -6,7 +6,7 @@ let package = Package(
     name: "SwiftTerm",
     platforms: [
         .iOS(.v13),
-        //.macOS(.v10_15)
+        .macOS(.v10_15)
     ],
     products: [
         .executable(name: "SwiftTermFuzz", targets: ["SwiftTermFuzz"]),

+ 36 - 15
Sources/SwiftTerm/Apple/AppleTerminalView.swift

@@ -32,12 +32,33 @@ public typealias TTImage = CGImage
 extension TerminalView {
     typealias CellDimension = CGSize
     
-    func setupOptions(width: CGFloat, height: CGFloat)
+    func resetCaches ()
     {
         self.attributes = [:]
         self.urlAttributes = [:]
         self.colors = Array(repeating: nil, count: 256)
         self.trueColors = [:]
+    }
+    
+    // This is invoked when the font changes to recompute state
+    func resetFont()
+    {
+        resetCaches()
+        self.cellDimension = computeFontDimensions ()
+        let newCols = Int(frame.width / cellDimension.width)
+        let newRows = Int(frame.height / cellDimension.height)
+        resize(cols: newCols, rows: newRows)
+        updateCaretView()
+    }
+    
+    func updateCaretView ()
+    {
+        caretView.frame.size = CGSize(width: cellDimension.width, height: cellDimension.height)
+    }
+    
+    func setupOptions(width: CGFloat, height: CGFloat)
+    {
+        resetCaches ()
         // Calculation assume that all glyphs in the font have the same advancement.
         // Get the ascent + descent + leading from the font, already scaled for the font's size
         self.cellDimension = computeFontDimensions ()
@@ -64,7 +85,7 @@ extension TerminalView {
             caretView = CaretView(frame: CGRect(origin: .zero, size: CGSize(width: cellDimension.width, height: cellDimension.height)))
             addSubview(caretView)
         } else {
-            caretView.frame.size = CGSize(width: cellDimension.width, height: cellDimension.height)
+            updateCaretView ()
         }
         
         search = SearchService (terminal: terminal)
@@ -142,14 +163,14 @@ extension TerminalView {
     // Computes the font dimensions once font.normal has been set
     func computeFontDimensions () -> CellDimension
     {
-        let lineAscent = CTFontGetAscent (font.normal)
-        let lineDescent = CTFontGetDescent (font.normal)
-        let lineLeading = CTFontGetLeading (font.normal)
+        let lineAscent = CTFontGetAscent (fontSet.normal)
+        let lineDescent = CTFontGetDescent (fontSet.normal)
+        let lineLeading = CTFontGetLeading (fontSet.normal)
         let cellHeight = ceil(lineAscent + lineDescent + lineLeading)
         #if os(macOS)
-        let cellWidth = font.normal.maximumAdvancement.width
+        let cellWidth = fontSet.normal.maximumAdvancement.width
         #else
-        let fontAttributes = [NSAttributedString.Key.font: font.normal]
+        let fontAttributes = [NSAttributedString.Key.font: fontSet.normal]
         let cellWidth = "W".size(withAttributes: fontAttributes).width
         #endif
         return CellDimension(width: cellWidth, height: cellHeight)
@@ -263,14 +284,14 @@ extension TerminalView {
         let isBold = flags.contains(.bold)
         if isBold {
             if flags.contains (.italic) {
-                tf = font.boldItalic
+                tf = fontSet.boldItalic
             } else {
-                tf = font.bold
+                tf = fontSet.bold
             }
         } else if flags.contains (.italic) {
-            tf = font.italic
+            tf = fontSet.italic
         } else {
-            tf = font.normal
+            tf = fontSet.normal
         }
         
         let fgColor = mapColor (color: fg, isFg: true, isBold: isBold)
@@ -404,13 +425,13 @@ extension TerminalView {
             // draw underline at font.normal.underlinePosition baseline
             let underlineStyle = NSUnderlineStyle(rawValue: attributes[.underlineStyle] as? NSUnderlineStyle.RawValue ?? 0)
             let underlineColor = attributes[.underlineColor] as? TTColor ?? nativeForegroundColor
-            let underlinePosition = font.underlinePosition ()
+            let underlinePosition = fontSet.underlinePosition ()
 
             // draw line at the baseline
             currentContext.setShouldAntialias(false)
             currentContext.setStrokeColor(underlineColor.cgColor)
 
-            let underlineThickness = max(round(scale * font.underlineThickness ()) / scale, 0.5)
+            let underlineThickness = max(round(scale * fontSet.underlineThickness ()) / scale, 0.5)
             for p in positions {
                 switch underlineStyle {
                 case let style where style.contains(.single):
@@ -459,8 +480,8 @@ extension TerminalView {
     // TODO: this should not render any lines outside the dirtyRect
     func drawTerminalContents (dirtyRect: TTRect, context: CGContext)
     {
-        let lineDescent = CTFontGetDescent(font.normal)
-        let lineLeading = CTFontGetLeading(font.normal)
+        let lineDescent = CTFontGetDescent(fontSet.normal)
+        let lineLeading = CTFontGetLeading(fontSet.normal)
 
         // draw lines
         for row in terminal.buffer.yDisp..<terminal.rows + terminal.buffer.yDisp {

+ 17 - 25
Sources/SwiftTerm/Mac/MacTerminalView.swift

@@ -36,7 +36,7 @@ import CoreGraphics
  * defaults, otherwise, this uses its own set of defaults colors.
  */
 open class TerminalView: NSView, NSTextInputClient, NSUserInterfaceValidations {
-    public struct Font {
+    struct FontSet {
         public let normal: NSFont
         let bold: NSFont
         let italic: NSFont
@@ -98,13 +98,21 @@ open class TerminalView: NSView, NSTextInputClient, NSUserInterfaceValidations {
     var trueColors: [Attribute.Color:NSColor] = [:]
     var transparent = TTColor.transparent ()
     
-    /// This font structure represents the font to be used for the terminal
-    public var font: Font {
-        didSet { setupOptions() }
+    var fontSet: FontSet
+
+    /// The font to use to render the terminal
+    public var font: NSFont {
+        get {
+            return fontSet.normal
+        }
+        set {
+            fontSet = FontSet (font: newValue)
+            resetFont()
+        }
     }
     
     public init(frame: CGRect, font: NSFont?) {
-        self.font = Font (font: font ?? Font.defaultFont)
+        self.fontSet = FontSet (font: font ?? FontSet.defaultFont)
 
         super.init (frame: frame)
         setup()
@@ -112,14 +120,14 @@ open class TerminalView: NSView, NSTextInputClient, NSUserInterfaceValidations {
     
     public override init (frame: CGRect)
     {
-        self.font = Font (font: Font.defaultFont)
+        self.fontSet = FontSet (font: FontSet.defaultFont)
         super.init (frame: frame)
         setup()
     }
     
     public required init? (coder: NSCoder)
     {
-        self.font = Font (font: Font.defaultFont)
+        self.fontSet = FontSet (font: FontSet.defaultFont)
         super.init (coder: coder)
         setup()
     }
@@ -961,24 +969,8 @@ open class TerminalView: NSView, NSTextInputClient, NSUserInterfaceValidations {
     
     public func resetFontSize ()
     {
-        font = Font (font: Font.defaultFont)
-    }
-    
-    let fontScale = [9, 10, 11, 13, 14, 18, 24, 36, 48, 64, 72, 96, 144, 288]
-    public func biggerFontSize ()
-    {
-        let current = font.normal.pointSize
-        for x in fontScale {
-            if current < CGFloat (x) {
-                // Set the font size here
-            }
-        }
-    }
-
-    public func smallerFontSize ()
-    {
-
-    }
+        fontSet = FontSet (font: FontSet.defaultFont)
+    }    
 }
 
 extension TerminalView: TerminalDelegate {

+ 2 - 0
Sources/SwiftTerm/Terminal.swift

@@ -4030,6 +4030,8 @@ open class Terminal {
         buffers.resize(newColumns: newCols, newRows: newRows)
         self.cols = newCols
         self.rows = newRows
+        options.cols = newCols
+        options.rows = newRows
         buffer.setupTabStops (index: oldCols)
         refresh (startRow: 0, endRow: self.rows - 1)
     }

+ 14 - 9
Sources/SwiftTerm/iOS/iOSTerminalView.swift

@@ -33,7 +33,7 @@ import CoreGraphics
  * defaults, otherwise, this uses its own set of defaults colors.
  */
 open class TerminalView: UIScrollView, UITextInputTraits, UIKeyInput, UIScrollViewDelegate {
-    public struct Font {
+    struct FontSet {
         public let normal: UIFont
         let bold: UIFont
         let italic: UIFont
@@ -88,30 +88,35 @@ open class TerminalView: UIScrollView, UITextInputTraits, UIKeyInput, UIScrollVi
     var colors: [UIColor?] = Array(repeating: nil, count: 256)
     var trueColors: [Attribute.Color:UIColor] = [:]
     var transparent = TTColor.transparent ()
-    
-    /// This font structure represents the font to be used for the terminal
-    public var font: Font {
-        didSet {
-            setupOptions()
+
+    var fontSet: FontSet
+    /// The font to use to render the terminal
+    public var font: UIFont {
+        get {
+            return fontSet.normal
+        }
+        set {
+            fontSet = FontSet (font: newValue)
+            resetFont();
         }
     }
     
     public init(frame: CGRect, font: UIFont?) {
-        self.font = Font (font: font ?? Font.defaultFont)
+        self.fontSet = FontSet (font: font ?? FontSet.defaultFont)
         super.init (frame: frame)
         setup()
     }
     
     public override init (frame: CGRect)
     {
-        self.font = Font (font: Font.defaultFont)
+        self.fontSet = FontSet (font: FontSet.defaultFont)
         super.init (frame: frame)
         setup()
     }
     
     public required init? (coder: NSCoder)
     {
-        self.font = Font (font: Font.defaultFont)
+        self.fontSet = FontSet (font: FontSet.defaultFont)
         super.init (coder: coder)
         setup()
     }

+ 1 - 1
SwiftSH.binaries

@@ -1 +1 @@
-Subproject commit 05291e0180553bbf58e694d3e2a89e66e75c0659
+Subproject commit 7f64bf1802c4fa2670d8bc39ea07750557269ed9

+ 17 - 5
TerminalApp/MacTerminal/Base.lproj/Main.storyboard

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
+<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16097"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <scenes>
@@ -262,9 +262,21 @@
                                             </connections>
                                         </menuItem>
                                         <menuItem isSeparatorItem="YES" id="jmg-UD-vBX"/>
-                                        <menuItem title="Default Font Size" keyEquivalent="0" id="ygS-hf-vVv"/>
-                                        <menuItem title="Bigger" keyEquivalent="+" id="CdY-Sy-zOI"/>
-                                        <menuItem title="Item" keyEquivalent="-" id="mcO-ZB-xGf"/>
+                                        <menuItem title="Default Font Size" keyEquivalent="0" id="ygS-hf-vVv">
+                                            <connections>
+                                                <action selector="defaultFontSize:" target="Ady-hI-5gd" id="Tw1-d1-QIC"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Bigger" keyEquivalent="+" id="CdY-Sy-zOI">
+                                            <connections>
+                                                <action selector="biggerFont:" target="Ady-hI-5gd" id="98A-AC-yxD"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Smaller" keyEquivalent="-" id="mcO-ZB-xGf">
+                                            <connections>
+                                                <action selector="smallerFont:" target="Ady-hI-5gd" id="3QY-zi-jNv"/>
+                                            </connections>
+                                        </menuItem>
                                         <menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
                                         <menuItem title="Allow Mouse Reporting" keyEquivalent="r" id="jzH-qx-TzS">
                                             <connections>

+ 42 - 20
TerminalApp/MacTerminal/ViewController.swift

@@ -14,7 +14,8 @@ class ViewController: NSViewController, LocalProcessTerminalViewDelegate, NSUser
 
     var changingSize = false
     var logging: Bool = false
-
+    var zoomGesture: NSMagnificationGestureRecognizer?
+    
     func sizeChanged(source: LocalProcessTerminalView, newCols: Int, newRows: Int) {
         if changingSize {
             return
@@ -57,7 +58,8 @@ class ViewController: NSViewController, LocalProcessTerminalViewDelegate, NSUser
         super.viewDidLoad()
 
         terminal = LocalProcessTerminalView(frame: view.frame)
-        
+        zoomGesture = NSMagnificationGestureRecognizer(target: self, action: #selector(zoomGestureHandler))
+        terminal.addGestureRecognizer(zoomGesture!)
         ViewController.lastTerminal = terminal
         terminal.processDelegate = self
         terminal.feed(text: "Welcome to SwiftTerm")
@@ -67,6 +69,15 @@ class ViewController: NSViewController, LocalProcessTerminalViewDelegate, NSUser
         logging = NSUserDefaultsController.shared.defaults.bool(forKey: "LogHostOutput")
         updateLogging ()
     }
+    
+    @objc
+    func zoomGestureHandler (_ sender: NSMagnificationGestureRecognizer) {
+        if sender.magnification > 0 {
+            biggerFont (sender)
+        } else {
+            smallerFont(sender)
+        }
+    }
 
     override func viewDidLayout() {
         super.viewDidLayout()
@@ -175,6 +186,35 @@ class ViewController: NSViewController, LocalProcessTerminalViewDelegate, NSUser
         terminal.optionAsMetaKey.toggle ()
     }
     
+    @objc @IBAction
+    func biggerFont (_ source: AnyObject)
+    {
+        let size = terminal.font.pointSize
+        guard size < 72 else {
+            return
+        }
+        
+        terminal.font = NSFont.monospacedSystemFont(ofSize: size+1, weight: .regular)
+    }
+
+    @objc @IBAction
+    func smallerFont (_ source: AnyObject)
+    {
+        let size = terminal.font.pointSize
+        guard size > 5 else {
+            return
+        }
+        
+        terminal.font = NSFont.monospacedSystemFont(ofSize: size-1, weight: .regular)
+    }
+
+    @objc @IBAction
+    func defaultFontSize  (_ source: AnyObject)
+    {
+        terminal.font = NSFont.monospacedSystemFont(ofSize: NSFont.systemFontSize, weight: .regular)
+    }
+    
+
     @objc @IBAction
     func addTab (_ source: AnyObject)
     {
@@ -233,24 +273,6 @@ class ViewController: NSViewController, LocalProcessTerminalViewDelegate, NSUser
         return true
     }
     
-    @objc @IBAction
-    func defaultFontSize  (_ source: AnyObject)
-    {
-        
-    }
-    
-    @objc @IBAction
-    func biggerFontSize (_ source: AnyObject)
-    {
-        
-    }
-    
-    @objc @IBAction
-    func smallerFontSize (_ source: AnyObject)
-    {
-        
-    }
-    
     @objc @IBAction
     func debugToggleHostLogging (_ source: AnyObject)
     {