Skip to content

Commit 658f285

Browse files
committed
address a bunch of feature requests
1 parent e3df1a0 commit 658f285

File tree

3 files changed

+155
-25
lines changed

3 files changed

+155
-25
lines changed

swift/qmoji/AppDelegate.swift

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ func fourCharCodeValue(string: String) -> Int {
2828
}
2929

3030
let showAtMouseKey = "showAtMouse"
31+
let shortcutKeyKey = "shortcutKey"
3132

3233
@main
3334
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
@@ -41,13 +42,25 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
4142
var popover: NSPopover!
4243
var window: NSWindow!
4344
var statusBarItem: NSStatusItem!
44-
var hotKeyRef: UnsafeMutablePointer<EventHotKeyRef?>!
45+
// var hotKeyRef: UnsafeMutablePointer<EventHotKeyRef?>?
4546
var showAtMouse: Bool = UserDefaults.standard.bool(forKey: showAtMouseKey)
47+
var shortcutKey: Int = {
48+
if UserDefaults.standard.string(forKey: shortcutKeyKey) == nil {
49+
return 0x31
50+
}
51+
return UserDefaults.standard.integer(forKey: shortcutKeyKey)
52+
}()
53+
var hotKeyRef: EventHotKeyRef?
4654

4755
@objc func onClick() {
4856
print("Hello")
4957
}
5058

59+
func setShortcutKey(key: Int) {
60+
registerHotkey(keyCode: key)
61+
UserDefaults.standard.set(key, forKey: shortcutKeyKey)
62+
}
63+
5164
func toggleShowAtMouse() {
5265
self.showAtMouse = !self.showAtMouse
5366
UserDefaults.standard.set(self.showAtMouse, forKey: showAtMouseKey)
@@ -91,15 +104,21 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
91104
button.action = #selector(toggle(_:))
92105
}
93106

94-
let keyCode = 0x1F // 0x31
95-
registerHotkey(keyCode: keyCode)
107+
// let keyCode = 0x1F // 0x31
108+
registerHotkey(keyCode: shortcutKey)
96109
}
97110

98111
func windowDidResignKey(_ notification: Notification) {
99112
NSApp.hide(nil)
100113
}
101114

102115
func registerHotkey(keyCode: Int) {
116+
if let current = hotKeyRef {
117+
UnregisterEventHotKey(current)
118+
}
119+
120+
let hotKeyRef = UnsafeMutablePointer<EventHotKeyRef?>.allocate(capacity: 1)
121+
103122
var gMyHotKeyID = EventHotKeyID()
104123
gMyHotKeyID.signature = OSType(fourCharCodeValue(string: "hotk"))
105124
gMyHotKeyID.id = UInt32(keyCode)
@@ -109,7 +128,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
109128
eventType.eventClass = OSType(kEventClassKeyboard)
110129
eventType.eventKind = OSType(kEventHotKeyPressed)
111130

112-
hotKeyRef = UnsafeMutablePointer<EventHotKeyRef?>.allocate(capacity: 1)
113131
// Install handler.
114132
InstallEventHandler(GetApplicationEventTarget(), {(nextHanlder, theEvent, userData) -> OSStatus in
115133
var hkCom = EventHotKeyID()
@@ -130,6 +148,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
130148
// Register hotkey.
131149
let status = RegisterEventHotKey(UInt32(keyCode), UInt32(cmdKey + optionKey), gMyHotKeyID, GetApplicationEventTarget(), 0, hotKeyRef)
132150
print("The status", status)
151+
152+
self.hotKeyRef = hotKeyRef.pointee
133153
}
134154

135155
func togglePopover(_ sender: AnyObject?) {

swift/qmoji/CustomView.swift

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ func sendKeystrokesToFrontmostApp(_ string: String) {
7171
keyup.postToPid(pid)
7272
}
7373

74+
func sortUsages(one: Usage, two: Usage) -> Bool {
75+
if one.count == two.count {
76+
return one.date > two.date
77+
} else {
78+
return one.count > two.count
79+
}
80+
}
81+
7482
struct Cache {
7583
var cached: [Emoji]
7684
var searchTerm: String
@@ -81,15 +89,7 @@ struct Cache {
8189
var used = emojis.filter({emoji in usages[emoji.id] != nil})
8290
let unused = emojis.filter({emoji in usages[emoji.id] == nil})
8391
used.sort(by: { one, two in
84-
let oc = usages[one.id]!.count
85-
let od = usages[one.id]!.date
86-
let tc = usages[two.id]!.count
87-
let td = usages[two.id]!.date
88-
if oc == tc {
89-
return od > td
90-
} else {
91-
return oc > tc
92-
}
92+
return sortUsages(one: usages[one.id]!, two: usages[two.id]!)
9393
})
9494
used.append(contentsOf: unused)
9595
cached = used
@@ -205,15 +205,36 @@ class CustomView: NSView {
205205
usage.date = Date.init().timeIntervalSince1970
206206
self.usages[id] = usage
207207
} else {
208+
// Bring it down to 20 if needed
209+
if self.usages.count >= 20 {
210+
let ids = self.usages.keys.sorted(by: {one, two in sortUsages(one: self.usages[one]!, two: self.usages[two]!)})
211+
for i in 19...ids.count - 1 {
212+
self.usages.remove(at: self.usages.index(forKey: ids[i])!)
213+
}
214+
}
208215
self.usages[id] = Usage(name: id, count: 1, date: Date.init().timeIntervalSince1970)
209216
}
217+
saveUsages()
218+
}
219+
220+
func saveUsages() {
210221
self.filterCache = Cache(searchTerm: _searchTerm, usages: usages)
211222
self.setNeedsDisplay(self.bounds)
212223
let encoder = JSONEncoder()
213224
if let encoded = try? encoder.encode(self.usages) {
214225
UserDefaults.standard.set(encoded, forKey: usageKey)
215226
}
216227
}
228+
229+
func removeUsage() {
230+
let filtered = sortedEmoijs()
231+
if filtered.isEmpty || self.selected > filtered.count {
232+
return
233+
}
234+
let emoji = filtered[self.selected]
235+
self.usages.remove(at: self.usages.index(forKey: emoji.id)!)
236+
saveUsages()
237+
}
217238

218239
func sendKey() {
219240
let filtered = sortedEmoijs()
@@ -233,6 +254,10 @@ class CustomView: NSView {
233254
onClear()
234255
searchTerm = ""
235256
}
257+
258+
override func rightMouseDown(with event: NSEvent) {
259+
removeUsage()
260+
}
236261

237262
override func mouseDown(with event: NSEvent) {
238263
sendKey()

swift/qmoji/ViewController.swift

Lines changed: 97 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,69 @@ struct Usage: Codable {
1919
var date: Double
2020
}
2121

22+
class MyText: NSTextField {
23+
24+
25+
override func keyDown(with event: NSEvent) {
26+
print("WHAT", event.keyCode)
27+
}
28+
}
29+
30+
class NewShortcutKey: NSViewController, NSTextFieldDelegate {
31+
var label: NSTextField!
32+
var onDismiss: (() -> ())!
33+
var currentCode: Int = AppDelegate.shared.shortcutKey
34+
35+
override func loadView() {
36+
self.view = NSView()
37+
}
38+
39+
@objc func onSet() {
40+
AppDelegate.shared.setShortcutKey(key: currentCode)
41+
onDismiss()
42+
}
43+
44+
override func viewDidLoad() {
45+
self.view.setFrameSize(NSSize(width: width, height: 60))
46+
47+
NSEvent.addLocalMonitorForEvents(matching: .keyDown, handler: {event in
48+
print("Event", event.keyCode)
49+
if event.keyCode == 53 {
50+
self.onDismiss()
51+
}
52+
self.currentCode = Int(event.keyCode)
53+
self.label.stringValue = "Key code: \(self.currentCode)"
54+
return nil
55+
})
56+
57+
let button = NSButton()
58+
button.title = "Update shortcut key"
59+
button.setFrameOrigin(NSPoint(x: margin, y: 0))
60+
button.setFrameSize(NSSize(width: width - margin * 2, height: 20))
61+
button.action = #selector(onSet)
62+
button.target = self
63+
64+
label = NSTextField(labelWithString: "Key code: \(currentCode)")
65+
label.lineBreakMode = .byWordWrapping
66+
label.setFrameOrigin(NSPoint(x: 0, y: 20))
67+
label.setFrameSize(NSSize(width: width - margin * 2, height: 20))
68+
self.view.addSubview(label)
69+
70+
let description = NSTextField(labelWithString: "Type any key. Escape to cancel.")
71+
description.setFrameOrigin(NSPoint(x: 0, y: 40))
72+
description.setFrameSize(NSSize(width: width - margin * 2, height: 20))
73+
self.view.addSubview(description)
74+
75+
self.view.addSubview(button)
76+
self.view.becomeFirstResponder()
77+
}
78+
79+
override func keyDown(with event: NSEvent) {
80+
label.stringValue = "\(event.keyCode)"
81+
print("OK")
82+
}
83+
}
84+
2285
class MyVC: NSViewController, NSTextFieldDelegate {
2386
var textField: NSTextField!
2487
var customView: CustomView!
@@ -29,6 +92,8 @@ class MyVC: NSViewController, NSTextFieldDelegate {
2992
var showAtCursor: NSMenuItem!
3093
var menuButton: NSButton!
3194

95+
var shortcutPopover: NSPopover!
96+
3297
override func loadView() {
3398
self.view = NSView()
3499
}
@@ -48,6 +113,13 @@ class MyVC: NSViewController, NSTextFieldDelegate {
48113
NSApp.terminate(nil)
49114
}
50115

116+
@objc func setShortcutKey() {
117+
print("Set shortcut key")
118+
// AppDelegate.shared.registerHotkey(keyCode: 0x31)
119+
shortcutPopover.show(relativeTo: menuButton.bounds, of: menuButton, preferredEdge: NSRectEdge.minY)
120+
// shortcutPopover.pres
121+
}
122+
51123
override func viewDidLoad() {
52124
let buttonSize = 20
53125

@@ -73,9 +145,16 @@ class MyVC: NSViewController, NSTextFieldDelegate {
73145
showAtCursor = NSMenuItem(title: "Show at cursor", action: #selector(toggleShowAtCursor), keyEquivalent: "")
74146
showAtCursor.state = AppDelegate.shared.showAtMouse ? .on : .off
75147
optionsMenu.addItem(showAtCursor)
148+
optionsMenu.addItem(withTitle: "Change shortcut key", action: #selector(setShortcutKey), keyEquivalent: "")
76149
optionsMenu.addItem(withTitle: "Quit", action: #selector(onQuit), keyEquivalent: "")
77150

78151

152+
shortcutPopover = NSPopover()
153+
let ksvc = NewShortcutKey()
154+
ksvc.onDismiss = {
155+
self.shortcutPopover.performClose(nil)
156+
}
157+
shortcutPopover.contentViewController = ksvc
79158

80159
let decoder = JSONDecoder()
81160
if let data = UserDefaults.standard.data(forKey: usageKey),
@@ -124,30 +203,36 @@ class MyVC: NSViewController, NSTextFieldDelegate {
124203
customView.searchTerm = textField.stringValue
125204
}
126205

127-
func textField(_ textField: NSTextField, textView: NSTextView, shouldSelectCandidateAt index: Int) -> Bool {
128-
print("Text field select", index)
129-
return true
130-
}
131-
132206
func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
133207
print("Selector", commandSelector)
208+
if commandSelector == #selector(moveRight(_:)) {
209+
self.customView.setSelected(proposed: self.customView.selected + 1)
210+
return true
211+
}
212+
if commandSelector == #selector(moveLeft(_:)) {
213+
self.customView.setSelected(proposed: self.customView.selected - 1)
214+
return true
215+
}
216+
if commandSelector == #selector(moveDown(_:)) {
217+
self.customView.setSelected(proposed: self.customView.selected + 10)
218+
return true
219+
}
220+
if commandSelector == #selector(moveUp(_:)) {
221+
self.customView.setSelected(proposed: self.customView.selected - 10)
222+
return true
223+
}
134224
if commandSelector == #selector(insertTab(_:)) {
135-
print("tab")
136225
self.customView.setSelected(proposed: self.customView.selected + 1)
226+
return true
137227
}
138228
if commandSelector == #selector(insertBacktab(_:)) {
139-
print("back tab")
140229
self.customView.setSelected(proposed: self.customView.selected - 1)
230+
return true
141231
}
142232
if commandSelector == #selector(cancelOperation(_:)) {
143-
print("Escape")
144233
NSApp.hide(nil)
145234
return true
146235
}
147236
return false
148237
}
149-
150-
override func keyDown(with event: NSEvent) {
151-
print(event.keyCode, "Key down here")
152-
}
153238
}

0 commit comments

Comments
 (0)