Skip to content

Commit

Permalink
Merge pull request #186 from Kvaz1r/findswitch178
Browse files Browse the repository at this point in the history
Add switch buttons to find command
  • Loading branch information
nelsam authored Jan 12, 2020
2 parents 0accda4 + cb26228 commit 0470b7f
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 42 deletions.
125 changes: 112 additions & 13 deletions command/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,21 @@ type SelectionEditor interface {
input.Editor
Controller() *gxui.TextBoxController
SelectSlice([]gxui.TextSelection)
ScrollToRune(int)
}

type Find struct {
driver gxui.Driver
theme *basic.Theme
editor SelectionEditor
display gxui.Label
pattern *findBox

next gxui.Focusable
mixins.LinearLayout

driver gxui.Driver
theme *basic.Theme
editor SelectionEditor
display gxui.Label
pattern *findBox
prevS gxui.Button
nextS gxui.Button
selections []int
selection int
}

func NewFind(driver gxui.Driver, theme *basic.Theme) *Find {
Expand All @@ -40,26 +45,113 @@ func NewFind(driver gxui.Driver, theme *basic.Theme) *Find {
}

func (f *Find) Init(driver gxui.Driver, theme *basic.Theme) {
f.LinearLayout.Init(f, theme)
f.SetDirection(gxui.RightToLeft)
f.driver = driver
f.theme = theme

f.display = f.theme.CreateLabel()
f.display.SetText("Start typing to search")

f.prevS = f.theme.CreateButton()
f.prevS.SetText("<")
f.prevS.OnClick(func(ev gxui.MouseEvent) {
if len(f.selections) != 0 {
f.selection = getNext(f.selection, len(f.selections), -1)
f.editor.ScrollToRune(f.selections[f.selection])
}
})

f.nextS = f.theme.CreateButton()
f.nextS.SetText(">")
f.nextS.OnClick(func(ev gxui.MouseEvent) {
if len(f.selections) != 0 {
f.selection = getNext(f.selection, len(f.selections), 1)
f.editor.ScrollToRune(f.selections[f.selection])
}
})
f.AddChild(f.nextS)
f.AddChild(f.prevS)
}

func (f *Find) KeyPress(event gxui.KeyboardEvent) bool {
if event.Modifier == gxui.ModControl {
if event.Key == gxui.KeyN {
f.nextS.Click(gxui.MouseEvent{})
} else if event.Key == gxui.KeyP {
f.prevS.Click(gxui.MouseEvent{})
}
}
return f.pattern.KeyPress(event)
}

func (f *Find) KeyDown(event gxui.KeyboardEvent) {
f.pattern.KeyDown(event)
}

func (f *Find) KeyUp(event gxui.KeyboardEvent) {
f.pattern.KeyUp(event)
}

func (f *Find) KeyStroke(event gxui.KeyStrokeEvent) bool {
return f.pattern.KeyStroke(event)
}

func (f *Find) KeyRepeat(event gxui.KeyboardEvent) {
f.pattern.KeyRepeat(event)
}

func (f *Find) Paint(c gxui.Canvas) {
f.LinearLayout.Paint(c)

if f.HasFocus() {
r := f.Size().Rect()
s := f.theme.FocusedStyle
c.DrawRoundedRect(r, 3, 3, 3, 3, s.Pen, s.Brush)
}
}

func (f *Find) IsFocusable() bool {
return f.pattern.IsFocusable()
}

func (f *Find) HasFocus() bool {
return f.pattern.HasFocus()
}

func (f *Find) GainedFocus() {
f.pattern.GainedFocus()
}

func (f *Find) LostFocus() {
f.pattern.LostFocus()
}

func (f *Find) OnGainedFocus(callback func()) gxui.EventSubscription {
return f.pattern.OnGainedFocus(callback)
}

func (f *Find) OnLostFocus(callback func()) gxui.EventSubscription {
return f.pattern.OnLostFocus(callback)
}

func (f *Find) Start(control gxui.Control) gxui.Control {
f.editor = findEditor(control)
if f.editor == nil {
return nil
}
f.display = f.theme.CreateLabel()
f.display.SetText("Start typing to search")
f.pattern = newFindBox(f.driver, f.theme)
f.next = f.pattern
f.AddChild(f.pattern)

f.pattern.OnTextChanged(func([]gxui.TextBoxEdit) {
f.editor.Controller().ClearSelections()
needle := f.pattern.Text()
if len(needle) == 0 {
f.display.SetText("Start typing to search")
return
}
f.selections = []int{}

haystack := f.editor.Text()
start := 0
var selections []gxui.TextSelection
Expand All @@ -71,9 +163,11 @@ func (f *Find) Start(control gxui.Control) gxui.Control {
pos += utf8.RuneCountInString(haystack[start : start+next])
selection := gxui.CreateTextSelection(pos, pos+count, false)
selections = append(selections, selection)
f.selections = append(f.selections, pos)
pos += count
start += (next + length)
}
f.selection = len(f.selections) - 1
f.editor.SelectSlice(selections)
f.display.SetText(fmt.Sprintf("%s: %d results found", needle, len(selections)))
})
Expand All @@ -96,9 +190,7 @@ func (f *Find) Defaults() []fmt.Stringer {
}

func (f *Find) Next() gxui.Focusable {
next := f.next
f.next = nil
return next
return f
}

type findBox struct {
Expand Down Expand Up @@ -135,3 +227,10 @@ func findEditor(elem interface{}) SelectionEditor {
}
return nil
}

func getNext(i, l, s int) int {
if s > 0 {
return (i + s) % l
}
return (i + l + s) % l
}
53 changes: 24 additions & 29 deletions command/find_regex.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,40 @@ import (
"github.com/nelsam/gxui/themes/basic"
)

type RegexFind Find

func NewRegexFind(driver gxui.Driver, theme *basic.Theme) *RegexFind {
finder := &RegexFind{}
finder.Init(driver, theme)
return finder
type RegexFind struct {
finder *Find
}

func (f *RegexFind) Init(driver gxui.Driver, theme *basic.Theme) {
f.driver = driver
f.theme = theme
func NewRegexFind(driver gxui.Driver, theme *basic.Theme) *RegexFind {
f := &RegexFind{}
f.finder = NewFind(driver, theme)
return f
}

func (f *RegexFind) Start(control gxui.Control) gxui.Control {
f.editor = findEditor(control)
if f.editor == nil {
f.finder.editor = findEditor(control)
if f.finder.editor == nil {
return nil
}
f.display = f.theme.CreateLabel()
f.display.SetText("Start typing to search")
f.pattern = newFindBox(f.driver, f.theme)
f.next = f.pattern
f.pattern.OnTextChanged(func([]gxui.TextBoxEdit) {
f.editor.Controller().ClearSelections()
needle := f.pattern.Text()
f.finder.pattern = newFindBox(f.finder.driver, f.finder.theme)
f.finder.AddChild(f.finder.pattern)
f.finder.pattern.OnTextChanged(func([]gxui.TextBoxEdit) {
f.finder.editor.Controller().ClearSelections()
needle := f.finder.pattern.Text()
if len(needle) == 0 {
f.display.SetText("Start typing to search")
f.finder.display.SetText("Start typing to search")
return
}
exp, err := regexp.Compile(needle)
if err != nil {
f.display.SetText("Incorrect regexp")
f.finder.display.SetText("Incorrect regexp")
return
}
haystack := f.editor.Text()
f.finder.selections = []int{}
haystack := f.finder.editor.Text()
arr := exp.FindAllStringIndex(haystack, -1)
if arr == nil {
f.display.SetText("Match not found")
f.finder.display.SetText("Match not found")
return
}

Expand All @@ -62,13 +58,14 @@ func (f *RegexFind) Start(control gxui.Control) gxui.Control {
end := start + utf8.RuneCountInString(haystack[indexes[i]:indexes[i+1]])
selection := gxui.CreateTextSelection(start, end, false)
selections = append(selections, selection)

f.finder.selections = append(f.finder.selections, start)
}
}
f.editor.SelectSlice(selections)
f.display.SetText(fmt.Sprintf("%s: %d results found", needle, len(selections)))
f.finder.selection = len(selections) - 1
f.finder.editor.SelectSlice(selections)
f.finder.display.SetText(fmt.Sprintf("%s: %d results found", needle, len(selections)))
})
return f.display
return f.finder.display
}

func (f *RegexFind) Name() string {
Expand All @@ -87,7 +84,5 @@ func (f *RegexFind) Defaults() []fmt.Stringer {
}

func (f *RegexFind) Next() gxui.Focusable {
next := f.next
f.next = nil
return next
return f.finder
}

0 comments on commit 0470b7f

Please sign in to comment.