From b3dc389cb44efe145b43ae1a73a7a5cc70d2098a Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 29 Mar 2020 20:53:28 +0200 Subject: [PATCH] Added mouse support to presentation demo. TextView "highlighted" callback also receives remaining highlights. --- demos/presentation/cover.go | 4 +- demos/presentation/main.go | 25 ++++++------ textview.go | 77 +++++++++++++++++++++---------------- 3 files changed, 60 insertions(+), 46 deletions(-) diff --git a/demos/presentation/cover.go b/demos/presentation/cover.go index 2c06e5c..6027561 100644 --- a/demos/presentation/cover.go +++ b/demos/presentation/cover.go @@ -20,6 +20,7 @@ const logo = ` const ( subtitle = `tview - Rich Widgets for Terminal UIs` navigation = `Ctrl-N: Next slide Ctrl-P: Previous slide Ctrl-C: Exit` + mouse = `(or use your mouse)` ) // Cover returns the cover page. @@ -45,7 +46,8 @@ func Cover(nextSlide func()) (title string, content tview.Primitive) { SetBorders(0, 0, 0, 0, 0, 0). AddText(subtitle, true, tview.AlignCenter, tcell.ColorWhite). AddText("", true, tview.AlignCenter, tcell.ColorWhite). - AddText(navigation, true, tview.AlignCenter, tcell.ColorDarkMagenta) + AddText(navigation, true, tview.AlignCenter, tcell.ColorDarkMagenta). + AddText(mouse, true, tview.AlignCenter, tcell.ColorDarkMagenta) // Create a Flex layout that centers the logo and subtitle. flex := tview.NewFlex(). diff --git a/demos/presentation/main.go b/demos/presentation/main.go index 7ae2eb9..065d798 100644 --- a/demos/presentation/main.go +++ b/demos/presentation/main.go @@ -47,33 +47,36 @@ func main() { End, } + pages := tview.NewPages() + // The bottom row has some info on where we are. info := tview.NewTextView(). SetDynamicColors(true). SetRegions(true). - SetWrap(false) + SetWrap(false). + SetHighlightedFunc(func(added, removed, remaining []string) { + pages.SwitchToPage(added[0]) + }) // Create the pages for all slides. - currentSlide := 0 - info.Highlight(strconv.Itoa(currentSlide)) - pages := tview.NewPages() previousSlide := func() { - currentSlide = (currentSlide - 1 + len(slides)) % len(slides) - info.Highlight(strconv.Itoa(currentSlide)). + slide, _ := strconv.Atoi(info.GetHighlights()[0]) + slide = (slide - 1 + len(slides)) % len(slides) + info.Highlight(strconv.Itoa(slide)). ScrollToHighlight() - pages.SwitchToPage(strconv.Itoa(currentSlide)) } nextSlide := func() { - currentSlide = (currentSlide + 1) % len(slides) - info.Highlight(strconv.Itoa(currentSlide)). + slide, _ := strconv.Atoi(info.GetHighlights()[0]) + slide = (slide + 1) % len(slides) + info.Highlight(strconv.Itoa(slide)). ScrollToHighlight() - pages.SwitchToPage(strconv.Itoa(currentSlide)) } for index, slide := range slides { title, primitive := slide(nextSlide) - pages.AddPage(strconv.Itoa(index), primitive, true, index == currentSlide) + pages.AddPage(strconv.Itoa(index), primitive, true, index == 0) fmt.Fprintf(info, `%d ["%d"][darkcyan]%s[white][""] `, index+1, index, title) } + info.Highlight("0") // Create the main layout. layout := tview.NewFlex(). diff --git a/textview.go b/textview.go index 4095454..e911c5f 100644 --- a/textview.go +++ b/textview.go @@ -190,7 +190,7 @@ type TextView struct { // An optional function which is called when one or more regions were // highlighted. - highlighted func([]string, []string) + highlighted func(added, removed, remaining []string) } // NewTextView returns a new text view. @@ -348,8 +348,12 @@ func (t *TextView) SetDoneFunc(handler func(key tcell.Key)) *TextView { // SetHighlightedFunc sets a handler which is called when the list of currently // highlighted regions change. It receives a list of region IDs which were newly -// highlighted as well as those that are not highlighted anymore. -func (t *TextView) SetHighlightedFunc(handler func(addedRegionIDs, removedRedionIDs []string)) *TextView { +// highlighted, those that are not highlighted anymore, and those that remain +// highlighted. +// +// Note that because regions are only determined during drawing, this function +// can only fire for regions that have existed during the last call to Draw(). +func (t *TextView) SetHighlightedFunc(handler func(added, removed, remaining []string)) *TextView { t.highlighted = handler return t } @@ -416,50 +420,55 @@ func (t *TextView) Clear() *TextView { // Text in highlighted regions will be drawn inverted, i.e. with their // background and foreground colors swapped. func (t *TextView) Highlight(regionIDs ...string) *TextView { - // Determine added and removed regions. - var added, removed []string - if t.highlighted != nil { - highlights := make(map[string]struct{}) - for regionID, highlight := range t.highlights { - highlights[regionID] = highlight + // Toggle highlights. + if t.toggleHighlights { + var newIDs []string + HighlightLoop: + for regionID := range t.highlights { + for _, id := range regionIDs { + if regionID == id { + continue HighlightLoop + } + } + newIDs = append(newIDs, regionID) } for _, regionID := range regionIDs { - if _, ok := highlights[regionID]; ok { - added = append(added, regionID) - delete(highlights, regionID) + if _, ok := t.highlights[regionID]; !ok { + newIDs = append(newIDs, regionID) } } - for regionID := range highlights { + regionIDs = newIDs + } // Now we have a list of region IDs that end up being highlighted. + + // Determine added and removed regions. + var added, removed, remaining []string + if t.highlighted != nil { + for _, regionID := range regionIDs { + if _, ok := t.highlights[regionID]; ok { + remaining = append(remaining, regionID) + delete(t.highlights, regionID) + } else { + added = append(added, regionID) + } + } + for regionID := range t.highlights { removed = append(removed, regionID) } } // Make new selection. - if t.toggleHighlights { - for _, id := range regionIDs { - if id == "" { - continue - } - if _, ok := t.highlights[id]; ok { - delete(t.highlights, id) - } else { - t.highlights[id] = struct{}{} - } + t.highlights = make(map[string]struct{}) + for _, id := range regionIDs { + if id == "" { + continue } - } else { - t.highlights = make(map[string]struct{}) - for _, id := range regionIDs { - if id == "" { - continue - } - t.highlights[id] = struct{}{} - } - t.index = nil + t.highlights[id] = struct{}{} } + t.index = nil // Notify. - if t.highlighted != nil { - t.highlighted(added, removed) + if t.highlighted != nil && len(added) > 0 || len(removed) > 0 { + t.highlighted(added, removed, remaining) } return t