Skip to content

Commit

Permalink
Initial Working version
Browse files Browse the repository at this point in the history
  • Loading branch information
Parajulibkrm committed Jan 4, 2024
0 parents commit 6068497
Show file tree
Hide file tree
Showing 26 changed files with 2,590 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
build:
runs-on: macos-latest
strategy:
matrix:
arch: [x86_64, arm64]

steps:
# Checks-out repository under $GITHUB_WORKSPACE
- uses: actions/checkout@v2

- name: Xcodebuild Action
# You may pin to the exact commit or the version.
# uses: sersoft-gmbh/xcodebuild-action@349a5f8426171a9680acbca22585d2af4c09a5d6
uses: sersoft-gmbh/[email protected]
with:
project: GoogleInputTools.xcodeproj
scheme: GoogleInputTools
configuration: Debug
arch: ${{ matrix.arch }}
action: build
use-xcpretty: false
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.DS_Store
*.xcuserstate
*.xcuserdatad
xcuserdata
build
6 changes: 6 additions & 0 deletions .swift-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"indentation" : {
"spaces" : 4
},
"tabWidth" : 4
}
383 changes: 383 additions & 0 deletions GoogleInputTools.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
58 changes: 58 additions & 0 deletions GoogleInputTools/Assets.xcassets/AppIcon.appiconset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"images" : [
{
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions GoogleInputTools/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
684 changes: 684 additions & 0 deletions GoogleInputTools/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions GoogleInputTools/CandidatesView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Foundation
import SwiftUI

class CandidatesView: NSView {

override func draw(_ dirtyRect: NSRect) {
NSLog("CandidatesView::draw")

let bounds: NSRect = self.bounds
UISettings.TextBackground.set()
NSBezierPath.fill(bounds)

let numberedCandidates = InputContext.shared.numberedCandidates
let text = numberedCandidates.joined(separator: " ")
let textToPaint: NSMutableAttributedString = NSMutableAttributedString.init(string: text)

let globalAttributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.font: UISettings.Font,
NSAttributedString.Key.foregroundColor: UISettings.TextColor,
]

var start = 0
let currentIndex = InputContext.shared.currentIndex
if currentIndex > 0 {
start = numberedCandidates.prefix(currentIndex).joined(separator: " ").count + 1
}

let selection = InputContext.shared.currentNumberedCandidate

let selectionAttributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.backgroundColor: UISettings.SelectionBackground
]

textToPaint.addAttributes(globalAttributes, range: NSMakeRange(0, text.count))
textToPaint.addAttributes(
selectionAttributes, range: NSMakeRange(start, selection.count))

// calculate text bounds with padding inside the view
let textBounds = NSMakeRect(
bounds.origin.x + UISettings.WindowPaddingX,
bounds.origin.y + UISettings.WindowPaddingY,
bounds.width - UISettings.WindowPaddingX * 2,
bounds.height - UISettings.WindowPaddingY * 2)

NSLog(
"textBounds: (%.0f, %.0f, %.0f, %.0f)", textBounds.origin.x, textBounds.origin.y,
textBounds.width, textBounds.height)

textToPaint.draw(in: textBounds)
}
}
85 changes: 85 additions & 0 deletions GoogleInputTools/CandidatesWindow.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import Foundation
import InputMethodKit
import SwiftUI

class CandidatesWindow: NSWindow {

static let shared = CandidatesWindow()

var _view: CandidatesView

override init(
contentRect: NSRect, styleMask style: NSWindow.StyleMask,
backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool
) {
self._view = CandidatesView()

super.init(
contentRect: contentRect, styleMask: NSWindow.StyleMask.borderless,
backing: backingStoreType, defer: flag)

self.isOpaque = false
self.level = NSWindow.Level.floating
self.backgroundColor = NSColor.clear

self._view = CandidatesView.init(frame: self.frame)
self.contentView = _view
self.orderFront(nil)
}

func update(sender: IMKTextInput) {
let caretPosition = self.getCaretPosition(sender: sender)

let numberedCandidates = InputContext.shared.numberedCandidates
let text = numberedCandidates.joined(separator: " ")
let textToPaint: NSMutableAttributedString = NSMutableAttributedString.init(string: text)

let attributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.font: UISettings.Font
]

textToPaint.addAttributes(attributes, range: NSMakeRange(0, text.count))

// do not paint by default
var rect: NSRect = NSZeroRect

// calculate candidate window position and size
if text.count > 0 {
rect = NSMakeRect(
caretPosition.x,
caretPosition.y - textToPaint.size().height - UISettings.WindowPaddingY * 2,
textToPaint.size().width + UISettings.WindowPaddingX * 2,
textToPaint.size().height + UISettings.WindowPaddingY * 2)
}

NSLog(
"CandidatesWindow::update rect: (%.0f, %.0f, %.0f, %.0f)",
rect.origin.x, rect.origin.y, rect.width, rect.height)

self.setFrame(rect, display: true)

// adjust candidate view
self._view.setNeedsDisplay(rect)
}

func getCaretPosition(sender: IMKTextInput) -> NSPoint {
var pos: NSPoint
let lineHeightRect: UnsafeMutablePointer<NSRect> = UnsafeMutablePointer<NSRect>.allocate(
capacity: 1)

sender.attributes(forCharacterIndex: 0, lineHeightRectangle: lineHeightRect)

let rect = lineHeightRect.pointee
pos = NSMakePoint(rect.origin.x, rect.origin.y)

return pos
}

func show() {
self.setIsVisible(true)
}

func hide() {
self.setIsVisible(false)
}
}
66 changes: 66 additions & 0 deletions GoogleInputTools/CloudInputEngine.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Foundation

enum InputTool: String {
case Nepali = "transliteration_en_ne"
}

class CloudInputEngine {

static let shared = CloudInputEngine()

let _inputTool = InputTool.Nepali
let _candidateNum = 11

func requestCandidates(
_ text: String,
complete: @escaping (_ candidates: [String], _ matchedLength: [Int]?) -> Void
) {
let url = URL(
string:
"https://inputtools.google.com/request?text=\(text)&ime=\(_inputTool.rawValue)&num=\(_candidateNum)&cp=0&cs=1&ie=utf-8&oe=utf-8&app=demopage"
)!

NSLog("%@", url.absoluteString)

var request = URLRequest(url: url)
request.httpMethod = "GET"

let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else { return }
let json = try? JSONSerialization.jsonObject(with: data, options: [])

let response = json as! [Any]
let status = response[0] as! String

if status == "SUCCESS" {
let candidateObject = (response[1] as! [Any])[0] as! [Any]

// let inputText = candidateObject[0] as! String
let candidateArray = candidateObject[1] as! [String]
let candidateMeta = candidateObject[3] as! [String: Any]

// let annotation = candidateMeta["annotation"] as! Array<String>
let matchedLength = candidateMeta["matched_length"] as? [Int]
complete(candidateArray, matchedLength)
}
}

task.resume()
}

func requestCandidatesSync(_ text: String) -> ([String], [Int]?) {
let semaphore = DispatchSemaphore(value: 0)

var candidates: [String] = []
var matchedLength: [Int]? = []
requestCandidates(text) { result, length in
candidates = result
matchedLength = length
semaphore.signal()
}

semaphore.wait()

return (candidates, matchedLength)
}
}
14 changes: 14 additions & 0 deletions GoogleInputTools/GoogleInputTools.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
</dict>
</plist>
Loading

0 comments on commit 6068497

Please sign in to comment.