fix: better textareas

This commit is contained in:
louis.pontoise authored and lwouis committed 2020-03-10 14:00:37 +09:00
1 parent cf92dc1e71
commit efc9bd3d3e
2 files changed
+48 -26

No files matched your search

+7 -10
View File
@@ -1,6 +1,6 @@
import Cocoa import Cocoa
class FeedbackWindow: NSWindow, NSTextViewDelegate { class FeedbackWindow: NSWindow {
var body: TextArea! var body: TextArea!
var email: TextArea! var email: TextArea!
var sendButton: NSButton! var sendButton: NSButton!
@@ -44,8 +44,9 @@ class FeedbackWindow: NSWindow, NSTextViewDelegate {
sendButton, sendButton,
]) ])
buttons.spacing = GridView.interPadding buttons.spacing = GridView.interPadding
body = TextArea(80, 20, "I think the app could be improved with…") body = TextArea(80, 12, "I think the app could be improved with…", {
body.delegate = self self.sendButton.isEnabled = !self.body.stringValue.isEmpty
})
email = TextArea(80, 1, "Optional: email (if you want a reply)") email = TextArea(80, 1, "Optional: email (if you want a reply)")
debugProfile = NSButton(checkboxWithTitle: "Send debug profile (CPU, memory, etc)", target: nil, action: nil) debugProfile = NSButton(checkboxWithTitle: "Send debug profile (CPU, memory, etc)", target: nil, action: nil)
debugProfile.state = .on debugProfile.state = .on
@@ -61,10 +62,6 @@ class FeedbackWindow: NSWindow, NSTextViewDelegate {
contentView = view contentView = view
} }
func textDidChange(_ notification: Notification) {
sendButton.isEnabled = !body.string.isEmpty
}
@objc @objc
private func cancelCallback(senderControl: NSControl) { private func cancelCallback(senderControl: NSControl) {
close() close()
@@ -97,11 +94,11 @@ class FeedbackWindow: NSWindow, NSTextViewDelegate {
private func assembleBody() -> String { private func assembleBody() -> String {
var result = "" var result = ""
result += "_This issue was opened by a bot after a user submitted feedback through the in-app form._" result += "_This issue was opened by a bot after a user submitted feedback through the in-app form._"
if !email.string.isEmpty { if !email.stringValue.isEmpty {
result += "\n\n__From:__ " + email.string result += "\n\n__From:__ " + email.stringValue
} }
result += "\n\n__Message:__" result += "\n\n__Message:__"
result += "\n\n> " + body.string.replacingOccurrences(of: "\n", with: "\n> ") result += "\n\n> " + body.stringValue.replacingOccurrences(of: "\n", with: "\n> ")
if debugProfile.state == .on { if debugProfile.state == .on {
result += "\n\n__Debug profile:__" result += "\n\n__Debug profile:__"
result += "\n\n" + DebugProfile.make() result += "\n\n" + DebugProfile.make()
@@ -1,23 +1,48 @@
import Cocoa import Cocoa
class TextArea: NSTextView { class TextArea: NSTextField, NSTextFieldDelegate {
static let padding = CGFloat(10) static let padding = CGFloat(5)
static let magicOffset = CGFloat(3) var callback: (() -> Void)!
@objc var placeholderAttributedString: NSAttributedString?
convenience init(_ width: CGFloat, _ height: CGFloat, _ placeholder: String) { convenience init(_ nCharactersWide: CGFloat, _ nLinesHigh: Int, _ placeholder: String, _ callback: (() -> Void)? = nil) {
self.init(frame: .zero) self.init(frame: .zero)
allowsUndo = true self.callback = callback
delegate = self
cell = TextFieldCell(placeholder, nLinesHigh == 1)
fit(font!.xHeight * nCharactersWide + TextArea.padding * 2, fittingSize.height * CGFloat(nLinesHigh) + TextArea.padding * 2)
}
func controlTextDidChange(_ notification: Notification) {
callback?()
}
// enter key inserts new line instead of submitting
func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
guard commandSelector == #selector(NSResponder.insertNewline) else { return false }
textView.insertNewlineIgnoringFieldEditor(self)
return true
}
}
// subclassing NSTextFieldCell is done uniquely to add padding
class TextFieldCell: NSTextFieldCell {
convenience init(_ placeholder: String, _ usesSingleLineMode: Bool) {
self.init()
isBordered = true
isBezeled = true
isEditable = true
font = NSFont.systemFont(ofSize: NSFont.systemFontSize) font = NSFont.systemFont(ofSize: NSFont.systemFontSize)
textContainerInset = NSSize(width: TextArea.padding, height: TextArea.padding) stringValue = ""
textContainer!.lineFragmentPadding = 0 placeholderString = placeholder
let paragraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle self.usesSingleLineMode = usesSingleLineMode
paragraphStyle.maximumLineHeight = NSFont.systemFontSize + TextArea.magicOffset }
placeholderAttributedString = NSAttributedString(string: placeholder, attributes: [
NSAttributedString.Key.font: NSFont.systemFont(ofSize: NSFont.systemFontSize), override func drawingRect(forBounds rect: NSRect) -> NSRect {
NSAttributedString.Key.foregroundColor: NSColor.gray, return super.drawingRect(forBounds: NSMakeRect(
NSAttributedString.Key.paragraphStyle: paragraphStyle, rect.origin.x + TextArea.padding,
]) rect.origin.y + TextArea.padding,
fit(font!.xHeight * width + TextArea.padding * 2, NSFont.systemFontSize * height + TextArea.padding * 2 + TextArea.magicOffset) rect.size.width - TextArea.padding * 2,
rect.size.height - TextArea.padding * 2
))
} }
} }