nt

A sensible note-taking program
git clone git://git.laack.co/nt.git
Log | Files | Refs | README

style.go (5466B)


      1 // Copyright 2024 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 	ulStyle UnderlineStyle
     29 	ulColor Color
     30 	attrs   AttrMask
     31 	url     string
     32 	urlId   string
     33 }
     34 
     35 // StyleDefault represents a default style, based upon the context.
     36 // It is the zero value.
     37 var StyleDefault Style
     38 
     39 // styleInvalid is just an arbitrary invalid style used internally.
     40 var styleInvalid = Style{attrs: AttrInvalid}
     41 
     42 // Foreground returns a new style based on s, with the foreground color set
     43 // as requested.  ColorDefault can be used to select the global default.
     44 func (s Style) Foreground(c Color) Style {
     45 	s2 := s
     46 	s2.fg = c
     47 	return s2
     48 }
     49 
     50 // Background returns a new style based on s, with the background color set
     51 // as requested.  ColorDefault can be used to select the global default.
     52 func (s Style) Background(c Color) Style {
     53 	s2 := s
     54 	s2.bg = c
     55 	return s2
     56 }
     57 
     58 // Decompose breaks a style up, returning the foreground, background,
     59 // and other attributes.  The URL if set is not included.
     60 // Deprecated: Applications should not attempt to decompose style,
     61 // as this content is not sufficient to describe the actual style.
     62 func (s Style) Decompose() (fg Color, bg Color, attr AttrMask) {
     63 	return s.fg, s.bg, s.attrs
     64 }
     65 
     66 func (s Style) setAttrs(attrs AttrMask, on bool) Style {
     67 	s2 := s
     68 	if on {
     69 		s2.attrs |= attrs
     70 	} else {
     71 		s2.attrs &^= attrs
     72 	}
     73 	return s2
     74 }
     75 
     76 // Normal returns the style with all attributes disabled.
     77 func (s Style) Normal() Style {
     78 	return Style{
     79 		fg: s.fg,
     80 		bg: s.bg,
     81 	}
     82 }
     83 
     84 // Bold returns a new style based on s, with the bold attribute set
     85 // as requested.
     86 func (s Style) Bold(on bool) Style {
     87 	return s.setAttrs(AttrBold, on)
     88 }
     89 
     90 // Blink returns a new style based on s, with the blink attribute set
     91 // as requested.
     92 func (s Style) Blink(on bool) Style {
     93 	return s.setAttrs(AttrBlink, on)
     94 }
     95 
     96 // Dim returns a new style based on s, with the dim attribute set
     97 // as requested.
     98 func (s Style) Dim(on bool) Style {
     99 	return s.setAttrs(AttrDim, on)
    100 }
    101 
    102 // Italic returns a new style based on s, with the italic attribute set
    103 // as requested.
    104 func (s Style) Italic(on bool) Style {
    105 	return s.setAttrs(AttrItalic, on)
    106 }
    107 
    108 // Reverse returns a new style based on s, with the reverse attribute set
    109 // as requested.  (Reverse usually changes the foreground and background
    110 // colors.)
    111 func (s Style) Reverse(on bool) Style {
    112 	return s.setAttrs(AttrReverse, on)
    113 }
    114 
    115 // StrikeThrough sets strikethrough mode.
    116 func (s Style) StrikeThrough(on bool) Style {
    117 	return s.setAttrs(AttrStrikeThrough, on)
    118 }
    119 
    120 // Underline style.  Modern terminals have the option of rendering the
    121 // underline using different styles, and even different colors.
    122 type UnderlineStyle int
    123 
    124 const (
    125 	UnderlineStyleNone = UnderlineStyle(iota)
    126 	UnderlineStyleSolid
    127 	UnderlineStyleDouble
    128 	UnderlineStyleCurly
    129 	UnderlineStyleDotted
    130 	UnderlineStyleDashed
    131 )
    132 
    133 // Underline returns a new style based on s, with the underline attribute set
    134 // as requested.  The parameters can be:
    135 //
    136 // bool: on / off - enables just a simple underline
    137 // UnderlineStyle: sets a specific style (should not coexist with the bool)
    138 // Color: the color to use
    139 func (s Style) Underline(params ...interface{}) Style {
    140 	s2 := s
    141 	for _, param := range params {
    142 		switch v := param.(type) {
    143 		case bool:
    144 			if v {
    145 				s2.ulStyle = UnderlineStyleSolid
    146 				s2.attrs |= AttrUnderline
    147 			} else {
    148 				s2.ulStyle = UnderlineStyleNone
    149 				s2.attrs &^= AttrUnderline
    150 			}
    151 		case UnderlineStyle:
    152 			if v == UnderlineStyleNone {
    153 				s2.attrs &^= AttrUnderline
    154 			} else {
    155 				s2.attrs |= AttrUnderline
    156 			}
    157 			s2.ulStyle = v
    158 		case Color:
    159 			s2.ulColor = v
    160 		default:
    161 			panic("Bad type for underline")
    162 		}
    163 	}
    164 	return s2
    165 }
    166 
    167 // Attributes returns a new style based on s, with its attributes set as
    168 // specified.
    169 func (s Style) Attributes(attrs AttrMask) Style {
    170 	s2 := s
    171 	s2.attrs = attrs
    172 	return s2
    173 }
    174 
    175 // Url returns a style with the Url set.  If the provided Url is not empty,
    176 // and the terminal supports it, text will typically be marked up as a clickable
    177 // link to that Url.  If the Url is empty, then this mode is turned off.
    178 func (s Style) Url(url string) Style {
    179 	s2 := s
    180 	s2.url = url
    181 	return s2
    182 }
    183 
    184 // UrlId returns a style with the UrlId set. If the provided UrlId is not empty,
    185 // any marked up Url with this style will be given the UrlId also. If the
    186 // terminal supports it, any text with the same UrlId will be grouped as if it
    187 // were one Url, even if it spans multiple lines.
    188 func (s Style) UrlId(id string) Style {
    189 	s2 := s
    190 	s2.urlId = "id=" + id
    191 	return s2
    192 }