Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
skiko
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liuqiang
skiko
Commits
47c33a3e
Unverified
Commit
47c33a3e
authored
Sep 07, 2022
by
dima.avdeev
Committed by
GitHub
Sep 07, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Text input multistage for China and Japan languages (#583)
parent
52640c31
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
519 additions
and
83 deletions
+519
-83
Clocks.kt
...rc/commonMain/kotlin/org/jetbrains/skiko/sample/Clocks.kt
+1
-1
SkikoInput.android.kt
...roidMain/kotlin/org/jetbrains/skiko/SkikoInput.android.kt
+5
-0
SkikoInput.awt.kt
.../src/awtMain/kotlin/org/jetbrains/skiko/SkikoInput.awt.kt
+5
-0
SkikoInput.common.kt
...ommonMain/kotlin/org/jetbrains/skiko/SkikoInput.common.kt
+5
-0
SkikoView.kt
skiko/src/commonMain/kotlin/org/jetbrains/skiko/SkikoView.kt
+5
-0
SkikoInput.ios.kt
.../src/iosMain/kotlin/org/jetbrains/skiko/SkikoInput.ios.kt
+104
-0
SkikoUIView.kt
skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt
+374
-81
SkiaLayer.js.kt
skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt
+1
-1
SkikoInput.js.kt
skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkikoInput.js.kt
+9
-0
SkikoInput.linux.kt
.../linuxMain/kotlin/org/jetbrains/skiko/SkikoInput.linux.kt
+5
-0
SkikoInput.macos.kt
.../macosMain/kotlin/org/jetbrains/skiko/SkikoInput.macos.kt
+5
-0
No files found.
samples/SkiaMultiplatformSample/src/commonMain/kotlin/org/jetbrains/skiko/sample/Clocks.kt
View file @
47c33a3e
skiko/src/androidMain/kotlin/org/jetbrains/skiko/SkikoInput.android.kt
0 → 100644
View file @
47c33a3e
package
org.jetbrains.skiko
actual
interface
SkikoInput
{
actual
object
Empty
:
SkikoInput
}
skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkikoInput.awt.kt
0 → 100644
View file @
47c33a3e
package
org.jetbrains.skiko
actual
interface
SkikoInput
{
actual
object
Empty
:
SkikoInput
}
skiko/src/commonMain/kotlin/org/jetbrains/skiko/SkikoInput.common.kt
0 → 100644
View file @
47c33a3e
package
org.jetbrains.skiko
expect
interface
SkikoInput
{
object
Empty
:
SkikoInput
}
skiko/src/commonMain/kotlin/org/jetbrains/skiko/SkikoView.kt
View file @
47c33a3e
...
@@ -6,7 +6,10 @@ interface SkikoView {
...
@@ -6,7 +6,10 @@ interface SkikoView {
// Input
// Input
fun
onKeyboardEvent
(
event
:
SkikoKeyboardEvent
)
=
Unit
fun
onKeyboardEvent
(
event
:
SkikoKeyboardEvent
)
=
Unit
fun
onPointerEvent
(
event
:
SkikoPointerEvent
)
=
Unit
fun
onPointerEvent
(
event
:
SkikoPointerEvent
)
=
Unit
@Deprecated
(
"This method will be removed. Use override val input: SkikoInput"
)
fun
onInputEvent
(
event
:
SkikoInputEvent
)
=
Unit
fun
onInputEvent
(
event
:
SkikoInputEvent
)
=
Unit
val
input
:
SkikoInput
get
()
=
SkikoInput
.
Empty
fun
onTouchEvent
(
events
:
Array
<
SkikoTouchEvent
>)
=
Unit
fun
onTouchEvent
(
events
:
Array
<
SkikoTouchEvent
>)
=
Unit
fun
onGestureEvent
(
event
:
SkikoGestureEvent
)
=
Unit
fun
onGestureEvent
(
event
:
SkikoGestureEvent
)
=
Unit
...
@@ -31,6 +34,8 @@ open class GenericSkikoView(
...
@@ -31,6 +34,8 @@ open class GenericSkikoView(
app
.
onInputEvent
(
event
)
app
.
onInputEvent
(
event
)
}
}
override
val
input
:
SkikoInput
get
()
=
app
.
input
override
fun
onKeyboardEvent
(
event
:
SkikoKeyboardEvent
)
{
override
fun
onKeyboardEvent
(
event
:
SkikoKeyboardEvent
)
{
app
.
onKeyboardEvent
(
event
)
app
.
onKeyboardEvent
(
event
)
}
}
...
...
skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkikoInput.ios.kt
0 → 100644
View file @
47c33a3e
package
org.jetbrains.skiko
actual
interface
SkikoInput
{
/**
* A Boolean value that indicates whether the text-entry object has any text.
* https://developer.apple.com/documentation/uikit/uikeyinput/1614457-hastext
*/
fun
hasText
():
Boolean
/**
* Inserts a character into the displayed text.
* Add the character text to your class’s backing store at the index corresponding to the cursor and redisplay the text.
* https://developer.apple.com/documentation/uikit/uikeyinput/1614543-inserttext
* @param text A string object representing the character typed on the system keyboard.
*/
fun
insertText
(
text
:
String
)
/**
* Deletes a character from the displayed text.
* Remove the character just before the cursor from your class’s backing store and redisplay the text.
* https://developer.apple.com/documentation/uikit/uikeyinput/1614572-deletebackward
*/
fun
deleteBackward
()
/**
* The text position for the end of a document.
* https://developer.apple.com/documentation/uikit/uitextinput/1614555-endofdocument
*/
fun
endOfDocument
():
Long
/**
* The range of selected text in a document.
* If the text range has a length, it indicates the currently selected text.
* If it has zero length, it indicates the caret (insertion point).
* If the text-range object is nil, it indicates that there is no current selection.
* https://developer.apple.com/documentation/uikit/uitextinput/1614541-selectedtextrange
*/
fun
getSelectedTextRange
():
IntRange
?
fun
setSelectedTextRange
(
range
:
IntRange
?)
fun
selectAll
()
/**
* Returns the text in the specified range.
* https://developer.apple.com/documentation/uikit/uitextinput/1614527-text
* @param range A range of text in a document.
* @return A substring of a document that falls within the specified range.
*/
fun
textInRange
(
range
:
IntRange
):
String
/**
* Replaces the text in a document that is in the specified range.
* https://developer.apple.com/documentation/uikit/uitextinput/1614558-replace
* @param range A range of text in a document.
* @param text A string to replace the text in range.
*/
fun
replaceRange
(
range
:
IntRange
,
text
:
String
)
/**
* Inserts the provided text and marks it to indicate that it is part of an active input session.
* Setting marked text either replaces the existing marked text or,
* if none is present, inserts it in place of the current selection.
* https://developer.apple.com/documentation/uikit/uitextinput/1614465-setmarkedtext
* @param markedText The text to be marked.
* @param selectedRange A range within markedText that indicates the current selection.
* This range is always relative to markedText.
*/
fun
setMarkedText
(
markedText
:
String
?,
selectedRange
:
IntRange
)
/**
* The range of currently marked text in a document.
* If there is no marked text, the value of the property is nil.
* Marked text is provisionally inserted text that requires user confirmation;
* it occurs in multistage text input.
* The current selection, which can be a caret or an extended range, always occurs within the marked text.
* https://developer.apple.com/documentation/uikit/uitextinput/1614489-markedtextrange
*/
fun
markedTextRange
():
IntRange
?
/**
* Unmarks the currently marked text.
* After this method is called, the value of markedTextRange is nil.
* https://developer.apple.com/documentation/uikit/uitextinput/1614512-unmarktext
*/
fun
unmarkText
()
actual
object
Empty
:
SkikoInput
{
override
fun
hasText
():
Boolean
=
false
override
fun
insertText
(
text
:
String
)
=
Unit
override
fun
deleteBackward
()
=
Unit
override
fun
endOfDocument
():
Long
=
0L
override
fun
getSelectedTextRange
():
IntRange
?
=
null
override
fun
setSelectedTextRange
(
range
:
IntRange
?)
=
Unit
override
fun
selectAll
()
=
Unit
override
fun
textInRange
(
range
:
IntRange
):
String
=
""
override
fun
replaceRange
(
range
:
IntRange
,
text
:
String
)
=
Unit
override
fun
setMarkedText
(
markedText
:
String
?,
selectedRange
:
IntRange
)
=
Unit
override
fun
markedTextRange
():
IntRange
?
=
null
override
fun
unmarkText
()
=
Unit
}
}
skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt
View file @
47c33a3e
package
org.jetbrains.skiko
package
org.jetbrains.skiko
import
kotlinx.cinterop.CValue
import
kotlinx.cinterop.*
import
kotlinx.cinterop.ExportObjCClass
import
platform.CoreGraphics.*
import
kotlinx.cinterop.useContents
import
platform.Foundation.*
import
platform.CoreGraphics.CGRect
import
platform.UIKit.*
import
platform.CoreGraphics.CGRectMake
import
platform.darwin.NSInteger
import
platform.Foundation.NSCoder
import
kotlin.math.max
import
platform.UIKit.UIEvent
import
kotlin.math.min
import
platform.UIKit.UITouch
import
platform.UIKit.UIScreen
import
platform.UIKit.UIView
import
platform.UIKit.setFrame
import
platform.UIKit.contentScaleFactor
import
platform.UIKit.UIKeyInputProtocol
import
platform.UIKit.UIPress
import
platform.UIKit.UIPressesEvent
@Suppress
(
"CONFLICTING_OVERLOADS"
)
@ExportObjCClass
@ExportObjCClass
class
SkikoUIView
:
UIView
,
UIKeyInputProtocol
{
class
SkikoUIView
:
UIView
,
UIKeyInputProtocol
,
UITextInputProtocol
,
UITextPasteConfigurationSupportingProtocol
{
@OverrideInit
@OverrideInit
constructor
(
frame
:
CValue
<
CGRect
>)
:
super
(
frame
)
constructor
(
frame
:
CValue
<
CGRect
>)
:
super
(
frame
)
...
@@ -25,11 +18,18 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
...
@@ -25,11 +18,18 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
constructor
(
coder
:
NSCoder
)
:
super
(
coder
)
constructor
(
coder
:
NSCoder
)
:
super
(
coder
)
private
var
skiaLayer
:
SkiaLayer
?
=
null
private
var
skiaLayer
:
SkiaLayer
?
=
null
private
var
_inputDelegate
:
UITextInputDelegateProtocol
?
=
null
private
var
_pasteConfiguration
:
UIPasteConfiguration
?
=
null
private
var
_pasteDelegate
:
UITextPasteDelegateProtocol
?
=
null
constructor
(
skiaLayer
:
SkiaLayer
,
frame
:
CValue
<
CGRect
>
=
CGRect
Make
(
0.0
,
0.0
,
1.0
,
1.0
))
:
super
(
frame
)
{
constructor
(
skiaLayer
:
SkiaLayer
,
frame
:
CValue
<
CGRect
>
=
CGRect
Null
.
readValue
(
))
:
super
(
frame
)
{
this
.
skiaLayer
=
skiaLayer
this
.
skiaLayer
=
skiaLayer
}
}
override
fun
selectAll
(
sender
:
Any
?)
{
skiaLayer
?.
skikoView
?.
input
?.
selectAll
()
}
fun
detach
()
=
skiaLayer
?.
detach
()
fun
detach
()
=
skiaLayer
?.
detach
()
fun
load
():
SkikoUIView
{
fun
load
():
SkikoUIView
{
...
@@ -50,33 +50,31 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
...
@@ -50,33 +50,31 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
fun
hideScreenKeyboard
()
=
resignFirstResponder
()
fun
hideScreenKeyboard
()
=
resignFirstResponder
()
fun
isScreenKeyboardOpen
()
=
isFirstResponder
fun
isScreenKeyboardOpen
()
=
isFirstResponder
private
val
pressedKeycodes
:
MutableSet
<
Long
>
=
mutableSetOf
()
/**
* A Boolean value that indicates whether the text-entry object has any text.
@Deprecated
(
"need be deleted"
)
* https://developer.apple.com/documentation/uikit/uikeyinput/1614457-hastext
private
var
inputText
:
String
=
""
//todo delete, because it's redundant and may leaks memory
*/
override
fun
hasText
():
Boolean
{
override
fun
hasText
():
Boolean
{
return
inputText
.
length
>
0
return
skiaLayer
?.
skikoView
?.
input
?.
hasText
()
?:
false
}
}
override
fun
insertText
(
theText
:
String
)
{
/**
inputText
+=
theText
* Inserts a character into the displayed text.
skiaLayer
?.
skikoView
?.
onInputEvent
(
toSkikoTypeEvent
(
theText
,
null
))
* Add the character text to your class’s backing store at the index corresponding to the cursor and redisplay the text.
* https://developer.apple.com/documentation/uikit/uikeyinput/1614543-inserttext
* @param text A string object representing the character typed on the system keyboard.
*/
override
fun
insertText
(
text
:
String
)
{
skiaLayer
?.
skikoView
?.
input
?.
insertText
(
text
)
}
}
/**
* Deletes a character from the displayed text.
* Remove the character just before the cursor from your class’s backing store and redisplay the text.
* https://developer.apple.com/documentation/uikit/uikeyinput/1614572-deletebackward
*/
override
fun
deleteBackward
()
{
override
fun
deleteBackward
()
{
inputText
=
inputText
.
dropLast
(
1
)
skiaLayer
?.
skikoView
?.
input
?.
deleteBackward
()
if
(!
pressedKeycodes
.
contains
(
SkikoKey
.
KEY_BACKSPACE
.
value
))
{
val
downEvent
=
SkikoKeyboardEvent
(
key
=
SkikoKey
.
KEY_BACKSPACE
,
kind
=
SkikoKeyboardEventKind
.
DOWN
,
platform
=
null
)
val
upEvent
=
downEvent
.
copy
(
kind
=
SkikoKeyboardEventKind
.
UP
)
skiaLayer
?.
skikoView
?.
onKeyboardEvent
(
downEvent
)
skiaLayer
?.
skikoView
?.
onKeyboardEvent
(
upEvent
)
}
}
}
override
fun
canBecomeFirstResponder
()
=
true
override
fun
canBecomeFirstResponder
()
=
true
...
@@ -86,9 +84,6 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
...
@@ -86,9 +84,6 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
for
(
press
in
withEvent
.
allPresses
)
{
for
(
press
in
withEvent
.
allPresses
)
{
val
uiPress
=
press
as
?
UIPress
val
uiPress
=
press
as
?
UIPress
if
(
uiPress
!=
null
)
{
if
(
uiPress
!=
null
)
{
uiPress
.
key
?.
let
{
pressedKeycodes
.
add
(
it
.
keyCode
)
}
skiaLayer
?.
skikoView
?.
onKeyboardEvent
(
skiaLayer
?.
skikoView
?.
onKeyboardEvent
(
toSkikoKeyboardEvent
(
press
,
SkikoKeyboardEventKind
.
DOWN
)
toSkikoKeyboardEvent
(
press
,
SkikoKeyboardEventKind
.
DOWN
)
)
)
...
@@ -103,9 +98,6 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
...
@@ -103,9 +98,6 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
for
(
press
in
withEvent
.
allPresses
)
{
for
(
press
in
withEvent
.
allPresses
)
{
val
uiPress
=
press
as
?
UIPress
val
uiPress
=
press
as
?
UIPress
if
(
uiPress
!=
null
)
{
if
(
uiPress
!=
null
)
{
uiPress
.
key
?.
let
{
pressedKeycodes
.
remove
(
it
.
keyCode
)
}
skiaLayer
?.
skikoView
?.
onKeyboardEvent
(
skiaLayer
?.
skikoView
?.
onKeyboardEvent
(
toSkikoKeyboardEvent
(
press
,
SkikoKeyboardEventKind
.
UP
)
toSkikoKeyboardEvent
(
press
,
SkikoKeyboardEventKind
.
UP
)
)
)
...
@@ -117,57 +109,358 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
...
@@ -117,57 +109,358 @@ class SkikoUIView : UIView, UIKeyInputProtocol {
override
fun
touchesBegan
(
touches
:
Set
<
*
>,
withEvent
:
UIEvent
?)
{
override
fun
touchesBegan
(
touches
:
Set
<
*
>,
withEvent
:
UIEvent
?)
{
super
.
touchesBegan
(
touches
,
withEvent
)
super
.
touchesBegan
(
touches
,
withEvent
)
val
events
:
MutableList
<
SkikoTouchEvent
>
=
mutableListOf
()
sendTouchEventToSkikoView
(
touches
,
SkikoTouchEventKind
.
STARTED
)
for
(
touch
in
touches
)
{
val
event
=
touch
as
UITouch
val
(
x
,
y
)
=
event
.
locationInView
(
null
).
useContents
{
x
to
y
}
val
timestamp
=
(
event
.
timestamp
*
1
_000
).
toLong
()
events
.
add
(
SkikoTouchEvent
(
x
,
y
,
SkikoTouchEventKind
.
STARTED
,
timestamp
,
event
)
)
}
skiaLayer
?.
skikoView
?.
onTouchEvent
(
events
.
toTypedArray
())
}
}
override
fun
touchesEnded
(
touches
:
Set
<
*
>,
withEvent
:
UIEvent
?)
{
override
fun
touchesEnded
(
touches
:
Set
<
*
>,
withEvent
:
UIEvent
?)
{
super
.
touchesEnded
(
touches
,
withEvent
)
super
.
touchesEnded
(
touches
,
withEvent
)
val
events
:
MutableList
<
SkikoTouchEvent
>
=
mutableListOf
()
sendTouchEventToSkikoView
(
touches
,
SkikoTouchEventKind
.
ENDED
)
for
(
touch
in
touches
)
{
val
event
=
touch
as
UITouch
val
(
x
,
y
)
=
event
.
locationInView
(
null
).
useContents
{
x
to
y
}
val
timestamp
=
(
event
.
timestamp
*
1
_000
).
toLong
()
events
.
add
(
SkikoTouchEvent
(
x
,
y
,
SkikoTouchEventKind
.
ENDED
,
timestamp
,
event
)
)
}
skiaLayer
?.
skikoView
?.
onTouchEvent
(
events
.
toTypedArray
())
}
}
override
fun
touchesMoved
(
touches
:
Set
<
*
>,
withEvent
:
UIEvent
?)
{
override
fun
touchesMoved
(
touches
:
Set
<
*
>,
withEvent
:
UIEvent
?)
{
super
.
touchesMoved
(
touches
,
withEvent
)
super
.
touchesMoved
(
touches
,
withEvent
)
val
events
:
MutableList
<
SkikoTouchEvent
>
=
mutableListOf
()
sendTouchEventToSkikoView
(
touches
,
SkikoTouchEventKind
.
MOVED
)
for
(
touch
in
touches
)
{
val
event
=
touch
as
UITouch
val
(
x
,
y
)
=
event
.
locationInView
(
null
).
useContents
{
x
to
y
}
val
timestamp
=
(
event
.
timestamp
*
1
_000
).
toLong
()
events
.
add
(
SkikoTouchEvent
(
x
,
y
,
SkikoTouchEventKind
.
MOVED
,
timestamp
,
event
)
)
}
skiaLayer
?.
skikoView
?.
onTouchEvent
(
events
.
toTypedArray
())
}
}
override
fun
touchesCancelled
(
touches
:
Set
<
*
>,
withEvent
:
UIEvent
?)
{
override
fun
touchesCancelled
(
touches
:
Set
<
*
>,
withEvent
:
UIEvent
?)
{
super
.
touchesCancelled
(
touches
,
withEvent
)
super
.
touchesCancelled
(
touches
,
withEvent
)
val
events
:
MutableList
<
SkikoTouchEvent
>
=
mutableListOf
()
sendTouchEventToSkikoView
(
touches
,
SkikoTouchEventKind
.
CANCELLED
)
for
(
touch
in
touches
)
{
}
val
event
=
touch
as
UITouch
private
fun
sendTouchEventToSkikoView
(
touches
:
Set
<
*
>,
kind
:
SkikoTouchEventKind
)
{
val
events
=
touches
.
map
{
val
event
=
it
as
UITouch
val
(
x
,
y
)
=
event
.
locationInView
(
null
).
useContents
{
x
to
y
}
val
(
x
,
y
)
=
event
.
locationInView
(
null
).
useContents
{
x
to
y
}
val
timestamp
=
(
event
.
timestamp
*
1
_000
).
toLong
()
val
timestamp
=
(
event
.
timestamp
*
1
_000
).
toLong
()
events
.
add
(
SkikoTouchEvent
(
x
,
y
,
kind
,
timestamp
,
event
)
SkikoTouchEvent
(
x
,
y
,
SkikoTouchEventKind
.
CANCELLED
,
timestamp
,
event
)
}.
toTypedArray
()
skiaLayer
?.
skikoView
?.
onTouchEvent
(
events
)
}
override
fun
inputDelegate
():
UITextInputDelegateProtocol
?
{
return
_inputDelegate
}
override
fun
setInputDelegate
(
inputDelegate
:
UITextInputDelegateProtocol
?)
{
_inputDelegate
=
inputDelegate
}
/**
* Returns the text in the specified range.
* https://developer.apple.com/documentation/uikit/uitextinput/1614527-text
* @param range A range of text in a document.
* @return A substring of a document that falls within the specified range.
*/
override
fun
textInRange
(
range
:
UITextRange
):
String
?
{
return
skiaLayer
?.
skikoView
?.
input
?.
textInRange
(
range
.
toIntRange
())
}
/**
* Replaces the text in a document that is in the specified range.
* https://developer.apple.com/documentation/uikit/uitextinput/1614558-replace
* @param range A range of text in a document.
* @param text A string to replace the text in range.
*/
override
fun
replaceRange
(
range
:
UITextRange
,
withText
:
String
)
{
skiaLayer
?.
skikoView
?.
input
?.
replaceRange
(
range
.
toIntRange
(),
withText
)
}
override
fun
setSelectedTextRange
(
selectedTextRange
:
UITextRange
?)
{
skiaLayer
?.
skikoView
?.
input
?.
setSelectedTextRange
(
selectedTextRange
?.
toIntRange
())
}
/**
* The range of selected text in a document.
* If the text range has a length, it indicates the currently selected text.
* If it has zero length, it indicates the caret (insertion point).
* If the text-range object is nil, it indicates that there is no current selection.
* https://developer.apple.com/documentation/uikit/uitextinput/1614541-selectedtextrange
*/
override
fun
selectedTextRange
():
UITextRange
?
{
return
skiaLayer
?.
skikoView
?.
input
?.
getSelectedTextRange
()
?.
toUITextRange
()
}
/**
* The range of currently marked text in a document.
* If there is no marked text, the value of the property is nil.
* Marked text is provisionally inserted text that requires user confirmation;
* it occurs in multistage text input.
* The current selection, which can be a caret or an extended range, always occurs within the marked text.
* https://developer.apple.com/documentation/uikit/uitextinput/1614489-markedtextrange
*/
override
fun
markedTextRange
():
UITextRange
?
{
return
skiaLayer
?.
skikoView
?.
input
?.
markedTextRange
()
?.
toUITextRange
()
}
override
fun
setMarkedTextStyle
(
markedTextStyle
:
Map
<
Any
?
,
*
>?)
{
// do nothing
}
override
fun
markedTextStyle
():
Map
<
Any
?
,
*
>?
{
return
null
}
/**
* Inserts the provided text and marks it to indicate that it is part of an active input session.
* Setting marked text either replaces the existing marked text or,
* if none is present, inserts it in place of the current selection.
* https://developer.apple.com/documentation/uikit/uitextinput/1614465-setmarkedtext
* @param markedText The text to be marked.
* @param selectedRange A range within markedText that indicates the current selection.
* This range is always relative to markedText.
*/
override
fun
setMarkedText
(
markedText
:
String
?,
selectedRange
:
CValue
<
NSRange
>)
{
val
(
locationRelative
,
lengthRelative
)
=
selectedRange
.
useContents
{
location
.
toInt
()
to
length
.
toInt
()
}
val
relativeTextRange
=
locationRelative
until
locationRelative
+
lengthRelative
skiaLayer
?.
skikoView
?.
input
?.
setMarkedText
(
markedText
,
relativeTextRange
)
}
/**
* Unmarks the currently marked text.
* After this method is called, the value of markedTextRange is nil.
* https://developer.apple.com/documentation/uikit/uitextinput/1614512-unmarktext
*/
override
fun
unmarkText
()
{
skiaLayer
?.
skikoView
?.
input
?.
unmarkText
()
}
override
fun
beginningOfDocument
():
UITextPosition
{
return
IntermediateTextPosition
(
0
)
}
/**
* The text position for the end of a document.
* https://developer.apple.com/documentation/uikit/uitextinput/1614555-endofdocument
*/
override
fun
endOfDocument
():
UITextPosition
{
return
IntermediateTextPosition
(
skiaLayer
?.
skikoView
?.
input
?.
endOfDocument
()
?:
0
)
}
/**
* Attention! fromPosition and toPosition may be null
*/
override
fun
textRangeFromPosition
(
fromPosition
:
UITextPosition
,
toPosition
:
UITextPosition
):
UITextRange
?
{
val
from
=
(
fromPosition
as
?
IntermediateTextPosition
)
?.
position
?:
0
val
to
=
(
toPosition
as
?
IntermediateTextPosition
)
?.
position
?:
0
return
IntermediateTextRange
(
IntermediateTextPosition
(
minOf
(
from
,
to
)),
IntermediateTextPosition
(
maxOf
(
from
,
to
))
)
)
}
}
skiaLayer
?.
skikoView
?.
onTouchEvent
(
events
.
toTypedArray
())
override
fun
positionFromPosition
(
position
:
UITextPosition
,
offset
:
NSInteger
):
UITextPosition
?
{
val
p
=
(
position
as
IntermediateTextPosition
).
position
val
endOfDocument
=
skiaLayer
?.
skikoView
?.
input
?.
endOfDocument
()
return
if
(
endOfDocument
!=
null
)
{
IntermediateTextPosition
(
max
(
min
(
p
+
offset
,
endOfDocument
),
0
))
}
else
{
null
}
}
override
fun
positionFromPosition
(
position
:
UITextPosition
,
inDirection
:
UITextLayoutDirection
,
offset
:
NSInteger
):
UITextPosition
?
{
return
when
(
inDirection
)
{
UITextLayoutDirectionLeft
,
UITextLayoutDirectionUp
->
{
positionFromPosition
(
position
,
-
offset
)
}
else
->
positionFromPosition
(
position
,
offset
)
}
}
/**
* Attention! position and toPosition may be null
*/
override
fun
comparePosition
(
position
:
UITextPosition
,
toPosition
:
UITextPosition
):
NSComparisonResult
{
val
from
=
(
position
as
?
IntermediateTextPosition
)
?.
position
?:
0
val
to
=
(
toPosition
as
?
IntermediateTextPosition
)
?.
position
?:
0
val
result
=
if
(
from
<
to
)
{
NSOrderedAscending
}
else
if
(
from
>
to
)
{
NSOrderedDescending
}
else
{
NSOrderedSame
}
return
result
}
override
fun
offsetFromPosition
(
from
:
UITextPosition
,
toPosition
:
UITextPosition
):
NSInteger
{
val
fromPosition
=
from
as
IntermediateTextPosition
val
to
=
toPosition
as
IntermediateTextPosition
return
to
.
position
-
fromPosition
.
position
}
override
fun
tokenizer
():
UITextInputTokenizerProtocol
{
return
UITextInputStringTokenizer
()
}
override
fun
positionWithinRange
(
range
:
UITextRange
,
atCharacterOffset
:
NSInteger
):
UITextPosition
?
=
TODO
(
"positionWithinRange range: $range, atCharacterOffset: $atCharacterOffset"
)
override
fun
positionWithinRange
(
range
:
UITextRange
,
farthestInDirection
:
UITextLayoutDirection
):
UITextPosition
?
=
TODO
(
"positionWithinRange, farthestInDirection: ${farthestInDirection.directionToStr()}"
)
override
fun
characterRangeByExtendingPosition
(
position
:
UITextPosition
,
inDirection
:
UITextLayoutDirection
):
UITextRange
?
{
TODO
(
"characterRangeByExtendingPosition, inDirection: ${inDirection.directionToStr()}"
)
}
override
fun
baseWritingDirectionForPosition
(
position
:
UITextPosition
,
inDirection
:
UITextStorageDirection
):
NSWritingDirection
{
return
NSWritingDirectionLeftToRight
// TODO support RTL text direction
}
override
fun
setBaseWritingDirection
(
writingDirection
:
NSWritingDirection
,
forRange
:
UITextRange
)
{
// TODO support RTL text direction
}
//Working with Geometry and Hit-Testing. All methods return stubs for now.
override
fun
firstRectForRange
(
range
:
UITextRange
):
CValue
<
CGRect
>
=
CGRectNull
.
readValue
()
override
fun
caretRectForPosition
(
position
:
UITextPosition
):
CValue
<
CGRect
>
=
CGRectNull
.
readValue
()
override
fun
selectionRectsForRange
(
range
:
UITextRange
):
List
<
*
>
=
listOf
<
UITextSelectionRect
>()
override
fun
closestPositionToPoint
(
point
:
CValue
<
CGPoint
>):
UITextPosition
?
=
null
override
fun
closestPositionToPoint
(
point
:
CValue
<
CGPoint
>,
withinRange
:
UITextRange
):
UITextPosition
?
=
null
override
fun
characterRangeAtPoint
(
point
:
CValue
<
CGPoint
>):
UITextRange
?
=
null
override
fun
textStylingAtPosition
(
position
:
UITextPosition
,
inDirection
:
UITextStorageDirection
):
Map
<
Any
?
,
*
>?
{
return
NSDictionary
.
dictionary
()
}
override
fun
characterOffsetOfPosition
(
position
:
UITextPosition
,
withinRange
:
UITextRange
):
NSInteger
{
TODO
(
"characterOffsetOfPosition"
)
}
override
fun
shouldChangeTextInRange
(
range
:
UITextRange
,
replacementText
:
String
):
Boolean
{
// Here we should decide to replace text in range or not.
// By default, this method returns true.
return
true
}
override
fun
textInputView
():
UIView
{
return
this
}
override
fun
canPerformAction
(
action
:
COpaquePointer
?,
withSender
:
Any
?):
Boolean
{
//todo context menu with actions
return
true
}
override
fun
pasteConfiguration
():
UIPasteConfiguration
?
{
//https://developer.apple.com/documentation/uikit/uitextpasteconfigurationsupporting
//todo uikit copy/paste
return
_pasteConfiguration
}
override
fun
setPasteConfiguration
(
pasteConfiguration
:
UIPasteConfiguration
?)
{
//todo uikit copy/paste
_pasteConfiguration
=
pasteConfiguration
}
override
fun
pasteDelegate
():
UITextPasteDelegateProtocol
?
{
//todo uikit copy/paste
return
_pasteDelegate
}
override
fun
setPasteDelegate
(
pasteDelegate
:
UITextPasteDelegateProtocol
?)
{
//todo uikit copy/paste
_pasteDelegate
=
pasteDelegate
}
override
fun
keyboardType
():
UIKeyboardType
{
return
UIKeyboardTypeDefault
//todo keyboardType
}
override
fun
isSecureTextEntry
():
Boolean
{
return
false
//todo secure text to prevent copy
}
override
fun
autocapitalizationType
():
UITextAutocapitalizationType
{
return
UITextAutocapitalizationType
.
UITextAutocapitalizationTypeSentences
// return UITextAutocapitalizationType.UITextAutocapitalizationTypeAllCharacters
}
override
fun
autocorrectionType
():
UITextAutocorrectionType
{
return
UITextAutocorrectionType
.
UITextAutocorrectionTypeYes
}
override
fun
dictationRecognitionFailed
()
{
//todo may be useful
}
override
fun
dictationRecordingDidEnd
()
{
//todo may be useful
}
/**
* Call when something changes in text data
*/
fun
textWillChange
()
{
_inputDelegate
?.
textWillChange
(
this
)
}
/**
* Call when something changes in text data
*/
fun
textDidChange
()
{
_inputDelegate
?.
textDidChange
(
this
)
}
/**
* Call when something changes in text data
*/
fun
selectionWillChange
()
{
_inputDelegate
?.
selectionWillChange
(
this
)
}
/**
* Call when something changes in text data
*/
fun
selectionDidChange
()
{
_inputDelegate
?.
selectionDidChange
(
this
)
}
}
}
}
private
class
IntermediateTextPosition
(
val
position
:
Long
=
0
)
:
UITextPosition
()
private
fun
IntermediateTextRange
(
start
:
Int
,
end
:
Int
)
=
IntermediateTextRange
(
_start
=
IntermediateTextPosition
(
start
.
toLong
()),
_end
=
IntermediateTextPosition
(
end
.
toLong
())
)
private
class
IntermediateTextRange
(
private
val
_start
:
IntermediateTextPosition
,
private
val
_end
:
IntermediateTextPosition
)
:
UITextRange
()
{
override
fun
isEmpty
()
=
(
_end
.
position
-
_start
.
position
)
<=
0
override
fun
start
():
UITextPosition
=
_start
override
fun
end
():
UITextPosition
=
_end
}
private
fun
UITextRange
.
toIntRange
():
IntRange
{
val
start
=
(
start
()
as
IntermediateTextPosition
).
position
.
toInt
()
val
end
=
(
end
()
as
IntermediateTextPosition
).
position
.
toInt
()
return
start
until
end
}
private
fun
IntRange
.
toUITextRange
():
UITextRange
=
IntermediateTextRange
(
start
=
start
,
end
=
endInclusive
+
1
)
private
fun
NSWritingDirection
.
directionToStr
()
=
when
(
this
)
{
UITextLayoutDirectionLeft
->
"Left"
UITextLayoutDirectionRight
->
"Right"
UITextLayoutDirectionUp
->
"Up"
UITextLayoutDirectionDown
->
"Down"
else
->
"unknown direction"
}
skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt
View file @
47c33a3e
...
@@ -135,7 +135,7 @@ actual open class SkiaLayer {
...
@@ -135,7 +135,7 @@ actual open class SkiaLayer {
skikoView
?.
onKeyboardEvent
(
toSkikoEvent
(
event
,
SkikoKeyboardEventKind
.
DOWN
))
skikoView
?.
onKeyboardEvent
(
toSkikoEvent
(
event
,
SkikoKeyboardEventKind
.
DOWN
))
toSkikoTypeEvent
(
event
.
key
,
event
)
?.
let
{
inputEvent
->
toSkikoTypeEvent
(
event
.
key
,
event
)
?.
let
{
inputEvent
->
skikoView
?.
onInputEvent
(
inputEvent
)
skikoView
?.
input
?.
onInputEvent
(
inputEvent
)
}
}
})
})
htmlCanvas
.
addEventListener
(
"keyup"
,
{
event
->
htmlCanvas
.
addEventListener
(
"keyup"
,
{
event
->
...
...
skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkikoInput.js.kt
0 → 100644
View file @
47c33a3e
package
org.jetbrains.skiko
actual
interface
SkikoInput
{
fun
onInputEvent
(
event
:
SkikoInputEvent
)
actual
object
Empty
:
SkikoInput
{
override
fun
onInputEvent
(
event
:
SkikoInputEvent
)
=
Unit
}
}
skiko/src/linuxMain/kotlin/org/jetbrains/skiko/SkikoInput.linux.kt
0 → 100644
View file @
47c33a3e
package
org.jetbrains.skiko
actual
interface
SkikoInput
{
actual
object
Empty
:
SkikoInput
}
skiko/src/macosMain/kotlin/org/jetbrains/skiko/SkikoInput.macos.kt
0 → 100644
View file @
47c33a3e
package
org.jetbrains.skiko
actual
interface
SkikoInput
{
actual
object
Empty
:
SkikoInput
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment