Skip to content

Commit

Permalink
Added cursor position into state in TextBox
Browse files Browse the repository at this point in the history
  • Loading branch information
viktor-podzigun committed Dec 18, 2019
1 parent ee213da commit 9a1908c
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 11 deletions.
15 changes: 10 additions & 5 deletions ui/src/main/scala/farclone/ui/TextBox.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ case class TextBoxProps(pos: (Int, Int),
object TextBox extends FunctionComponent[TextBoxProps] {

protected def render(compProps: Props): ReactElement = {
val elementRef = useRef[BlessedElement](null)

val props = compProps.wrapped
val elementRef = useRef[BlessedElement](null)
val (cursorX, setCursorX) = useState(props.value.length)
val (left, top) = props.pos

<.input(
Expand All @@ -32,7 +32,12 @@ object TextBox extends FunctionComponent[TextBoxProps] {
^.rbOnClick := { data =>
val el = elementRef.current
val screen = el.screen
screen.program.omove(data.x, data.y)
val aleft = el.aleft
val newPos = math.min(math.max(data.x - aleft, 0), props.value.length)
if (newPos != cursorX) {
screen.program.omove(aleft + newPos, data.y)
setCursorX(newPos)
}
if (screen.focused != el) {
el.focus()
}
Expand All @@ -41,7 +46,7 @@ object TextBox extends FunctionComponent[TextBoxProps] {
val el = elementRef.current
val screen = el.screen
if (screen.focused == el) {
screen.program.omove(el.aleft, el.atop)
screen.program.omove(el.aleft + cursorX, el.atop)
}
},
^.rbOnFocus := { () =>
Expand All @@ -52,7 +57,7 @@ object TextBox extends FunctionComponent[TextBoxProps] {
screen.cursorShape("underline", blink = true)
}
val program = screen.program
program.omove(el.aleft, el.atop)
program.omove(el.aleft + cursorX, el.atop)
program.showCursor()
},
^.rbOnBlur := { () =>
Expand Down
13 changes: 7 additions & 6 deletions ui/src/test/scala/farclone/ui/TextBoxSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,18 @@ class TextBoxSpec extends TestSpec
//then
(inputMock.screen _).expects().returning(screenMock.asInstanceOf[BlessedScreen])
(screenMock.program _).expects().returning(programMock.asInstanceOf[BlessedProgram])
(programMock.omove _).expects(1, 2)
(inputMock.aleft _).expects().returning(1)
(programMock.omove _).expects(2, 3)
(screenMock.focused _).expects().returning(null)
(inputMock.focus _).expects()

//when
root.children(0).props.onClick(js.Dynamic.literal(x = 1, y = 2))
root.children(0).props.onClick(js.Dynamic.literal(x = 2, y = 3))
}

it should "keep cursor position when onResize" in {
//given
val props = getTextBoxProps()
val props = getTextBoxProps(value = "test")
val programMock = mock[BlessedProgramMock]
val screenMock = mock[BlessedScreenMock]
val inputMock = mock[BlessedElementMock]
Expand All @@ -53,15 +54,15 @@ class TextBoxSpec extends TestSpec
(screenMock.focused _).expects().returning(inputMock.asInstanceOf[BlessedElement])
(inputMock.aleft _).expects().returning(1)
(inputMock.atop _).expects().returning(2)
(programMock.omove _).expects(1, 2)
(programMock.omove _).expects(5, 2)

//when
root.children(0).props.onResize()
}

it should "show cursor when onFocus" in {
//given
val props = getTextBoxProps()
val props = getTextBoxProps(value = "test")
val programMock = mock[BlessedProgramMock]
val screenMock = mock[BlessedScreenMock]
val cursorMock = mock[BlessedCursorMock]
Expand All @@ -80,7 +81,7 @@ class TextBoxSpec extends TestSpec
(screenMock.program _).expects().returning(programMock.asInstanceOf[BlessedProgram])
(inputMock.aleft _).expects().returning(1)
(inputMock.atop _).expects().returning(2)
(programMock.omove _).expects(1, 2)
(programMock.omove _).expects(5, 2)
(programMock.showCursor _).expects()

//when
Expand Down

0 comments on commit 9a1908c

Please sign in to comment.