Add sementic colors for time, header and "default"

master
joce 3 years ago
parent b45fbfe908
commit 3df70dc52c
  1. 12
      layout.go
  2. 20
      markup.go
  3. 26
      profile.go
  4. 25
      screen.go

@ -168,7 +168,7 @@ func (layout *Layout) prettify(quotes *Quotes) []Stock {
profile := quotes.profile profile := quotes.profile
if profile.Filter != ""{ // Fix for blank display if invalid filter expression was cleared. if profile.Filter != "" { // Fix for blank display if invalid filter expression was cleared.
if profile.filterExpression != nil { if profile.filterExpression != nil {
if layout.filter == nil { // Initialize filter on first invocation. if layout.filter == nil { // Initialize filter on first invocation.
layout.filter = NewFilter(profile) layout.filter = NewFilter(profile)
@ -218,11 +218,11 @@ func buildMarketTemplate() *template.Template {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func buildQuotesTemplate() *template.Template { func buildQuotesTemplate() *template.Template {
markup := `<right><white>{{.Now}}</></right> markup := `<right><time>{{.Now}}</></right>
{{.Header}} <header>{{.Header}}</>
{{range.Stocks}}{{if eq .Direction 1}}<gain>{{else if eq .Direction -1}}<loss>{{end}}{{.Ticker}}{{.LastTrade}}{{.Change}}{{.ChangePct}}{{.Open}}{{.Low}}{{.High}}{{.Low52}}{{.High52}}{{.Volume}}{{.AvgVolume}}{{.PeRatio}}{{.Dividend}}{{.Yield}}{{.MarketCap}}{{.PreOpen}}{{.AfterHours}}</> {{range.Stocks}}{{if eq .Direction 1}}<gain>{{else if eq .Direction -1}}<loss>{{end}}{{.Ticker}}{{.LastTrade}}{{.Change}}{{.ChangePct}}{{.Open}}{{.Low}}{{.High}}{{.Low52}}{{.High52}}{{.Volume}}{{.AvgVolume}}{{.PeRatio}}{{.Dividend}}{{.Yield}}{{.MarketCap}}{{.PreOpen}}{{.AfterHours}}</>
{{end}}` {{end}}`
@ -234,7 +234,7 @@ func highlight(collections ...map[string]string) {
for _, collection := range collections { for _, collection := range collections {
change := collection[`change`] change := collection[`change`]
if change[len(change)-1:] == `%` { if change[len(change)-1:] == `%` {
change = change[0:len(change)-1] change = change[0 : len(change)-1]
} }
adv, err := strconv.ParseFloat(change, 64) adv, err := strconv.ParseFloat(change, 64)
if err == nil { if err == nil {
@ -272,9 +272,9 @@ func group(stocks []Stock) []Stock {
func arrowFor(column int, profile *Profile) string { func arrowFor(column int, profile *Profile) string {
if column == profile.SortColumn { if column == profile.SortColumn {
if profile.Ascending { if profile.Ascending {
return string('\U00002191') return string('')
} }
return string('\U00002193') return string('')
} }
return `` return ``
} }

@ -5,9 +5,10 @@
package mop package mop
import ( import (
`github.com/nsf/termbox-go` "regexp"
`regexp` "strings"
`strings`
"github.com/nsf/termbox-go"
) )
// Markup implements some minimalistic text formatting conventions that // Markup implements some minimalistic text formatting conventions that
@ -35,9 +36,6 @@ type Markup struct {
// colors and column alignments. // colors and column alignments.
func NewMarkup(profile *Profile) *Markup { func NewMarkup(profile *Profile) *Markup {
markup := &Markup{} markup := &Markup{}
markup.Foreground = termbox.ColorDefault
markup.Background = termbox.ColorDefault
markup.RightAligned = false
markup.tags = make(map[string]termbox.Attribute) markup.tags = make(map[string]termbox.Attribute)
markup.tags[`/`] = termbox.ColorDefault markup.tags[`/`] = termbox.ColorDefault
@ -67,6 +65,14 @@ func NewMarkup(profile *Profile) *Markup {
markup.tags[`gain`] = markup.tags[profile.Colors.Gain] markup.tags[`gain`] = markup.tags[profile.Colors.Gain]
markup.tags[`loss`] = markup.tags[profile.Colors.Loss] markup.tags[`loss`] = markup.tags[profile.Colors.Loss]
markup.tags[`tag`] = markup.tags[profile.Colors.Tag] markup.tags[`tag`] = markup.tags[profile.Colors.Tag]
markup.tags[`header`] = markup.tags[profile.Colors.Header]
markup.tags[`time`] = markup.tags[profile.Colors.Time]
markup.tags[`default`] = markup.tags[profile.Colors.Default]
markup.Foreground = markup.tags[profile.Colors.Default]
markup.Background = termbox.ColorDefault
markup.RightAligned = false
markup.regex = markup.supportedTags() // Once we have the hash we could build the regex. markup.regex = markup.supportedTags() // Once we have the hash we could build the regex.
@ -138,7 +144,7 @@ func (markup *Markup) process(tag string, open bool) bool {
if attribute >= termbox.AttrBold { if attribute >= termbox.AttrBold {
markup.Foreground &= ^attribute // Clear the Termbox attribute. markup.Foreground &= ^attribute // Clear the Termbox attribute.
} else { } else {
markup.Foreground = termbox.ColorDefault markup.Foreground = markup.tags[`default`]
} }
} }
} }

@ -16,6 +16,9 @@ import (
const defaultGainColor = "green" const defaultGainColor = "green"
const defaultLossColor = "red" const defaultLossColor = "red"
const defaultTagColor = "yellow" const defaultTagColor = "yellow"
const defaultHeaderColor = "lightgray"
const defaultTimeColor = "lightgray"
const defaultColor = "lightgray"
// Profile manages Mop program settings as defined by user (ex. list of // Profile manages Mop program settings as defined by user (ex. list of
// stock tickers). The settings are serialized using JSON and saved in // stock tickers). The settings are serialized using JSON and saved in
@ -32,6 +35,9 @@ type Profile struct {
Gain string Gain string
Loss string Loss string
Tag string Tag string
Header string
Time string
Default string
} }
filterExpression *govaluate.EvaluableExpression // The filter as a govaluate expression filterExpression *govaluate.EvaluableExpression // The filter as a govaluate expression
selectedColumn int // Stores selected column number when the column editor is active. selectedColumn int // Stores selected column number when the column editor is active.
@ -78,13 +84,19 @@ func NewProfile(filename string) *Profile {
profile.Colors.Gain = defaultGainColor profile.Colors.Gain = defaultGainColor
profile.Colors.Loss = defaultLossColor profile.Colors.Loss = defaultLossColor
profile.Colors.Tag = defaultTagColor profile.Colors.Tag = defaultTagColor
profile.Colors.Header = defaultHeaderColor
profile.Colors.Time = defaultTimeColor
profile.Colors.Default = defaultColor
profile.Save() profile.Save()
} else { } else {
json.Unmarshal(data, profile) json.Unmarshal(data, profile)
InitColor(profile.Colors.Gain, defaultGainColor) InitColor(&profile.Colors.Gain, defaultGainColor)
InitColor(profile.Colors.Loss, defaultLossColor) InitColor(&profile.Colors.Loss, defaultLossColor)
InitColor(profile.Colors.Tag, defaultTagColor) InitColor(&profile.Colors.Tag, defaultTagColor)
InitColor(&profile.Colors.Header, defaultHeaderColor)
InitColor(&profile.Colors.Time, defaultTimeColor)
InitColor(&profile.Colors.Default, defaultColor)
profile.SetFilter(profile.Filter) profile.SetFilter(profile.Filter)
} }
@ -93,10 +105,10 @@ func NewProfile(filename string) *Profile {
return profile return profile
} }
func InitColor(color string, defaultValue string) { func InitColor(color *string, defaultValue string) {
color = strings.ToLower(color) *color = strings.ToLower(*color)
if !IsSupportedColor(color) { if !IsSupportedColor(*color) {
color = defaultValue; *color = defaultValue
} }
} }

@ -5,11 +5,12 @@
package mop package mop
import ( import (
`github.com/nsf/termbox-go` "fmt"
`strings` "strconv"
`time` "strings"
`strconv` "time"
`fmt`
"github.com/nsf/termbox-go"
) )
// Screen is thin wrapper around Termbox library to provide basic display // Screen is thin wrapper around Termbox library to provide basic display
@ -90,7 +91,7 @@ func (screen *Screen) ClearLine(x int, y int) *Screen {
func (screen *Screen) Draw(objects ...interface{}) *Screen { func (screen *Screen) Draw(objects ...interface{}) *Screen {
zonename, _ := time.Now().In(time.Local).Zone() zonename, _ := time.Now().In(time.Local).Zone()
if screen.pausedAt != nil { if screen.pausedAt != nil {
defer screen.DrawLine(0, 0, `<right><r>`+screen.pausedAt.Format(`3:04:05pm ` + zonename)+`</r></right>`) defer screen.DrawLine(0, 0, `<right><r>`+screen.pausedAt.Format(`3:04:05pm `+zonename)+`</r></right>`)
} }
for _, ptr := range objects { for _, ptr := range objects {
switch ptr.(type) { switch ptr.(type) {
@ -102,7 +103,7 @@ func (screen *Screen) Draw(objects ...interface{}) *Screen {
screen.draw(screen.layout.Quotes(object.Fetch())) screen.draw(screen.layout.Quotes(object.Fetch()))
case time.Time: case time.Time:
timestamp := ptr.(time.Time).Format(`3:04:05pm ` + zonename) timestamp := ptr.(time.Time).Format(`3:04:05pm ` + zonename)
screen.DrawLine(0, 0, `<right>`+timestamp+`</right>`) screen.DrawLine(0, 0, `<right><time>`+timestamp+`</></right>`)
default: default:
screen.draw(ptr.(string)) screen.draw(ptr.(string))
} }
@ -146,7 +147,7 @@ func (screen *Screen) draw(str string) {
drewHeading := false drewHeading := false
tempFormat := "%" + strconv.Itoa(screen.width) + "s" tempFormat := "%" + strconv.Itoa(screen.width) + "s"
blankLine := fmt.Sprintf(tempFormat,"") blankLine := fmt.Sprintf(tempFormat, "")
allLines = strings.Split(str, "\n") allLines = strings.Split(str, "\n")
// Write the lines being updated. // Write the lines being updated.
@ -154,9 +155,9 @@ func (screen *Screen) draw(str string) {
screen.DrawLine(0, row, allLines[row]) screen.DrawLine(0, row, allLines[row])
// Did we draw the underlined heading row? This is a crude // Did we draw the underlined heading row? This is a crude
// check, but--see comments below... // check, but--see comments below...
if strings.Contains(allLines[row],"Ticker") && if strings.Contains(allLines[row], "Ticker") &&
strings.Contains(allLines[row],"Last") && strings.Contains(allLines[row], "Last") &&
strings.Contains(allLines[row],"Change") { strings.Contains(allLines[row], "Change") {
drewHeading = true drewHeading = true
} }
} }
@ -173,7 +174,7 @@ func (screen *Screen) draw(str string) {
// cycle. In that case, padding with blank lines would overwrite the // cycle. In that case, padding with blank lines would overwrite the
// stocks list.) // stocks list.)
if drewHeading { if drewHeading {
for i := len(allLines)-1; i < screen.height; i++ { for i := len(allLines) - 1; i < screen.height; i++ {
screen.DrawLine(0, i, blankLine) screen.DrawLine(0, i, blankLine)
} }
} }

Loading…
Cancel
Save