1// Copyright 2019 Graham Clark. All rights reserved. Use of this source code is governed by the MIT license 2// that can be found in the LICENSE file. 3 4// A port of urwid's palette_test.py example using gowid widgets. 5package main 6 7import ( 8 "errors" 9 "regexp" 10 "strings" 11 12 "github.com/gcla/gowid" 13 "github.com/gcla/gowid/examples" 14 "github.com/gcla/gowid/widgets/button" 15 "github.com/gcla/gowid/widgets/columns" 16 "github.com/gcla/gowid/widgets/divider" 17 "github.com/gcla/gowid/widgets/holder" 18 "github.com/gcla/gowid/widgets/pile" 19 "github.com/gcla/gowid/widgets/radio" 20 "github.com/gcla/gowid/widgets/styled" 21 "github.com/gcla/gowid/widgets/text" 22 "github.com/gdamore/tcell" 23 log "github.com/sirupsen/logrus" 24) 25 26//====================================================================== 27 28// t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t254 t255 29 30var chart256 = ` 31brown__ dark_red_ dark_magenta_ dark_blue_ dark_cyan_ dark_green_ 32yellow_ light_red light_magenta light_blue light_cyan light_green 33 34 #00f#06f#08f#0af#0df#0ff black_______ dark_gray___ 35 #60f#00d#06d#08d#0ad#0dd#0fd light_gray__ white_______ 36 #80f#60d#00a#06a#08a#0aa#0da#0fa 37 #a0f#80d#60a#008#068#088#0a8#0d8#0f8 38 #d0f#a0d#80d#608#006#066#086#0a6#0d6#0f6 39 #f0f#d0d#a0a#808#606#000#060#080#0a0#0d0#0f0#0f6#0f8#0fa#0fd#0ff 40 #f0d#d0a#a08#806#600#660#680#6a0#6d0#6f0#6f6#6f8#6fa#6fd#6ff#0df 41 #f0a#d08#a06#800#860#880#8a0#8d0#8f0#8f6#8f8#8fa#8fd#8ff#6df#0af 42 #f08#d06#a00#a60#a80#aa0#ad0#af0#af6#af8#afa#afd#aff#8df#6af#08f 43 #f06#d00#d60#d80#da0#dd0#df0#df6#df8#dfa#dfd#dff#adf#8af#68f#06f 44 #f00#f60#f80#fa0#fd0#ff0#ff6#ff8#ffa#ffd#fff#ddf#aaf#88f#66f#00f 45 #fd0#fd6#fd8#fda#fdd#fdf#daf#a8f#86f#60f 46 #66d#68d#6ad#6dd #fa0#fa6#fa8#faa#fad#faf#d8f#a6f#80f 47 #86d#66a#68a#6aa#6da #f80#f86#f88#f8a#f8d#f8f#d6f#a0f 48 #a6d#86a#668#688#6a8#6d8 #f60#f66#f68#f6a#f6d#f6f#d0f 49#d6d#a6a#868#666#686#6a6#6d6#6d8#6da#6dd #f00#f06#f08#f0a#f0d#f0f 50 #d6a#a68#866#886#8a6#8d6#8d8#8da#8dd#6ad 51 #d68#a66#a86#aa6#ad6#ad8#ada#add#8ad#68d 52 #d66#d86#da6#dd6#dd8#dda#ddd#aad#88d#66d g78_g82_g85_g89_g93_g100_ 53 #da6#da8#daa#dad#a8d#86d g52_g58_g62_g66_g70_g74_ 54 #88a#8aa #d86#d88#d8a#d8d#a6d g27_g31_g35_g38_g42_g46_g50_ 55 #a8a#888#8a8#8aa #d66#d68#d6a#d6d g0__g3__g7__g11_g15_g19_g23_ 56 #a88#aa8#aaa#88a 57 #a88#a8a 58` 59 60var chart88 = ` 61brown__ dark_red_ dark_magenta_ dark_blue_ dark_cyan_ dark_green_ 62yellow_ light_red light_magenta light_blue light_cyan light_green 63 64 #00f#08f#0cf#0ff black_______ dark_gray___ 65 #80f#00c#08c#0cc#0fc light_gray__ white_______ 66 #c0f#80c#008#088#0c8#0f8 67#f0f#c0c#808#000#080#0c0#0f0#0f8#0fc#0ff #88c#8cc 68 #f0c#c08#800#880#8c0#8f0#8f8#8fc#8ff#0cf #c8c#888#8c8#8cc 69 #f08#c00#c80#cc0#cf0#cf8#cfc#cff#8cf#08f #c88#cc8#ccc#88c 70 #f00#f80#fc0#ff0#ff8#ffc#fff#ccf#88f#00f #c88#c8c 71 #fc0#fc8#fcc#fcf#c8f#80f 72 #f80#f88#f8c#f8f#c0f g62_g74_g82_g89_g100 73 #f00#f08#f0c#f0f g0__g19_g35_g46_g52 74` 75 76var chart16 = ` 77brown__ dark_red_ dark_magenta_ dark_blue_ dark_cyan_ dark_green_ 78yellow_ light_red light_magenta light_blue light_cyan light_green 79 80black_______ dark_gray___ light_gray__ white_______ 81` 82 83var chart8 = ` 84black__ red_ green_ yellow_ blue_ magenta_ cyan_ white_ 85` 86 87var chartMono = ` 88black__ white_ 89` 90 91var attrRE = regexp.MustCompile(`(?P<whitespace>[ \n]*)(?P<entry>((#...)|([a-z_]{2,})|(g[0-9]+_+)|(t[0-9]{1,3})))`) 92 93var attrREIndices = makeRegexpNameMap(attrRE) 94 95var fgColorDefault = gowid.NewUrwidColor("light gray") 96var bgColorDefault = gowid.MakeTCellColorExt(tcell.ColorBlack) 97 98var chartHolder *holder.Widget 99 100var chart256Content *text.Widget 101var chart88Content *text.Widget 102var chart16Content *text.Widget 103var chart8Content *text.Widget 104var chartMonoContent *text.Widget 105 106var foregroundColors = true 107 108//====================================================================== 109 110func makeRegexpNameMap(re *regexp.Regexp) map[string]int { 111 res := make(map[string]int) 112 for i, name := range re.SubexpNames() { 113 res[name] = i 114 } 115 return res 116} 117 118//====================================================================== 119 120func updateChartHolder(mode gowid.ColorMode, app gowid.IApp) { 121 switch mode { 122 case gowid.Mode256Colors: 123 chart256Content = text.NewFromContent(parseChart(chart256)) 124 chartHolder.SetSubWidget(chart256Content, app) 125 case gowid.Mode88Colors: 126 chart88Content = text.NewFromContent(parseChart(chart88)) 127 chartHolder.SetSubWidget(chart88Content, app) 128 case gowid.Mode16Colors: 129 chart16Content = text.NewFromContent(parseChart(chart16)) 130 chartHolder.SetSubWidget(chart16Content, app) 131 case gowid.Mode8Colors: 132 chart8Content = text.NewFromContent(parseChart(chart8)) 133 chartHolder.SetSubWidget(chart8Content, app) 134 case gowid.ModeMonochrome: 135 chartMonoContent = text.NewFromContent(parseChart(chartMono)) 136 chartHolder.SetSubWidget(chartMonoContent, app) 137 default: 138 panic(errors.New("Invalid mode, something went wrong!")) 139 } 140} 141 142//====================================================================== 143 144func modeRb(group *[]radio.IWidget, txt string) gowid.IWidget { 145 rbt := text.New(" " + txt) 146 rb := radio.New(group) 147 widp := gowid.RenderFixed{} 148 149 rb.OnClick(gowid.WidgetCallback{"cb", func(app gowid.IApp, w gowid.IWidget) { 150 if rb.Selected { 151 switch txt { 152 case "256-Color": 153 app.SetColorMode(gowid.Mode256Colors) 154 case "88-Color": 155 app.SetColorMode(gowid.Mode88Colors) 156 case "16-Color": 157 app.SetColorMode(gowid.Mode16Colors) 158 case "8-Color": 159 app.SetColorMode(gowid.Mode8Colors) 160 case "Monochrome": 161 app.SetColorMode(gowid.ModeMonochrome) 162 case "Foreground Colors": 163 foregroundColors = true 164 case "Background Colors": 165 foregroundColors = false 166 default: 167 panic(errors.New("Invalid mode, something went wrong!")) 168 } 169 updateChartHolder(app.GetColorMode(), app) // Update the chart displayed 170 } 171 }}) 172 173 c := columns.New([]gowid.IContainerWidget{ 174 &gowid.ContainerWidget{rb, widp}, 175 &gowid.ContainerWidget{rbt, widp}, 176 }) 177 178 cm := styled.NewExt(c, gowid.MakePaletteRef("panel"), gowid.MakePaletteRef("focus")) 179 180 return cm 181} 182 183//====================================================================== 184 185func parseChart(chart string) *text.Content { 186 content := make([]text.ContentSegment, 0) 187 replacer := strings.NewReplacer("_", " ") 188 for _, match := range attrRE.FindAllStringSubmatch(chart, -1) { 189 ws := match[attrREIndices["whitespace"]] 190 if ws != "" { 191 content = append(content, text.StringContent(ws)) 192 } 193 entry := match[attrREIndices["entry"]] 194 entry = replacer.Replace(entry) 195 196 entry2 := strings.Trim(entry, " ") 197 scol, err := gowid.MakeColorSafe(entry2) 198 if err == nil { 199 var attrPair gowid.PaletteEntry 200 if foregroundColors { 201 attrPair = gowid.MakePaletteEntry(scol, bgColorDefault) 202 } else { 203 attrPair = gowid.MakePaletteEntry(fgColorDefault, scol) 204 } 205 content = append(content, text.StyledContent(entry, attrPair)) 206 } else { 207 content = append(content, text.StyledContent(entry, gowid.MakePaletteRef("redinv"))) 208 } 209 } 210 return text.NewContent(content) 211} 212 213//====================================================================== 214 215func main() { 216 217 f := examples.RedirectLogger("palette.log") 218 defer f.Close() 219 220 palette := gowid.Palette{ 221 "header": gowid.MakeStyledPaletteEntry(gowid.ColorBlack, gowid.ColorWhite, gowid.StyleUnderline), 222 "panel": gowid.MakePaletteEntry(gowid.ColorWhite, gowid.ColorDarkBlue), 223 "focus": gowid.MakePaletteEntry(gowid.ColorYellow, gowid.ColorRed), 224 "red": gowid.MakePaletteEntry(gowid.ColorRed, gowid.ColorBlack), 225 "redinv": gowid.MakePaletteEntry(gowid.ColorBlack, gowid.ColorRed), 226 "default": gowid.MakePaletteEntry(gowid.NewUrwidColor("light gray"), gowid.ColorBlack), 227 } 228 229 header := gowid.MakePaletteRef("header") 230 231 // make this just text 232 headerContent := []text.ContentSegment{ 233 text.StyledContent("Gowid Palette Test", header), 234 } 235 236 headerText := styled.New(text.NewFromContent(text.NewContent(headerContent)), header) 237 238 rbgroup := make([]radio.IWidget, 0) 239 bggroup := make([]radio.IWidget, 0) 240 241 btn := button.New(text.New("Exit")) 242 243 btn.OnClick(gowid.WidgetCallback{"cb", func(app gowid.IApp, w gowid.IWidget) { 244 app.Quit() 245 }}) 246 247 subFlow := gowid.RenderFlow{} 248 249 // Put this in the group first so it is the one selected 250 cols256 := modeRb(&rbgroup, "256-Color") 251 252 pw1 := pile.New([]gowid.IContainerWidget{ 253 &gowid.ContainerWidget{modeRb(&rbgroup, "Monochrome"), subFlow}, 254 &gowid.ContainerWidget{modeRb(&rbgroup, "8-Color"), subFlow}, 255 &gowid.ContainerWidget{modeRb(&rbgroup, "16-Color"), subFlow}, 256 &gowid.ContainerWidget{modeRb(&rbgroup, "88-Color"), subFlow}, 257 &gowid.ContainerWidget{cols256, subFlow}, 258 }) 259 260 pw2 := pile.New([]gowid.IContainerWidget{ 261 &gowid.ContainerWidget{modeRb(&bggroup, "Foreground Colors"), subFlow}, 262 &gowid.ContainerWidget{modeRb(&bggroup, "Background Colors"), subFlow}, 263 &gowid.ContainerWidget{divider.NewBlank(), subFlow}, 264 &gowid.ContainerWidget{divider.NewBlank(), subFlow}, 265 &gowid.ContainerWidget{ 266 styled.NewExt( 267 btn, 268 gowid.MakePaletteRef("panel"), 269 gowid.MakePaletteRef("focus"), 270 ), 271 subFlow}, 272 }) 273 274 cs := columns.New([]gowid.IContainerWidget{ 275 &gowid.ContainerWidget{pw1, gowid.RenderWithWeight{10}}, 276 &gowid.ContainerWidget{pw2, gowid.RenderWithWeight{10}}, 277 }) 278 279 cs2 := styled.New(cs, gowid.MakePaletteRef("panel")) 280 281 chart256Content = text.NewFromContent(parseChart(chart256)) 282 chartHolder = holder.New(chart256Content) 283 284 view := pile.New([]gowid.IContainerWidget{ 285 &gowid.ContainerWidget{headerText, subFlow}, 286 &gowid.ContainerWidget{cs2, subFlow}, 287 &gowid.ContainerWidget{chartHolder, gowid.RenderWithWeight{1}}, 288 }) 289 290 app, err := gowid.NewApp(gowid.AppArgs{ 291 View: view, 292 Palette: &palette, 293 Log: log.StandardLogger(), 294 }) 295 examples.ExitOnErr(err) 296 app.SetColorMode(gowid.Mode256Colors) 297 298 app.SimpleMainLoop() 299} 300 301//====================================================================== 302// Local Variables: 303// mode: Go 304// fill-column: 110 305// End: 306