1
0
mirror of https://github.com/rivo/tview.git synced 2025-04-28 13:48:53 +08:00

Added mouse support to presentation demo. TextView "highlighted" callback also receives remaining highlights.

This commit is contained in:
Oliver 2020-03-29 20:53:28 +02:00
parent 2505a942a1
commit b3dc389cb4
3 changed files with 60 additions and 46 deletions

View File

@ -20,6 +20,7 @@ const logo = `
const ( const (
subtitle = `tview - Rich Widgets for Terminal UIs` subtitle = `tview - Rich Widgets for Terminal UIs`
navigation = `Ctrl-N: Next slide Ctrl-P: Previous slide Ctrl-C: Exit` navigation = `Ctrl-N: Next slide Ctrl-P: Previous slide Ctrl-C: Exit`
mouse = `(or use your mouse)`
) )
// Cover returns the cover page. // 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). SetBorders(0, 0, 0, 0, 0, 0).
AddText(subtitle, true, tview.AlignCenter, tcell.ColorWhite). AddText(subtitle, true, tview.AlignCenter, tcell.ColorWhite).
AddText("", 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. // Create a Flex layout that centers the logo and subtitle.
flex := tview.NewFlex(). flex := tview.NewFlex().

View File

@ -47,33 +47,36 @@ func main() {
End, End,
} }
pages := tview.NewPages()
// The bottom row has some info on where we are. // The bottom row has some info on where we are.
info := tview.NewTextView(). info := tview.NewTextView().
SetDynamicColors(true). SetDynamicColors(true).
SetRegions(true). SetRegions(true).
SetWrap(false) SetWrap(false).
SetHighlightedFunc(func(added, removed, remaining []string) {
pages.SwitchToPage(added[0])
})
// Create the pages for all slides. // Create the pages for all slides.
currentSlide := 0
info.Highlight(strconv.Itoa(currentSlide))
pages := tview.NewPages()
previousSlide := func() { previousSlide := func() {
currentSlide = (currentSlide - 1 + len(slides)) % len(slides) slide, _ := strconv.Atoi(info.GetHighlights()[0])
info.Highlight(strconv.Itoa(currentSlide)). slide = (slide - 1 + len(slides)) % len(slides)
info.Highlight(strconv.Itoa(slide)).
ScrollToHighlight() ScrollToHighlight()
pages.SwitchToPage(strconv.Itoa(currentSlide))
} }
nextSlide := func() { nextSlide := func() {
currentSlide = (currentSlide + 1) % len(slides) slide, _ := strconv.Atoi(info.GetHighlights()[0])
info.Highlight(strconv.Itoa(currentSlide)). slide = (slide + 1) % len(slides)
info.Highlight(strconv.Itoa(slide)).
ScrollToHighlight() ScrollToHighlight()
pages.SwitchToPage(strconv.Itoa(currentSlide))
} }
for index, slide := range slides { for index, slide := range slides {
title, primitive := slide(nextSlide) 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) fmt.Fprintf(info, `%d ["%d"][darkcyan]%s[white][""] `, index+1, index, title)
} }
info.Highlight("0")
// Create the main layout. // Create the main layout.
layout := tview.NewFlex(). layout := tview.NewFlex().

View File

@ -190,7 +190,7 @@ type TextView struct {
// An optional function which is called when one or more regions were // An optional function which is called when one or more regions were
// highlighted. // highlighted.
highlighted func([]string, []string) highlighted func(added, removed, remaining []string)
} }
// NewTextView returns a new text view. // 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 // 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 regions change. It receives a list of region IDs which were newly
// highlighted as well as those that are not highlighted anymore. // highlighted, those that are not highlighted anymore, and those that remain
func (t *TextView) SetHighlightedFunc(handler func(addedRegionIDs, removedRedionIDs []string)) *TextView { // 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 t.highlighted = handler
return t return t
} }
@ -416,50 +420,55 @@ func (t *TextView) Clear() *TextView {
// Text in highlighted regions will be drawn inverted, i.e. with their // Text in highlighted regions will be drawn inverted, i.e. with their
// background and foreground colors swapped. // background and foreground colors swapped.
func (t *TextView) Highlight(regionIDs ...string) *TextView { func (t *TextView) Highlight(regionIDs ...string) *TextView {
// Determine added and removed regions. // Toggle highlights.
var added, removed []string if t.toggleHighlights {
if t.highlighted != nil { var newIDs []string
highlights := make(map[string]struct{}) HighlightLoop:
for regionID, highlight := range t.highlights { for regionID := range t.highlights {
highlights[regionID] = highlight for _, id := range regionIDs {
if regionID == id {
continue HighlightLoop
}
}
newIDs = append(newIDs, regionID)
} }
for _, regionID := range regionIDs { for _, regionID := range regionIDs {
if _, ok := highlights[regionID]; ok { if _, ok := t.highlights[regionID]; !ok {
added = append(added, regionID) newIDs = append(newIDs, regionID)
delete(highlights, 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) removed = append(removed, regionID)
} }
} }
// Make new selection. // Make new selection.
if t.toggleHighlights { t.highlights = make(map[string]struct{})
for _, id := range regionIDs { for _, id := range regionIDs {
if id == "" { if id == "" {
continue continue
}
if _, ok := t.highlights[id]; ok {
delete(t.highlights, id)
} else {
t.highlights[id] = struct{}{}
}
} }
} else { t.highlights[id] = struct{}{}
t.highlights = make(map[string]struct{})
for _, id := range regionIDs {
if id == "" {
continue
}
t.highlights[id] = struct{}{}
}
t.index = nil
} }
t.index = nil
// Notify. // Notify.
if t.highlighted != nil { if t.highlighted != nil && len(added) > 0 || len(removed) > 0 {
t.highlighted(added, removed) t.highlighted(added, removed, remaining)
} }
return t return t