Improved scrolling.

* Added scrolling with scroll wheel on mouse.
 * Added scrolling with vim style j/k keys.
 * Changed scrolling so that it is more smooth and the whole screen is
   not redrawn each time
 * Changed channel keyboardQueue to a buffered queue, so there are not
   too many scroll requests, and the draw commands can be done once the
   queue is empty.
 * Added UpDownJump in profile, so user can set how much PgUp/PgDown jumps

 * Have not tested with a _huge_ number of stocks in ticker, probably
   worth doing
master
root 3 years ago
parent 6f78b90964
commit e1f62d6afc
  1. 46
      cmd/mop/main.go
  2. 6
      profile.go
  3. 12
      screen.go

@ -33,8 +33,8 @@ NO WARRANTIES OF ANY KIND WHATSOEVER. SEE THE LICENSE FILE FOR DETAILS.
g Group stocks by advancing/declining issues.
o Change column sort order.
p Pause market data and stock updates.
PgDn Scroll Down, down arrow key also works.
PgUp Scroll up, up arrow key also works.
Scroll Scroll up/down.
PgUp/PgDn; Up/Down arrow; j/k;J/K also all scroll up/down
q Quit mop.
esc Ditto.
@ -48,13 +48,18 @@ func mainLoop(screen *mop.Screen, profile *mop.Profile) {
var lineEditor *mop.LineEditor
var columnEditor *mop.ColumnEditor
keyboardQueue := make(chan termbox.Event)
termbox.SetInputMode(termbox.InputMouse)
// use buffered channel for keyboard event queue
keyboardQueue := make(chan termbox.Event, 16)
timestampQueue := time.NewTicker(1 * time.Second)
quotesQueue := time.NewTicker(5 * time.Second)
marketQueue := time.NewTicker(12 * time.Second)
showingHelp := false
paused := false
pgUpDownLines := 10
upDownJump := profile.UpDownJump
redrawQuotesFlag := false
go func() {
for {
@ -96,13 +101,19 @@ loop:
showingHelp = true
screen.Clear().Draw(help)
} else if event.Key == termbox.KeyPgdn ||
event.Key == termbox.KeyArrowDown {
screen.IncreaseOffset(pgUpDownLines, len(profile.Tickers))
screen.Clear().Draw(market, quotes)
event.Ch == 'J' {
screen.IncreaseOffset(upDownJump, len(profile.Tickers))
redrawQuotesFlag = true
} else if event.Key == termbox.KeyPgup ||
event.Key == termbox.KeyArrowUp {
screen.DecreaseOffset(pgUpDownLines)
screen.Clear().Draw(market, quotes)
event.Ch == 'K' {
screen.DecreaseOffset(upDownJump)
redrawQuotesFlag = true
} else if event.Key == termbox.KeyArrowUp || event.Ch == 'k' {
screen.DecreaseOffset(1)
redrawQuotesFlag = true
} else if event.Key == termbox.KeyArrowDown || event.Ch == 'j' {
screen.IncreaseOffset(1, len(profile.Tickers))
redrawQuotesFlag = true
}
} else if lineEditor != nil {
if done := lineEditor.Handle(event); done {
@ -123,6 +134,17 @@ loop:
} else {
screen.Draw(help)
}
case termbox.EventMouse:
if lineEditor == nil && columnEditor == nil && !showingHelp {
switch event.Key {
case termbox.MouseWheelUp:
screen.DecreaseOffset(1)
redrawQuotesFlag = true
case termbox.MouseWheelDown:
screen.IncreaseOffset(1, len(profile.Tickers))
redrawQuotesFlag = true
}
}
}
case <-timestampQueue.C:
@ -140,6 +162,10 @@ loop:
screen.Draw(market)
}
}
if redrawQuotesFlag && len(keyboardQueue) == 0 {
screen.Draw(quotes)
}
}
}

@ -31,6 +31,7 @@ type Profile struct {
Ascending bool // True when sort order is ascending.
Grouped bool // True when stocks are grouped by advancing/declining.
Filter string // Filter in human form
UpDownJump int // Number of lines to go up/down when scrolling.
Colors struct { // User defined colors
Gain string
Loss string
@ -93,6 +94,10 @@ func NewProfile(filename string) (*Profile, error) {
}
profile.selectedColumn = -1
if profile.UpDownJump < 1 {
profile.UpDownJump = 10
}
return profile, err
}
@ -105,6 +110,7 @@ func (profile *Profile) InitDefaultProfile() {
profile.SortColumn = 0 // Stock quotes are sorted by ticker name.
profile.Ascending = true // A to Z.
profile.Filter = ""
profile.UpDownJump = 10
profile.Colors.Gain = defaultGainColor
profile.Colors.Loss = defaultLossColor
profile.Colors.Tag = defaultTagColor

@ -92,7 +92,7 @@ func (screen *Screen) ClearLine(x int, y int) *Screen {
// Increase the offset for scrolling feature by n
// Takes number of tickers as max, so not scrolling down forever
func (screen *Screen) IncreaseOffset(n int, max int) {
if screen.offset+n < max {
if screen.offset+n+1 < max {
screen.offset += n
}
}
@ -173,9 +173,9 @@ func (screen *Screen) draw(str string, offset bool) {
// Write the lines being updated.
for row := 0; row < len(allLines); row++ {
if offset {
// Did we draw the underlined heading row? This is a crude
// check, but--see comments below...
// --- Heading row only appears for quotes, so offset is true
// Did we draw the underlined heading row? This is a crude
// check, but--see comments below...
// --- Heading row only appears for quotes, so offset is true
if strings.Contains(allLines[row], "Ticker") &&
strings.Contains(allLines[row], "Last") &&
strings.Contains(allLines[row], "Change") {
@ -189,7 +189,7 @@ func (screen *Screen) draw(str string, offset bool) {
}
}
} else {
screen.DrawLine(0, row, allLines[row])
screen.DrawLine(0, row, allLines[row])
}
}
// If the quotes lines in this cycle are shorter than in the previous
@ -205,7 +205,7 @@ func (screen *Screen) draw(str string, offset bool) {
// cycle. In that case, padding with blank lines would overwrite the
// stocks list.)
if drewHeading {
for i := len(allLines) - 1; i < screen.height; i++ {
for i := len(allLines) - 1 - screen.offset; i < screen.height; i++ {
screen.DrawLine(0, i, blankLine)
}
}

Loading…
Cancel
Save