1 // Copyright 2022 The TCell Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use file except in compliance with the License. 5 // You may obtain a copy of the license at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tcell 16 17 // Style represents a complete text style, including both foreground color, 18 // background color, and additional attributes such as "bold" or "underline". 19 // 20 // Note that not all terminals can display all colors or attributes, and 21 // many might have specific incompatibilities between specific attributes 22 // and color combinations. 23 // 24 // To use Style, just declare a variable of its type. 25 type Style struct { 26 fg Color 27 bg Color 28 attrs AttrMask 29 url string 30 urlId string 31 } 32 33 // StyleDefault represents a default style, based upon the context. 34 // It is the zero value. 35 var StyleDefault Style 36 37 // styleInvalid is just an arbitrary invalid style used internally. 38 var styleInvalid = Style{attrs: AttrInvalid} 39 40 // Foreground returns a new style based on s, with the foreground color set 41 // as requested. ColorDefault can be used to select the global default. 42 func (s Style) Foreground(c Color) Style { 43 return Style{ 44 fg: c, 45 bg: s.bg, 46 attrs: s.attrs, 47 url: s.url, 48 urlId: s.urlId, 49 } 50 } 51 52 // Background returns a new style based on s, with the background color set 53 // as requested. ColorDefault can be used to select the global default. 54 func (s Style) Background(c Color) Style { 55 return Style{ 56 fg: s.fg, 57 bg: c, 58 attrs: s.attrs, 59 url: s.url, 60 urlId: s.urlId, 61 } 62 } 63 64 // Decompose breaks a style up, returning the foreground, background, 65 // and other attributes. The URL if set is not included. 66 func (s Style) Decompose() (fg Color, bg Color, attr AttrMask) { 67 return s.fg, s.bg, s.attrs 68 } 69 70 func (s Style) setAttrs(attrs AttrMask, on bool) Style { 71 if on { 72 return Style{ 73 fg: s.fg, 74 bg: s.bg, 75 attrs: s.attrs | attrs, 76 url: s.url, 77 urlId: s.urlId, 78 } 79 } 80 return Style{ 81 fg: s.fg, 82 bg: s.bg, 83 attrs: s.attrs &^ attrs, 84 url: s.url, 85 urlId: s.urlId, 86 } 87 } 88 89 // Normal returns the style with all attributes disabled. 90 func (s Style) Normal() Style { 91 return Style{ 92 fg: s.fg, 93 bg: s.bg, 94 } 95 } 96 97 // Bold returns a new style based on s, with the bold attribute set 98 // as requested. 99 func (s Style) Bold(on bool) Style { 100 return s.setAttrs(AttrBold, on) 101 } 102 103 // Blink returns a new style based on s, with the blink attribute set 104 // as requested. 105 func (s Style) Blink(on bool) Style { 106 return s.setAttrs(AttrBlink, on) 107 } 108 109 // Dim returns a new style based on s, with the dim attribute set 110 // as requested. 111 func (s Style) Dim(on bool) Style { 112 return s.setAttrs(AttrDim, on) 113 } 114 115 // Italic returns a new style based on s, with the italic attribute set 116 // as requested. 117 func (s Style) Italic(on bool) Style { 118 return s.setAttrs(AttrItalic, on) 119 } 120 121 // Reverse returns a new style based on s, with the reverse attribute set 122 // as requested. (Reverse usually changes the foreground and background 123 // colors.) 124 func (s Style) Reverse(on bool) Style { 125 return s.setAttrs(AttrReverse, on) 126 } 127 128 // Underline returns a new style based on s, with the underline attribute set 129 // as requested. 130 func (s Style) Underline(on bool) Style { 131 return s.setAttrs(AttrUnderline, on) 132 } 133 134 // StrikeThrough sets strikethrough mode. 135 func (s Style) StrikeThrough(on bool) Style { 136 return s.setAttrs(AttrStrikeThrough, on) 137 } 138 139 // Attributes returns a new style based on s, with its attributes set as 140 // specified. 141 func (s Style) Attributes(attrs AttrMask) Style { 142 return Style{ 143 fg: s.fg, 144 bg: s.bg, 145 attrs: attrs, 146 url: s.url, 147 urlId: s.urlId, 148 } 149 } 150 151 // Url returns a style with the Url set. If the provided Url is not empty, 152 // and the terminal supports it, text will typically be marked up as a clickable 153 // link to that Url. If the Url is empty, then this mode is turned off. 154 func (s Style) Url(url string) Style { 155 return Style{ 156 fg: s.fg, 157 bg: s.bg, 158 attrs: s.attrs, 159 url: url, 160 urlId: s.urlId, 161 } 162 } 163 164 // UrlId returns a style with the UrlId set. If the provided UrlId is not empty, 165 // any marked up Url with this style will be given the UrlId also. If the 166 // terminal supports it, any text with the same UrlId will be grouped as if it 167 // were one Url, even if it spans multiple lines. 168 func (s Style) UrlId(id string) Style { 169 return Style{ 170 fg: s.fg, 171 bg: s.bg, 172 attrs: s.attrs, 173 url: s.url, 174 urlId: "id=" + id, 175 } 176 } 177