label.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package gui
  5. import (
  6. "github.com/g3n/engine/gls"
  7. "github.com/g3n/engine/math32"
  8. "github.com/g3n/engine/text"
  9. "github.com/g3n/engine/texture"
  10. "github.com/g3n/engine/window"
  11. )
  12. // Label is a panel which contains a texture with text.
  13. // The content size of the label panel is the exact size of the texture.
  14. type Label struct {
  15. Panel // Embedded Panel
  16. font *text.Font // TrueType font face
  17. tex *texture.Texture2D // Texture with text
  18. style *LabelStyle // The style of the panel and font attributes
  19. text string // Text being displayed
  20. }
  21. // LabelStyle contains all the styling attributes of a Label.
  22. // It's essentially a BasicStyle combined with FontAttributes.
  23. type LabelStyle struct {
  24. PanelStyle
  25. text.FontAttributes
  26. FgColor math32.Color4
  27. }
  28. // NewLabel creates and returns a label panel with
  29. // the specified text drawn using the default text font.
  30. func NewLabel(text string) *Label {
  31. return NewLabelWithFont(text, StyleDefault().Font)
  32. }
  33. // NewIcon creates and returns a label panel with
  34. // the specified text drawn using the default icon font.
  35. func NewIcon(icon string) *Label {
  36. return NewLabelWithFont(icon, StyleDefault().FontIcon)
  37. }
  38. // NewLabelWithFont creates and returns a label panel with
  39. // the specified text drawn using the specified font.
  40. func NewLabelWithFont(msg string, font *text.Font) *Label {
  41. l := new(Label)
  42. l.initialize(msg, font)
  43. return l
  44. }
  45. // initialize initializes this label and is normally used by other
  46. // components which contain a label.
  47. func (l *Label) initialize(msg string, font *text.Font) {
  48. l.font = font
  49. l.Panel.Initialize(l, 0, 0)
  50. l.Panel.mat.SetTransparent(true)
  51. // TODO: Remove this hack in an elegant way e.g. set the label style depending of if it's an icon or text label and have two defaults (one for icon labels one for text tabels)
  52. if font != StyleDefault().FontIcon {
  53. l.Panel.SetPaddings(2, 0, 2, 0)
  54. }
  55. // Copy the style based on the default Label style
  56. styleCopy := StyleDefault().Label
  57. l.style = &styleCopy
  58. l.SetText(msg)
  59. }
  60. // SetText sets and draws the label text using the font.
  61. func (l *Label) SetText(text string) {
  62. // Need at least a character to get dimensions
  63. l.text = text
  64. if text == "" {
  65. text = " "
  66. }
  67. // Set font properties
  68. l.font.SetAttributes(&l.style.FontAttributes)
  69. l.font.SetColor(&l.style.FgColor)
  70. scaleX, scaleY := window.Get().GetScale()
  71. l.font.SetScaleXY(scaleX, scaleY)
  72. // Create an image with the text
  73. textImage := l.font.DrawText(text)
  74. // Create texture if it doesn't exist yet
  75. if l.tex == nil {
  76. l.tex = texture.NewTexture2DFromRGBA(textImage)
  77. l.tex.SetMagFilter(gls.NEAREST)
  78. l.tex.SetMinFilter(gls.NEAREST)
  79. l.Panel.Material().AddTexture(l.tex)
  80. // Otherwise update texture with new image
  81. } else {
  82. l.tex.SetFromRGBA(textImage)
  83. }
  84. // Update label panel dimensions
  85. width, height := float32(textImage.Rect.Dx()), float32(textImage.Rect.Dy())
  86. // since we enlarged the font texture for higher quality, we have to scale it back to it's original point size
  87. width, height = width / float32(scaleX), height / float32(scaleY)
  88. l.Panel.SetContentSize(width, height)
  89. }
  90. // Text returns the label text.
  91. func (l *Label) Text() string {
  92. return l.text
  93. }
  94. // SetColor sets the text color.
  95. // Alpha is set to 1 (opaque).
  96. func (l *Label) SetColor(color *math32.Color) *Label {
  97. l.style.FgColor.FromColor(color, 1.0)
  98. l.SetText(l.text)
  99. return l
  100. }
  101. // SetColor4 sets the text color.
  102. func (l *Label) SetColor4(color4 *math32.Color4) *Label {
  103. l.style.FgColor = *color4
  104. l.SetText(l.text)
  105. return l
  106. }
  107. // Color returns the text color.
  108. func (l *Label) Color() math32.Color4 {
  109. return l.style.FgColor
  110. }
  111. // SetBgColor sets the background color.
  112. // The color alpha is set to 1.0
  113. func (l *Label) SetBgColor(color *math32.Color) *Label {
  114. l.style.BgColor.FromColor(color, 1.0)
  115. l.Panel.SetColor4(&l.style.BgColor)
  116. l.SetText(l.text)
  117. return l
  118. }
  119. // SetBgColor4 sets the background color.
  120. func (l *Label) SetBgColor4(color *math32.Color4) *Label {
  121. l.style.BgColor = *color
  122. l.Panel.SetColor4(&l.style.BgColor)
  123. l.SetText(l.text)
  124. return l
  125. }
  126. // BgColor returns returns the background color.
  127. func (l *Label) BgColor() math32.Color4 {
  128. return l.style.BgColor
  129. }
  130. // SetFont sets the font.
  131. func (l *Label) SetFont(f *text.Font) {
  132. l.font = f
  133. l.SetText(l.text)
  134. }
  135. // Font returns the font.
  136. func (l *Label) Font() *text.Font {
  137. return l.font
  138. }
  139. // SetFontSize sets the point size of the font.
  140. func (l *Label) SetFontSize(size float64) *Label {
  141. l.style.PointSize = size
  142. l.SetText(l.text)
  143. return l
  144. }
  145. // FontSize returns the point size of the font.
  146. func (l *Label) FontSize() float64 {
  147. return l.style.PointSize
  148. }
  149. // SetFontDPI sets the resolution of the font in dots per inch (DPI).
  150. func (l *Label) SetFontDPI(dpi float64) *Label {
  151. l.style.DPI = dpi
  152. l.SetText(l.text)
  153. return l
  154. }
  155. // FontDPI returns the resolution of the font in dots per inch (DPI).
  156. func (l *Label) FontDPI() float64 {
  157. return l.style.DPI
  158. }
  159. // SetLineSpacing sets the spacing between lines.
  160. func (l *Label) SetLineSpacing(spacing float64) *Label {
  161. l.style.LineSpacing = spacing
  162. l.SetText(l.text)
  163. return l
  164. }
  165. // LineSpacing returns the spacing between lines.
  166. func (l *Label) LineSpacing() float64 {
  167. return l.style.LineSpacing
  168. }
  169. // setTextCaret sets the label text and draws a caret at the
  170. // specified line and column.
  171. // It is normally used by the Edit widget.
  172. func (l *Label) setTextCaret(msg string, mx, width int, drawCaret bool, line, col, selStart, selEnd int) {
  173. // Set font properties
  174. l.font.SetAttributes(&l.style.FontAttributes)
  175. l.font.SetColor(&l.style.FgColor)
  176. scaleX, scaleY := window.Get().GetScale()
  177. l.font.SetScaleXY(scaleX, scaleY)
  178. // Create canvas and draw text
  179. _, height := l.font.MeasureText(msg)
  180. canvas := text.NewCanvas(width, height, &l.style.BgColor)
  181. canvas.DrawTextCaret(mx, 0, msg, l.font, drawCaret, line, col, selStart, selEnd)
  182. // Creates texture if if doesnt exist.
  183. if l.tex == nil {
  184. l.tex = texture.NewTexture2DFromRGBA(canvas.RGBA)
  185. l.Panel.Material().AddTexture(l.tex)
  186. // Otherwise update texture with new image
  187. } else {
  188. l.tex.SetFromRGBA(canvas.RGBA)
  189. }
  190. // Set texture filtering parameters for text
  191. l.tex.SetMagFilter(gls.NEAREST)
  192. l.tex.SetMinFilter(gls.NEAREST)
  193. // Updates label panel dimensions
  194. l.Panel.SetContentSize(float32(width) / float32(scaleX), float32(height) / float32(scaleY))
  195. l.text = msg
  196. }