1 module evael.graphics.gui.controls.TextBlock; 2 3 import evael.graphics.gui.controls.Control; 4 import evael.graphics.Font; 5 6 import evael.utils.Math; 7 import evael.utils.Size; 8 import evael.utils.Color; 9 10 class TextBlock : Control 11 { 12 enum Type 13 { 14 FixedSize, 15 DynamicSize 16 } 17 18 enum TextAlignement 19 { 20 Center = (1u << 0), // Vertical align 21 Middle = (1u << 1), // Horizontal align 22 Top = (1u << 2), 23 Left = (1u << 3), 24 Bottom = (1u << 4), 25 Right = (1u << 5) 26 } 27 28 /// Textblock text 29 private wstring m_text; 30 31 /// Text position 32 private vec2 m_textPosition; 33 34 /// Text color 35 private Color m_color; 36 37 /// Text alignement 38 private TextAlignement m_textAlignement; 39 40 private int m_nvgTextAlignement; 41 42 /// Type 43 private Type m_type; 44 45 /// Indicates if textblock use theme color or custom color 46 private bool m_useThemeColor; 47 48 public this()(in auto ref vec2 position, in auto ref Size!int size) 49 { 50 super(position, size); 51 52 this.m_name = "textBlock"; 53 this.m_color = Color.Black; 54 55 this.m_textAlignement = TextAlignement.Center | TextAlignement.Middle; 56 this.m_type = Type.DynamicSize; 57 58 this.m_useThemeColor = true; 59 } 60 61 public this(in float x = 0, in float y = 0) 62 { 63 this(vec2(x, y), Size!int(0, 0)); 64 } 65 66 public this(in float x, in float y, in int width, in int height) 67 { 68 this(vec2(x, y), Size!int(width, height)); 69 70 this.m_type = Type.FixedSize; 71 } 72 73 public override void draw(in float deltaTime) 74 { 75 if (!this.m_isVisible) 76 return; 77 78 super.draw(deltaTime); 79 80 auto color = this.m_useThemeColor ? this.m_theme.fontColor : this.m_color; 81 82 this.m_theme.font.draw(this.m_text, vec2(this.m_realPosition.x, this.m_realPosition.y) + this.m_textPosition, 83 color, this.m_theme.fontSize, this.m_theme.drawTextShadow, this.m_nvgTextAlignement ); 84 } 85 86 /** 87 */ 88 public override void initialize() 89 { 90 super.initialize(); 91 92 if(this.m_text.length) 93 { 94 this.text = this.m_text; 95 } 96 } 97 98 @property 99 public override void opacity(in ubyte value) @nogc 100 { 101 super.opacity = value; 102 103 if(!this.m_useThemeColor) 104 { 105 this.m_color.a = value; 106 } 107 } 108 109 @property 110 { 111 public wstring text() const nothrow @nogc 112 { 113 return this.m_text; 114 } 115 116 117 public void text(in string value) 118 { 119 import std.conv; 120 121 this.text = value.to!wstring(); 122 } 123 124 public void text(in wstring value) 125 { 126 this.m_text = value; 127 128 if(this.m_theme !is null && this.m_theme.font !is null) 129 { 130 if(this.m_type == Type.DynamicSize) 131 { 132 float[4] bounds = this.m_theme.font.getTextBounds(this.m_text, 0, this.m_theme.fontSize); 133 134 immutable float w = bounds[2] - bounds[0]; 135 immutable float h = bounds[3] - bounds[1]; 136 137 this.m_size.width = cast(int)w + 10; 138 this.m_size.height = cast(int)h + 5; 139 140 this.m_textPosition.x = this.m_size.halfWidth; 141 this.m_textPosition.y = this.m_size.halfHeight; 142 this.m_nvgTextAlignement = NVGalign.NVG_ALIGN_CENTER | NVGalign.NVG_ALIGN_MIDDLE; 143 } 144 else if(this.m_type == Type.FixedSize) 145 { 146 this.m_nvgTextAlignement = 0; 147 148 /** 149 * Vertical alignement 150 */ 151 if(this.m_textAlignement & TextAlignement.Center) 152 { 153 this.m_textPosition.y = this.m_size.halfHeight; 154 this.m_nvgTextAlignement = NVGalign.NVG_ALIGN_CENTER; 155 } 156 157 if(this.m_textAlignement & TextAlignement.Bottom) 158 { 159 this.m_textPosition.y = this.m_size.height; 160 this.m_nvgTextAlignement += NVGalign.NVG_ALIGN_BOTTOM; 161 } 162 163 if(this.m_textAlignement & TextAlignement.Top) 164 { 165 this.m_textPosition.y = 0; 166 this.m_nvgTextAlignement += NVGalign.NVG_ALIGN_TOP; 167 } 168 169 /** 170 * Horizontal alignement 171 */ 172 if(this.m_textAlignement & TextAlignement.Middle) 173 { 174 this.m_textPosition.x = this.m_size.halfWidth; 175 this.m_nvgTextAlignement += NVGalign.NVG_ALIGN_MIDDLE; 176 } 177 178 if(this.m_textAlignement & TextAlignement.Left) 179 { 180 this.m_textPosition.x = 0; 181 this.m_nvgTextAlignement += NVGalign.NVG_ALIGN_LEFT; 182 } 183 184 if(this.m_textAlignement & TextAlignement.Right) 185 { 186 this.m_textPosition.x = this.m_size.width; 187 this.m_nvgTextAlignement += NVGalign.NVG_ALIGN_RIGHT; 188 } 189 } 190 else 191 { 192 /*wstring realText; 193 194 int i, j; 195 196 // We try to cut the text in multiple lines 197 if(this.m_theme.font.getTextWidth(value) > this.m_size.width - this.m_position.x) 198 { 199 while(j < value.length) 200 { 201 j++; 202 203 if(this.m_theme.font.getTextWidth(value[i..j]) >= (this.m_size.width - this.m_position.x - 3)) 204 { 205 realText = realText ~ value[i..j] ~ '\n'; 206 i = j; 207 } 208 } 209 210 realText ~= value[i..j]; 211 } 212 else realText = value; 213 214 this.m_text = realText;*/ 215 } 216 } 217 } 218 219 public void color(in Color value) nothrow @nogc 220 { 221 this.m_color = value; 222 this.m_useThemeColor = false; 223 } 224 225 public void textAlignement(in TextAlignement value) nothrow @nogc 226 { 227 this.m_textAlignement = value; 228 } 229 } 230 }