From a585963c43488f99e5e6bbea31a7bdbfa25d7455 Mon Sep 17 00:00:00 2001 From: erroneousboat Date: Sat, 2 Dec 2017 15:24:56 +0100 Subject: [PATCH] Add overflow functionality Input component Fixes #7 --- components/input.go | 105 ++++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 34 deletions(-) diff --git a/components/input.go b/components/input.go index 5d4a6ce..26ac1e8 100644 --- a/components/input.go +++ b/components/input.go @@ -8,17 +8,21 @@ import ( // Input is the definition of an Input component type Input struct { - Par *termui.Par - Text []rune - CursorPosition int + Par *termui.Par + Text []rune + CursorPositionScreen int + CursorPositionText int + Offset int } // CreateInput is the constructor of the Input struct func CreateInputComponent() *Input { input := &Input{ - Par: termui.NewPar(""), - Text: make([]rune, 0), - CursorPosition: 0, + Par: termui.NewPar(""), + Text: make([]rune, 0), + CursorPositionScreen: 0, + CursorPositionText: 0, + Offset: 0, } input.Par.Height = 3 @@ -31,9 +35,9 @@ func (i *Input) Buffer() termui.Buffer { buf := i.Par.Buffer() // Set visible cursor - char := buf.At(i.Par.InnerX()+i.CursorPosition, i.Par.Block.InnerY()) + char := buf.At(i.Par.InnerX()+i.CursorPositionScreen, i.Par.Block.InnerY()) buf.Set( - i.Par.InnerX()+i.CursorPosition, + i.Par.InnerX()+i.CursorPositionScreen, i.Par.Block.InnerY(), termui.Cell{ Ch: char.Ch, @@ -70,49 +74,81 @@ func (i *Input) SendMessage(svc *service.SlackService, channel string, message s svc.SendMessage(channel, message) } -// Insert will insert a given key at the place of the current CursorPosition +// Insert will insert a given key at the place of the current CursorPositionText func (i *Input) Insert(key rune) { - if len(i.Text) < i.Par.InnerBounds().Dx()-1 { + // Append key to the left side + left := make([]rune, len(i.Text[0:i.CursorPositionText])) + copy(left, i.Text[0:i.CursorPositionText]) + left = append(left, key) - left := make([]rune, len(i.Text[0:i.CursorPosition])) - copy(left, i.Text[0:i.CursorPosition]) - left = append(left, key) + // Combine left and right side + i.Text = append(left, i.Text[i.CursorPositionText:]...) - i.Text = append(left, i.Text[i.CursorPosition:]...) - - i.Par.Text = string(i.Text) - i.MoveCursorRight() - } + // Set visible range of component + i.MoveCursorRight() } -// Backspace will remove a character in front of the CursorPosition +// Backspace will remove a character in front of the CursorPositionText func (i *Input) Backspace() { - if i.CursorPosition > 0 { - i.Text = append(i.Text[0:i.CursorPosition-1], i.Text[i.CursorPosition:]...) - i.Par.Text = string(i.Text) + if i.CursorPositionText > 0 { + i.Text = append(i.Text[0:i.CursorPositionText-1], i.Text[i.CursorPositionText:]...) + i.Par.Text = string(i.Text[i.Offset:]) i.MoveCursorLeft() } } -// Delete will remove a character at the CursorPosition +// Delete will remove a character at the CursorPositionText func (i *Input) Delete() { - if i.CursorPosition < len(i.Text) { - i.Text = append(i.Text[0:i.CursorPosition], i.Text[i.CursorPosition+1:]...) - i.Par.Text = string(i.Text) + if i.CursorPositionText < len(i.Text) { + i.Text = append(i.Text[0:i.CursorPositionText], i.Text[i.CursorPositionText+1:]...) + i.Par.Text = string(i.Text[i.Offset:]) } } -// MoveCursorRight will increase the current CursorPosition with 1 +// MoveCursorRight will increase the current CursorPositionText with 1 func (i *Input) MoveCursorRight() { - if i.CursorPosition < len(i.Text) { - i.CursorPosition++ + if i.CursorPositionText < len(i.Text) { + i.CursorPositionText++ + i.ScrollRight() + } + + i.Par.Text = string(i.Text[i.Offset:]) +} + +// MoveCursorLeft will decrease the current CursorPositionText with 1 +func (i *Input) MoveCursorLeft() { + if i.CursorPositionText > 0 { + i.CursorPositionText-- + i.ScrollLeft() + } + + i.Par.Text = string(i.Text[i.Offset:]) +} + +func (i *Input) ScrollLeft() { + // Is the cursor at the far left of the Input component? + if i.CursorPositionScreen == 0 { + + // Decrease offset to show what is on the left side + if i.Offset > 0 { + i.Offset-- + } + } else { + i.CursorPositionScreen-- } } -// MoveCursorLeft will decrease the current CursorPosition with 1 -func (i *Input) MoveCursorLeft() { - if i.CursorPosition > 0 { - i.CursorPosition-- +func (i *Input) ScrollRight() { + // Is the cursor at the far right of the Input component, cursor + // isn't at the end of the text + if i.CursorPositionScreen == i.Par.InnerBounds().Dx()-1 { + + // Increase offset to show what is on the right side + if i.Offset < len(i.Text) { + i.Offset++ + } + } else { + i.CursorPositionScreen++ } } @@ -128,7 +164,8 @@ func (i *Input) IsEmpty() bool { func (i *Input) Clear() { i.Text = make([]rune, 0) i.Par.Text = "" - i.CursorPosition = 0 + i.CursorPositionScreen = 0 + i.CursorPositionText = 0 } // GetText returns the text currently in the input