Skip to content

Commit cdeff91

Browse files
committed
Merge pull request #28 from cemolcay/feature/cemolcay-keymenu
Feature/cemolcay keymenu
2 parents 1989de2 + 4612bfe commit cdeff91

File tree

58 files changed

+4423
-249
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+4423
-249
lines changed

Keyboard/DefaultKeyboard/CustomKeyboard.swift

Lines changed: 131 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,15 @@ import UIKit
1010

1111
// MARK: - CustomKeyboardDelegate
1212
@objc public protocol CustomKeyboardDelegate {
13-
optional func customKeyboardKeyButtonPressed(customKeyboard: CustomKeyboard, key: String)
13+
optional func customKeyboard(customKeyboard: CustomKeyboard, keyboardButtonPressed keyboardButton: KeyboardButton)
14+
optional func customKeyboard(customKeyboard: CustomKeyboard, keyButtonPressed key: String)
1415
optional func customKeyboardSpaceButtonPressed(customKeyboard: CustomKeyboard)
1516
optional func customKeyboardBackspaceButtonPressed(customKeyboard: CustomKeyboard)
1617
optional func customKeyboardGlobeButtonPressed(customKeyboard: CustomKeyboard)
1718
optional func customKeyboardReturnButtonPressed(customKeyboard: CustomKeyboard)
18-
optional func customKeyboardButtonPressed(customKeyboard: CustomKeyboard, keyboardButton: KeyboardButton)
1919
}
2020

2121
// MARK: - CustomKeyboard
22-
public var CustomKeyboardKeyButtonPopupTag: Int = 101
23-
2422
public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
2523
public var keyButtonPopupContainer: UIView?
2624

@@ -34,6 +32,24 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
3432
private var backspaceDeleteTimer: NSTimer?
3533
private var backspaceAutoDeleteModeTimer: NSTimer?
3634

35+
public var keyMenuLocked: Bool = false
36+
public var keyMenuOpenTimer: NSTimer?
37+
public var keyMenuOpenTimeInterval: NSTimeInterval = 1
38+
public var keyMenuShowingKeyboardButton: KeyboardButton? {
39+
didSet {
40+
oldValue?.showKeyPop(show: false)
41+
oldValue?.showKeyMenu(show: false)
42+
keyMenuShowingKeyboardButton?.showKeyPop(show: false)
43+
keyMenuShowingKeyboardButton?.showKeyMenu(show: true)
44+
45+
dispatch_after(
46+
dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))),
47+
dispatch_get_main_queue()) { [weak self] in
48+
self?.currentLayout.typingEnabled = self!.keyMenuShowingKeyboardButton == nil && self!.keyMenuLocked == false
49+
}
50+
}
51+
}
52+
3753
public var uppercaseToggledLayout: KeyboardLayout! {
3854
didSet {
3955
layoutDidChange(
@@ -74,7 +90,6 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
7490
}
7591
}
7692

77-
private var lastLetterLayout: KeyboardLayout?
7893
private(set) var currentLayout: KeyboardLayout! {
7994
didSet {
8095
oldValue?.delegate = nil
@@ -183,46 +198,64 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
183198
repeats: false)
184199
}
185200

186-
public func invalidateShiftToggleTimer() {
201+
internal func invalidateShiftToggleTimer() {
187202
shiftToggleTimer?.invalidate()
188203
shiftToggleTimer = nil
189204
shiftCanBeToggled = false
190205
}
191206

192-
// MARK: Key popup in custom container
193-
public func addKeyPopup(forKey key: KeyboardButton) {
194-
switch key.type {
195-
case .Key(_):
196-
if let container = keyButtonPopupContainer {
197-
if container.viewWithTag(CustomKeyboardKeyButtonPopupTag) == nil {
198-
let popup = key.createPopup()
199-
popup.tag = CustomKeyboardKeyButtonPopupTag
200-
popup.frame.origin = key.convertPoint(popup.frame.origin, toView: container)
201-
container.addSubview(popup)
202-
}
203-
}
204-
default:
205-
return
206-
}
207+
// MARK: KeyMenu Toggle
208+
private func startKeyMenuOpenTimer(forKeyboardButton keyboardButton: KeyboardButton) {
209+
keyMenuOpenTimer = NSTimer.scheduledTimerWithTimeInterval(
210+
keyMenuOpenTimeInterval,
211+
target: self,
212+
selector: #selector(CustomKeyboard.openKeyMenu(_:)),
213+
userInfo: keyboardButton,
214+
repeats: false)
207215
}
208216

209-
public func removeKeyPopup() {
210-
if let container = keyButtonPopupContainer {
211-
if let popup = container.viewWithTag(CustomKeyboardKeyButtonPopupTag) {
212-
popup.removeFromSuperview()
213-
}
217+
private func invalidateKeyMenuOpenTimer() {
218+
keyMenuOpenTimer?.invalidate()
219+
keyMenuOpenTimer = nil
220+
}
221+
222+
public func openKeyMenu(timer: NSTimer) {
223+
if let userInfo = timer.userInfo, keyboardButton = userInfo as? KeyboardButton {
224+
keyMenuShowingKeyboardButton = keyboardButton
214225
}
215226
}
216227

217228
// MARK: KeyboardLayoutDelegate
218-
public func keyboardLayoutDidPressButton(keyboardLayout: KeyboardLayout, keyboardButton: KeyboardButton) {
219-
delegate?.customKeyboardButtonPressed?(self, keyboardButton: keyboardButton)
229+
public func keyboardLayout(keyboardLayout: KeyboardLayout, didKeyPressStart keyboardButton: KeyboardButton) {
220230
invalidateBackspaceAutoDeleteModeTimer()
221231
invalidateBackspaceDeleteTimer()
232+
invalidateKeyMenuOpenTimer()
233+
234+
if keyboardLayout == currentLayout {
235+
// Backspace
236+
if keyboardButton.identifier == CustomKeyboardIdentifier.Backspace.rawValue {
237+
startBackspaceAutoDeleteModeTimer()
238+
}
239+
240+
// KeyPop and KeyMenu
241+
if keyboardButton.style.keyPopType != nil {
242+
keyboardButton.showKeyPop(show: true)
243+
if keyboardButton.keyMenu != nil {
244+
startKeyMenuOpenTimer(forKeyboardButton: keyboardButton)
245+
}
246+
} else if keyboardButton.keyMenu != nil {
247+
keyMenuShowingKeyboardButton = keyboardButton
248+
keyMenuLocked = false
249+
}
250+
}
251+
}
252+
253+
public func keyboardLayout(keyboardLayout: KeyboardLayout, didKeyPressEnd keyboardButton: KeyboardButton) {
222254
if keyboardLayout == currentLayout {
255+
delegate?.customKeyboard?(self, keyboardButtonPressed: keyboardButton)
223256
switch keyboardButton.type {
224257
case .Key(let key):
225-
delegate?.customKeyboardKeyButtonPressed?(self, key: key)
258+
delegate?.customKeyboard?(self, keyButtonPressed: key)
226259
if uppercaseOnce {
227260
uppercaseOnce = false
228261
currentLayout = lowercaseLayout
@@ -231,23 +264,23 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
231264
if let id = keyboardButton.identifier,
232265
let identifier = CustomKeyboardIdentifier(rawValue: id) {
233266
switch identifier {
267+
case .Numbers:
268+
currentLayout = numbersLayout
269+
case .Symbols:
270+
currentLayout = symbolsLayout
271+
case .Letters:
272+
currentLayout = uppercaseLayout
273+
uppercaseOnce = true
274+
case .Globe:
275+
delegate?.customKeyboardGlobeButtonPressed?(self)
276+
case .Return:
277+
delegate?.customKeyboardReturnButtonPressed?(self)
234278
case .Space:
235279
delegate?.customKeyboardSpaceButtonPressed?(self)
236280
uppercaseOnce = false
237281
case .Backspace:
238282
delegate?.customKeyboardBackspaceButtonPressed?(self)
239283
uppercaseOnce = false
240-
case .Globe:
241-
delegate?.customKeyboardGlobeButtonPressed?(self)
242-
case .Return:
243-
delegate?.customKeyboardReturnButtonPressed?(self)
244-
case .Letters:
245-
currentLayout = uppercaseLayout
246-
uppercaseOnce = true
247-
case .Numbers:
248-
currentLayout = numbersLayout
249-
case .Symbols:
250-
currentLayout = symbolsLayout
251284
case .Shift:
252285
if shiftCanBeToggled {
253286
currentLayout = uppercaseToggledLayout
@@ -258,9 +291,6 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
258291
uppercaseOnce = true
259292
startShiftToggleTimer()
260293
}
261-
case .ShiftToggled:
262-
currentLayout = lowercaseLayout
263-
uppercaseOnce = false
264294
case .ShiftToggledOnce:
265295
if shiftCanBeToggled {
266296
currentLayout = uppercaseToggledLayout
@@ -271,30 +301,75 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
271301
currentLayout = lowercaseLayout
272302
startShiftToggleTimer()
273303
}
304+
case .ShiftToggled:
305+
currentLayout = lowercaseLayout
306+
uppercaseOnce = false
274307
}
275308
}
276-
break
277309
}
278310
}
279311
}
280312

281-
public func keyboardLayoutDidStartPressingButton(keyboardLayout: KeyboardLayout, keyboardButton: KeyboardButton) {
313+
public func keyboardLayout(keyboardLayout: KeyboardLayout, didTouchesBegin touches: Set<UITouch>) {
314+
if let menu = keyMenuShowingKeyboardButton?.keyMenu, touch = touches.first {
315+
menu.updateSelection(touchLocation: touch.locationInView(self), inView: self)
316+
}
317+
}
318+
319+
public func keyboardLayout(keyboardLayout: KeyboardLayout, didTouchesMove touches: Set<UITouch>) {
320+
if let menu = keyMenuShowingKeyboardButton?.keyMenu, touch = touches.first {
321+
menu.updateSelection(touchLocation: touch.locationInView(self), inView: self)
322+
}
323+
}
324+
325+
public func keyboardLayout(keyboardLayout: KeyboardLayout, didTouchesEnd touches: Set<UITouch>?) {
282326
invalidateBackspaceAutoDeleteModeTimer()
283327
invalidateBackspaceDeleteTimer()
284-
addKeyPopup(forKey: keyboardButton)
285-
if keyboardLayout == currentLayout {
286-
if keyboardButton.identifier == CustomKeyboardIdentifier.Backspace.rawValue {
287-
startBackspaceAutoDeleteModeTimer()
328+
invalidateKeyMenuOpenTimer()
329+
330+
if let menu = keyMenuShowingKeyboardButton?.keyMenu, touch = touches?.first {
331+
menu.updateSelection(touchLocation: touch.locationInView(self), inView: self)
332+
// select item
333+
if menu.selectedIndex >= 0 {
334+
if let item = menu.items[safe: menu.selectedIndex] {
335+
item.action?(keyMenuItem: item)
336+
}
337+
keyMenuShowingKeyboardButton = nil
338+
keyMenuLocked = false
339+
} else {
340+
if keyMenuLocked {
341+
keyMenuShowingKeyboardButton = nil
342+
keyMenuLocked = false
343+
return
344+
}
345+
keyMenuLocked = true
288346
}
289347
}
290348
}
291349

292-
public func keyboardLayoutDidDraggedInButton(keyboardLayout: KeyboardLayout, keyboardButton: KeyboardButton) {
293-
removeKeyPopup()
294-
addKeyPopup(forKey: keyboardButton)
295-
}
296-
297-
public func keyboardLayoutDidEndTouches(keyboardLayout: KeyboardLayout) {
298-
removeKeyPopup()
350+
public func keyboardLayout(keyboardLayout: KeyboardLayout, didTouchesCancel touches: Set<UITouch>?) {
351+
invalidateBackspaceAutoDeleteModeTimer()
352+
invalidateBackspaceDeleteTimer()
353+
invalidateKeyMenuOpenTimer()
354+
355+
if let menu = keyMenuShowingKeyboardButton?.keyMenu, touch = touches?.first {
356+
menu.updateSelection(touchLocation: touch.locationInView(self), inView: self)
357+
// select item
358+
if menu.selectedIndex >= 0 {
359+
if let item = menu.items[safe: menu.selectedIndex] {
360+
item.action?(keyMenuItem: item)
361+
}
362+
keyMenuShowingKeyboardButton = nil
363+
keyMenuLocked = false
364+
} else {
365+
if keyMenuLocked {
366+
keyMenuShowingKeyboardButton = nil
367+
keyMenuLocked = false
368+
currentLayout.typingEnabled = true
369+
return
370+
}
371+
keyMenuLocked = true
372+
}
373+
}
299374
}
300375
}

0 commit comments

Comments
 (0)