Skip to content

Commit

Permalink
New implementation of NSScrollView, cleaned up some
Browse files Browse the repository at this point in the history
  • Loading branch information
antingle committed Apr 30, 2022
1 parent 3d05200 commit 2e8ff08
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 274 deletions.
8 changes: 4 additions & 4 deletions Calculator.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
9218BABD280DB3E90068F3AF /* MacEditorTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9218BABC280DB3E90068F3AF /* MacEditorTextView.swift */; };
925E9140281D02AC0027E183 /* CustomMacTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 925E913F281D02AC0027E183 /* CustomMacTextView.swift */; };
928D96C6280A8F9300B6CE2E /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 928D96C5280A8F9300B6CE2E /* ButtonView.swift */; };
928D96C8280AA58D00B6CE2E /* CalculatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 928D96C7280AA58D00B6CE2E /* CalculatorView.swift */; };
928D96CA280AA5E400B6CE2E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 928D96C9280AA5E400B6CE2E /* SettingsView.swift */; };
Expand All @@ -22,7 +22,7 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
9218BABC280DB3E90068F3AF /* MacEditorTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacEditorTextView.swift; sourceTree = "<group>"; };
925E913F281D02AC0027E183 /* CustomMacTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomMacTextView.swift; sourceTree = "<group>"; };
928D96C5280A8F9300B6CE2E /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = "<group>"; };
928D96C7280AA58D00B6CE2E /* CalculatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalculatorView.swift; sourceTree = "<group>"; };
928D96C9280AA5E400B6CE2E /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -70,7 +70,7 @@
isa = PBXGroup;
children = (
92F447832808C1B600EC45D5 /* Info.plist */,
9218BABC280DB3E90068F3AF /* MacEditorTextView.swift */,
925E913F281D02AC0027E183 /* CustomMacTextView.swift */,
92F4476B28089FEE00EC45D5 /* CalculatorApp.swift */,
92F447842808C25800EC45D5 /* AppDelegate.swift */,
92F4476D28089FEE00EC45D5 /* ContentView.swift */,
Expand Down Expand Up @@ -175,10 +175,10 @@
928D96CA280AA5E400B6CE2E /* SettingsView.swift in Sources */,
928D96C8280AA58D00B6CE2E /* CalculatorView.swift in Sources */,
928D96C6280A8F9300B6CE2E /* ButtonView.swift in Sources */,
925E9140281D02AC0027E183 /* CustomMacTextView.swift in Sources */,
92F4476E28089FEE00EC45D5 /* ContentView.swift in Sources */,
92F447852808C25800EC45D5 /* AppDelegate.swift in Sources */,
92F4476C28089FEE00EC45D5 /* CalculatorApp.swift in Sources */,
9218BABD280DB3E90068F3AF /* MacEditorTextView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
4 changes: 4 additions & 0 deletions Calculator/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,24 @@ class AppDelegate: NSObject, NSApplicationDelegate {
statusBarItem?.button?.image = NSImage(systemSymbolName: "function", accessibilityDescription: "calculator")
statusBarItem?.button?.action = #selector(AppDelegate.togglePopover(_:))

// enables global shortcut
hotKey.keyDownHandler = {
self.togglePopover(self)
}

}

@objc func showPopover(_ sender: AnyObject?) {
if let button = statusBarItem?.button {
popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
// !!! - displays the popover window with an offset in x in macOS BigSur.
}
}

@objc func closePopover(_ sender: AnyObject?) {
popover.performClose(sender)
}

@objc func togglePopover(_ sender: AnyObject?) {
if popover.isShown {
closePopover(sender)
Expand Down
4 changes: 2 additions & 2 deletions Calculator/CalculatorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ struct CalculatorView: View {
}).rotationEffect(Angle(degrees: 180)).scaleEffect(x: -1.0, y: 1.0, anchor: .center)


MacEditorTextView(text: $expression, placeholderText: "Calculate",
CustomMacTextView(placeholderText: "Calculate", text: $expression,
// Run when submmitting the text (hitting return)
onCommit: {
onSubmit: {
do {
solution = try evaluateExpression(expression)

Expand Down
119 changes: 119 additions & 0 deletions Calculator/CustomMacTextView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//
// CustomMacTextView.swift
//
// Foundation by Marc Maset - 2021
// Changes inspired from MacEditorTextView by Thiago Holanda
//
// Modified by Anthony Ingle - 2022
//

import SwiftUI

struct CustomMacTextView: NSViewRepresentable {

var placeholderText: String?
@Binding var text: String
var font: NSFont = .systemFont(ofSize: 14, weight: .regular)

var onSubmit : () -> Void = {}
var onTextChange : (String) -> Void = { _ in }
var onEditingChanged: () -> Void = {}

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

func makeNSView(context: Context) -> NSScrollView {
let theTextView = PlaceholderNSTextView.scrollableTextView()
let textView = (theTextView.documentView as! PlaceholderNSTextView)
textView.delegate = context.coordinator
textView.string = text
textView.drawsBackground = false
textView.font = font
textView.placeholderText = placeholderText
theTextView.hasVerticalScroller = false

return theTextView
}

func updateNSView(_ view: NSScrollView, context: Context) {
guard let textView = view.documentView as? NSTextView else {
return
}

textView.string = text
}

}

extension CustomMacTextView {

class Coordinator: NSObject, NSTextViewDelegate {

var parent: CustomMacTextView
var affectedCharRange: NSRange?

init(_ parent: CustomMacTextView) {
self.parent = parent
}
func textDidBeginEditing(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}

self.parent.text = textView.string
self.parent.onEditingChanged()
}

func textDidChange(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}

// Update text
self.parent.text = textView.string
self.parent.onTextChange(textView.string)
}

func textDidEndEditing(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}

self.parent.text = textView.string
self.parent.onSubmit()
}


func textView(_ textView: NSTextView, shouldChangeTextIn affectedCharRange: NSRange, replacementString: String?) -> Bool {
return true
}

// handles commands
func textView(_ textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
if (commandSelector == #selector(NSResponder.insertNewline(_:))) {
// Do something against ENTER key
self.parent.onSubmit()
return true
}

// return true if the action was handled; otherwise false
return false
}

}
}

// for setting a proper placeholder text on an NSTextView
fileprivate class PlaceholderNSTextView: NSTextView {
@objc private var placeholderAttributedString: NSAttributedString?
var placeholderText: String? {
didSet {
var attributes = [NSAttributedString.Key: AnyObject]()
attributes[.font] = font
attributes[.foregroundColor] = NSColor.gray
let captionAttributedString = NSAttributedString(string: placeholderText ?? "", attributes: attributes)
placeholderAttributedString = captionAttributedString
}
}
}
Loading

0 comments on commit 2e8ff08

Please sign in to comment.