Repo // Preparing for IMK Candidate implementation.
This commit is contained in:
parent
7ea221f7ec
commit
40d3382564
|
@ -29,7 +29,7 @@ import Cocoa
|
|||
// 註:所有 InputState 型別均不適合使用 Struct,因為 Struct 無法相互繼承派生。
|
||||
|
||||
// 用以讓每個狀態自描述的 enum。
|
||||
enum StateType {
|
||||
public enum StateType {
|
||||
case ofDeactivated
|
||||
case ofAssociatedPhrases
|
||||
case ofEmpty
|
||||
|
@ -43,7 +43,7 @@ enum StateType {
|
|||
}
|
||||
|
||||
// 所有 InputState 均遵守該協定:
|
||||
protocol InputStateProtocol {
|
||||
public protocol InputStateProtocol {
|
||||
var type: StateType { get }
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ protocol InputStateProtocol {
|
|||
/// 詞音組合放入語彙濾除清單。
|
||||
/// - .ChoosingCandidate: 叫出選字窗、允許使用者選字。
|
||||
/// - .SymbolTable: 波浪鍵符號選單專用的狀態,有自身的特殊處理。
|
||||
enum InputState {
|
||||
public enum InputState {
|
||||
/// .Deactivated: 使用者沒在使用輸入法。
|
||||
class Deactivated: InputStateProtocol {
|
||||
public var type: StateType { .ofDeactivated }
|
||||
|
|
|
@ -46,7 +46,7 @@ protocol KeyHandlerDelegate {
|
|||
// MARK: - 核心 (Kernel).
|
||||
|
||||
/// KeyHandler 按鍵調度模組。
|
||||
class KeyHandler {
|
||||
public class KeyHandler {
|
||||
/// 半衰模組的衰減指數
|
||||
let kEpsilon: Double = 0.000001
|
||||
/// 檢測是否出現游標切斷組字圈內字符的情況
|
||||
|
|
|
@ -24,7 +24,7 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import Cocoa
|
||||
|
||||
// MARK: - KeyHandler Delegate
|
||||
|
||||
|
@ -70,6 +70,53 @@ extension ctlInputMethod: KeyHandlerDelegate {
|
|||
// MARK: - Candidate Controller Delegate
|
||||
|
||||
extension ctlInputMethod: ctlCandidateDelegate {
|
||||
func handleDelegateEvent(_ event: NSEvent!) -> Bool {
|
||||
/// 這裡仍舊需要判斷 flags。之前使輸入法狀態卡住無法敲漢字的問題已在 KeyHandler 內修復。
|
||||
/// 這裡不判斷 flags 的話,用方向鍵前後定位光標之後,再次試圖觸發組字區時、反而會在首次按鍵時失敗。
|
||||
/// 同時注意:必須在 event.type == .flagsChanged 結尾插入 return false,
|
||||
/// 否則,每次處理這種判斷時都會觸發 NSInternalInconsistencyException。
|
||||
if event.type == .flagsChanged {
|
||||
return false
|
||||
}
|
||||
|
||||
// 準備修飾鍵,用來判定是否需要利用就地新增語彙時的 Enter 鍵來砍詞。
|
||||
ctlInputMethod.areWeDeleting = event.modifierFlags.contains([.shift, .command])
|
||||
|
||||
var textFrame = NSRect.zero
|
||||
|
||||
let attributes: [AnyHashable: Any]? = client().attributes(
|
||||
forCharacterIndex: 0, lineHeightRectangle: &textFrame
|
||||
)
|
||||
|
||||
let isTypingVertical =
|
||||
(attributes?["IMKTextOrientation"] as? NSNumber)?.intValue == 0 || false
|
||||
|
||||
if client().bundleIdentifier()
|
||||
== "org.atelierInmu.vChewing.vChewingPhraseEditor"
|
||||
{
|
||||
IME.areWeUsingOurOwnPhraseEditor = true
|
||||
} else {
|
||||
IME.areWeUsingOurOwnPhraseEditor = false
|
||||
}
|
||||
|
||||
let input = InputSignal(event: event, isVerticalTyping: isTypingVertical)
|
||||
|
||||
// 無法列印的訊號輸入,一概不作處理。
|
||||
// 這個過程不能放在 KeyHandler 內,否則不會起作用。
|
||||
if !input.charCode.isPrintable {
|
||||
return false
|
||||
}
|
||||
|
||||
/// 將按鍵行為與當前輸入法狀態結合起來、交給按鍵調度模組來處理。
|
||||
/// 再根據返回的 result bool 數值來告知 IMK「這個按鍵事件是被處理了還是被放行了」。
|
||||
let result = keyHandler.handleCandidate(state: state, input: input) { newState in
|
||||
self.handle(state: newState)
|
||||
} errorCallback: {
|
||||
clsSFX.beep()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func candidateCountForController(_ controller: ctlCandidateProtocol) -> Int {
|
||||
_ = controller // 防止格式整理工具毀掉與此對應的參數。
|
||||
if let state = state as? InputState.ChoosingCandidate {
|
||||
|
|
|
@ -43,6 +43,7 @@ public class CandidateKeyLabel: NSObject {
|
|||
}
|
||||
|
||||
public protocol ctlCandidateDelegate: AnyObject {
|
||||
func handleDelegateEvent(_ event: NSEvent!) -> Bool
|
||||
func candidateCountForController(_ controller: ctlCandidateProtocol) -> Int
|
||||
func candidatesForController(_ controller: ctlCandidateProtocol) -> [(String, String)]
|
||||
func ctlCandidate(_ controller: ctlCandidateProtocol, candidateAtIndex index: Int)
|
||||
|
|
Loading…
Reference in New Issue