1// Copyright 2019 Graham Clark. All rights reserved. Use of this source 2// code is governed by the MIT license that can be found in the LICENSE 3// file. 4 5// Package divider provides a widget that draws a dividing line between other widgets. 6package divider 7 8import ( 9 "fmt" 10 "runtime" 11 12 "github.com/gcla/gowid" 13) 14 15//====================================================================== 16 17var ( 18 HorizontalLine = '━' 19 AltHorizontalLine = '▀' 20) 21 22func init() { 23 switch runtime.GOOS { 24 case "windows": 25 HorizontalLine = '─' 26 AltHorizontalLine = HorizontalLine 27 case "darwin": 28 AltHorizontalLine = HorizontalLine 29 } 30} 31 32type IDivider interface { 33 Opts() Options 34} 35 36type IWidget interface { 37 gowid.IWidget 38 IDivider 39} 40 41type Widget struct { 42 opts Options 43 gowid.RejectUserInput 44 gowid.NotSelectable 45} 46 47type Options struct { 48 Chr rune 49 Above, Below int 50} 51 52func New(opts ...Options) *Widget { 53 var opt Options 54 if len(opts) == 0 { 55 opt = Options{ 56 Chr: '-', 57 } 58 } else { 59 opt = opts[0] 60 } 61 res := &Widget{ 62 opts: opt, 63 } 64 var _ IWidget = res 65 return res 66} 67 68func NewAscii() *Widget { 69 return New(Options{ 70 Chr: '-', 71 }) 72} 73 74func NewBlank() *Widget { 75 return New(Options{ 76 Chr: ' ', 77 }) 78} 79 80func NewUnicode() *Widget { 81 return New(Options{ 82 Chr: HorizontalLine, 83 }) 84} 85 86func NewUnicodeAlt() *Widget { 87 return New(Options{ 88 Chr: AltHorizontalLine, 89 }) 90} 91 92func (w *Widget) String() string { 93 return fmt.Sprintf("div[%c]", w.Opts().Chr) 94} 95 96func (w *Widget) Opts() Options { 97 return w.opts 98} 99 100func (w *Widget) RenderSize(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderBox { 101 return RenderSize(w, size, focus, app) 102} 103 104func (w *Widget) Render(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.ICanvas { 105 return Render(w, size, focus, app) 106} 107 108//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 109 110func RenderSize(w IDivider, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderBox { 111 if flow, ok := size.(gowid.IRenderFlowWith); !ok { 112 panic(gowid.WidgetSizeError{Widget: w, Size: size, Required: "gowid.IRenderFlowWith"}) 113 } else { 114 return gowid.RenderBox{C: flow.FlowColumns(), R: w.Opts().Above + w.Opts().Below + 1} 115 } 116} 117 118func Render(w IDivider, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.ICanvas { 119 flow, ok := size.(gowid.IRenderFlowWith) 120 if !ok { 121 panic(gowid.WidgetSizeError{Widget: w, Size: size, Required: "gowid.IRenderFlowWith"}) 122 } 123 124 div := gowid.CellFromRune(w.Opts().Chr) 125 divArr := make([]gowid.Cell, flow.FlowColumns()) 126 for i := 0; i < flow.FlowColumns(); i++ { 127 divArr[i] = div 128 } 129 130 res := gowid.NewCanvas() 131 for i := 0; i < w.Opts().Above; i++ { 132 res.AppendLine([]gowid.Cell{}, false) 133 } 134 res.AppendLine(divArr, false) 135 for i := 0; i < w.Opts().Below; i++ { 136 res.AppendLine([]gowid.Cell{}, false) 137 } 138 res.AlignRight() 139 140 return res 141} 142 143//====================================================================== 144// Local Variables: 145// mode: Go 146// fill-column: 110 147// End: 148