1 /* 2 Package tview implements rich widgets for terminal based user interfaces. The 3 widgets provided with this package are useful for data exploration and data 4 entry. 5 6 # Widgets 7 8 The package implements the following widgets: 9 10 - [TextView]: A scrollable window that display multi-colored text. Text may 11 also be highlighted. 12 - [TextArea]: An editable multi-line text area. 13 - [Table]: A scrollable display of tabular data. Table cells, rows, or columns 14 may also be highlighted. 15 - [TreeView]: A scrollable display for hierarchical data. Tree nodes can be 16 highlighted, collapsed, expanded, and more. 17 - [List]: A navigable text list with optional keyboard shortcuts. 18 - [InputField]: One-line input fields to enter text. 19 - [DropDown]: Drop-down selection fields. 20 - [Checkbox]: Selectable checkbox for boolean values. 21 - [Image]: Displays images. 22 - [Button]: Buttons which get activated when the user selects them. 23 - [Form]: Forms composed of input fields, drop down selections, checkboxes, 24 and buttons. 25 - [Modal]: A centered window with a text message and one or more buttons. 26 - [Grid]: A grid based layout manager. 27 - [Flex]: A Flexbox based layout manager. 28 - [Pages]: A page based layout manager. 29 30 The package also provides Application which is used to poll the event queue and 31 draw widgets on screen. 32 33 # Hello World 34 35 The following is a very basic example showing a box with the title "Hello, 36 world!": 37 38 package main 39 40 import ( 41 "github.com/rivo/tview" 42 ) 43 44 func main() { 45 box := tview.NewBox().SetBorder(true).SetTitle("Hello, world!") 46 if err := tview.NewApplication().SetRoot(box, true).Run(); err != nil { 47 panic(err) 48 } 49 } 50 51 First, we create a box primitive with a border and a title. Then we create an 52 application, set the box as its root primitive, and run the event loop. The 53 application exits when the application's [Application.Stop] function is called 54 or when Ctrl-C is pressed. 55 56 If we have a primitive which consumes key presses, we call the application's 57 [Application.SetFocus] function to redirect all key presses to that primitive. 58 Most primitives then offer ways to install handlers that allow you to react to 59 any actions performed on them. 60 61 # More Demos 62 63 You will find more demos in the "demos" subdirectory. It also contains a 64 presentation (written using tview) which gives an overview of the different 65 widgets and how they can be used. 66 67 # Colors 68 69 Throughout this package, colors are specified using the [tcell.Color] type. 70 Functions such as [tcell.GetColor], [tcell.NewHexColor], and [tcell.NewRGBColor] 71 can be used to create colors from W3C color names or RGB values. 72 73 Almost all strings which are displayed can contain color tags. Color tags are 74 W3C color names or six hexadecimal digits following a hash tag, wrapped in 75 square brackets. Examples: 76 77 This is a [red]warning[white]! 78 The sky is [#8080ff]blue[#ffffff]. 79 80 A color tag changes the color of the characters following that color tag. This 81 applies to almost everything from box titles, list text, form item labels, to 82 table cells. In a TextView, this functionality has to be switched on explicitly. 83 See the TextView documentation for more information. 84 85 Color tags may contain not just the foreground (text) color but also the 86 background color and additional flags. In fact, the full definition of a color 87 tag is as follows: 88 89 [<foreground>:<background>:<flags>] 90 91 Each of the three fields can be left blank and trailing fields can be omitted. 92 (Empty square brackets "[]", however, are not considered color tags.) Colors 93 that are not specified will be left unchanged. A field with just a dash ("-") 94 means "reset to default". 95 96 You can specify the following flags (some flags may not be supported by your 97 terminal): 98 99 l: blink 100 b: bold 101 i: italic 102 d: dim 103 r: reverse (switch foreground and background color) 104 u: underline 105 s: strike-through 106 107 Examples: 108 109 [yellow]Yellow text 110 [yellow:red]Yellow text on red background 111 [:red]Red background, text color unchanged 112 [yellow::u]Yellow text underlined 113 [::bl]Bold, blinking text 114 [::-]Colors unchanged, flags reset 115 [-]Reset foreground color 116 [-:-:-]Reset everything 117 [:]No effect 118 []Not a valid color tag, will print square brackets as they are 119 120 In the rare event that you want to display a string such as "[red]" or 121 "[#00ff1a]" without applying its effect, you need to put an opening square 122 bracket before the closing square bracket. Note that the text inside the 123 brackets will be matched less strictly than region or colors tags. I.e. any 124 character that may be used in color or region tags will be recognized. Examples: 125 126 [red[] will be output as [red] 127 ["123"[] will be output as ["123"] 128 [#6aff00[[] will be output as [#6aff00[] 129 [a#"[[[] will be output as [a#"[[] 130 [] will be output as [] (see color tags above) 131 [[] will be output as [[] (not an escaped tag) 132 133 You can use the Escape() function to insert brackets automatically where needed. 134 135 # Styles 136 137 When primitives are instantiated, they are initialized with colors taken from 138 the global Styles variable. You may change this variable to adapt the look and 139 feel of the primitives to your preferred style. 140 141 # Unicode Support 142 143 This package supports unicode characters including wide characters. 144 145 # Concurrency 146 147 Many functions in this package are not thread-safe. For many applications, this 148 may not be an issue: If your code makes changes in response to key events, it 149 will execute in the main goroutine and thus will not cause any race conditions. 150 151 If you access your primitives from other goroutines, however, you will need to 152 synchronize execution. The easiest way to do this is to call 153 [Application.QueueUpdate] or [Application.QueueUpdateDraw] (see the function 154 documentation for details): 155 156 go func() { 157 app.QueueUpdateDraw(func() { 158 table.SetCellSimple(0, 0, "Foo bar") 159 }) 160 }() 161 162 One exception to this is the io.Writer interface implemented by [TextView]. You 163 can safely write to a [TextView] from any goroutine. See the [TextView] 164 documentation for details. 165 166 You can also call [Application.Draw] from any goroutine without having to wrap 167 it in [Application.QueueUpdate]. And, as mentioned above, key event callbacks 168 are executed in the main goroutine and thus should not use 169 [Application.QueueUpdate] as that may lead to deadlocks. 170 171 # Type Hierarchy 172 173 All widgets listed above contain the [Box] type. All of [Box]'s functions are 174 therefore available for all widgets, too. Please note that if you are using the 175 functions of [Box] on a subclass, they will return a *Box, not the subclass. So 176 while tview supports method chaining in many places, these chains must be broken 177 when using [Box]'s functions. Example: 178 179 // This will cause "textArea" to be an empty Box. 180 textArea := tview.NewTextArea(). 181 SetMaxLength(256). 182 SetPlaceholder("Enter text here"). 183 SetBorder(true) 184 185 You will need to call [Box.SetBorder] separately: 186 187 textArea := tview.NewTextArea(). 188 SetMaxLength(256). 189 SetPlaceholder("Enter text here") 190 texArea.SetBorder(true) 191 192 All widgets also implement the [Primitive] interface. 193 194 The tview package is based on https://github.com/gdamore/tcell. It uses types 195 and constants from that package (e.g. colors and keyboard values). 196 */ 197 package tview 198