Skip to content

Commit

Permalink
First implementation of text selection
Browse files Browse the repository at this point in the history
This is so you can immediately clear the URL bar upon toggling. Which
saves you holding down the backspace key if you want to ente a new URL.

Only for input boxes. And SHIFT-ARROW isn't implemented.
  • Loading branch information
tombh committed Jun 3, 2018
1 parent 55c70d9 commit c8d5d09
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 22 deletions.
29 changes: 29 additions & 0 deletions interfacer/src/browsh/input_box.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type inputBox struct {
textCursor int
xScroll int
yScroll int
selectionStart int
selectionEnd int
}

func newInputBox(id string) *inputBox {
Expand Down Expand Up @@ -173,21 +175,48 @@ func (i *inputBox) handleEnterKey() {
}
}

func (i *inputBox) selectionOff() {
i.selectionStart = 0
i.selectionEnd = 0
}

func (i *inputBox) selectAll() {
urlInputBox.selectionStart = 0
urlInputBox.selectionEnd = utf8.RuneCountInString(urlInputBox.text)
}

func (i *inputBox) removeSelectedText() {
if (i.selectionEnd - i.selectionStart <= 0) { return }
start := i.text[:i.selectionStart]
end := i.text[i.selectionEnd:]
i.text = start + end
i.textCursor = i.selectionStart
i.updateXYCursors()
activeInputBox.selectionOff()
}

func handleInputBoxInput(ev *tcell.EventKey) {
switch ev.Key() {
case tcell.KeyLeft:
activeInputBox.selectionOff()
activeInputBox.cursorLeft()
case tcell.KeyRight:
activeInputBox.selectionOff()
activeInputBox.cursorRight()
case tcell.KeyDown:
activeInputBox.selectionOff()
activeInputBox.cursorDown()
case tcell.KeyUp:
activeInputBox.selectionOff()
activeInputBox.cursorUp()
case tcell.KeyBackspace, tcell.KeyBackspace2:
activeInputBox.removeSelectedText()
activeInputBox.cursorBackspace()
case tcell.KeyEnter:
activeInputBox.removeSelectedText()
activeInputBox.handleEnterKey()
case tcell.KeyRune:
activeInputBox.removeSelectedText()
activeInputBox.cursorInsertRune(ev.Rune())
}
if urlInputBox.isActive {
Expand Down
50 changes: 40 additions & 10 deletions interfacer/src/browsh/input_cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,53 @@ package browsh
import "unicode/utf8"

func (i *inputBox) renderCursor() {
var xCursor int
if i.isSelection() {
i.renderSelectionCursor()
} else {
i.renderSingleCursor()
}
}

func (i *inputBox) isSelection() bool {
return i.selectionStart > 0 || i.selectionEnd > 0
}

func (i *inputBox) renderSingleCursor() {
x, y := i.getCoordsOfCursor()
reverseCellColour(x, y)
}

func (i *inputBox) renderSelectionCursor() {
var x, y int
textLength := utf8.RuneCountInString(i.text)
for index := 0; index < textLength; index++ {
x, y = i.getCoordsOfIndex(index)
if x >= i.selectionStart && x < i.selectionEnd {
reverseCellColour(x, y)
}
}
}

func (i *inputBox) getCoordsOfCursor() (int, int) {
var index int
if i.isMultiLine() {
index = i.xCursor
} else {
index = i.textCursor
}
return i.getCoordsOfIndex(index)
}

func (i *inputBox) getCoordsOfIndex(index int) (int, int) {
xFrameOffset := CurrentTab.frame.xScroll
yFrameOffset := CurrentTab.frame.yScroll - uiHeight
if urlInputBox.isActive {
xFrameOffset = 0
yFrameOffset = 0
}
if i.isMultiLine() {
xCursor = i.xCursor
} else {
xCursor = i.textCursor
}
x := (i.X + xCursor) - i.xScroll - xFrameOffset
x := (i.X + index) - i.xScroll - xFrameOffset
y := (i.Y + i.yCursor) - i.yScroll - yFrameOffset
mainRune, combiningRunes, style, _ := screen.GetContent(x, y)
style = style.Reverse(true)
screen.SetContent(x, y, mainRune, combiningRunes, style)
return x, y
}

func (i *inputBox) cursorLeft() {
Expand Down
7 changes: 7 additions & 0 deletions interfacer/src/browsh/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,14 @@ func urlBarFocus(on bool) {
if !on {
activeInputBox = nil
urlInputBox.isActive = false
urlInputBox.selectionOff()
} else {
activeInputBox = &urlInputBox
urlInputBox.isActive = true
urlInputBox.xScroll = 0
urlInputBox.text = CurrentTab.URI
urlInputBox.putCursorAtEnd()
urlInputBox.selectAll()
}
}

Expand All @@ -105,3 +107,8 @@ func overlayPageStatusMessage() {
writeString(0, height - 1, CurrentTab.StatusMessage, tcell.StyleDefault)
}

func reverseCellColour(x, y int) {
mainRune, combiningRunes, style, _ := screen.GetContent(x, y)
style = style.Reverse(true)
screen.SetContent(x, y, mainRune, combiningRunes, style)
}
11 changes: 0 additions & 11 deletions interfacer/test/tty/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ func sleepUntilPageLoad(maxTime time.Duration) {
// GotoURL sends the browsh browser to the specified URL
func GotoURL(url string) {
SpecialKey(tcell.KeyCtrlL)
BackspaceRemoveURL()
Keyboard(url)
SpecialKey(tcell.KeyEnter)
WaitForPageLoad()
Expand All @@ -116,16 +115,6 @@ func GotoURL(url string) {
gomega.Expect(url).To(BeInFrameAt(0, 1))
}

// BackspaceRemoveURL holds down the backspace key to delete the existing URL
// TODO: Remove when text input supports selecting all and pressing any key to overwrite
// the selection.
func BackspaceRemoveURL() {
for i := 1; i <= 50; i++ {
simScreen.InjectKey(tcell.KeyBackspace2, 0, tcell.ModNone)
time.Sleep(10 * time.Millisecond)
}
}

func mouseClick(x, y int) {
simScreen.InjectMouse(x, y, 1, tcell.ModNone)
simScreen.InjectMouse(x, y, 0, tcell.ModNone)
Expand Down
1 change: 0 additions & 1 deletion interfacer/test/tty/tty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ var _ = Describe("Showing a basic webpage", func() {
Describe("Interaction", func() {
It("should navigate to a new page by using the URL bar", func() {
SpecialKey(tcell.KeyCtrlL)
BackspaceRemoveURL()
Keyboard(testSiteURL + "/smorgasbord/another.html")
SpecialKey(tcell.KeyEnter)
Expect("Another").To(BeInFrameAt(0, 0))
Expand Down

0 comments on commit c8d5d09

Please sign in to comment.