First implementation of text selection
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.
This commit is contained in:
parent
55c70d9e5e
commit
c8d5d09de7
|
@ -35,6 +35,8 @@ type inputBox struct {
|
|||
textCursor int
|
||||
xScroll int
|
||||
yScroll int
|
||||
selectionStart int
|
||||
selectionEnd int
|
||||
}
|
||||
|
||||
func newInputBox(id string) *inputBox {
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in a new issue