1 /** 2 * Copyright: Copyright Auburn Sounds 2015 and later. 3 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 4 * Authors: Guillaume Piolat 5 */ 6 module dplug.gui.label; 7 8 import std.math; 9 import dplug.gui.element; 10 import dplug.client.params; 11 12 /// Simple area with text. 13 class UILabel : UIElement 14 { 15 public: 16 nothrow: 17 @nogc: 18 19 /// Sets to true if this is clickable 20 bool clickable = false; 21 string targetURL = "http://example.com"; 22 23 this(UIContext context, Font font, string text = "") 24 { 25 super(context); 26 _text = text; 27 _font = font; 28 } 29 30 /// Returns: Font used. 31 Font font() 32 { 33 return _font; 34 } 35 36 /// Sets text size. 37 Font font(Font font_) 38 { 39 setDirtyWhole(); 40 return _font = font_; 41 } 42 43 /// Returns: Displayed text. 44 string text() 45 { 46 return _text; 47 } 48 49 /// Sets displayed text. 50 string text(string text_) 51 { 52 setDirtyWhole(); 53 return _text = text_; 54 } 55 56 /// Returns: Size of displayed text. 57 float textSize() 58 { 59 return _textSize; 60 } 61 62 /// Sets size of displayed text. 63 float textSize(float textSize_) 64 { 65 setDirtyWhole(); 66 return _textSize = textSize_; 67 } 68 69 float letterSpacing() 70 { 71 return _letterSpacing; 72 } 73 74 float letterSpacing(float letterSpacing_) 75 { 76 setDirtyWhole(); 77 return _letterSpacing = letterSpacing_; 78 } 79 80 /// Returns: Diffuse color of displayed text. 81 RGBA textColor() 82 { 83 return _textColor; 84 } 85 86 /// Sets diffuse color of displayed text. 87 RGBA textColor(RGBA textColor_) 88 { 89 setDirtyWhole(); 90 return _textColor = textColor_; 91 } 92 93 override void onBeginDrag() 94 { 95 if (clickable) 96 setDirtyWhole(); 97 } 98 99 override void onStopDrag() 100 { 101 if (clickable) 102 setDirtyWhole(); 103 } 104 105 override void onMouseEnter() 106 { 107 if (clickable) 108 setDirtyWhole(); 109 } 110 111 override void onMouseExit() 112 { 113 if (clickable) 114 setDirtyWhole(); 115 } 116 117 override bool onMouseClick(int x, int y, int button, bool isDoubleClick, MouseState mstate) 118 { 119 if (clickable) 120 { 121 browseNoGC(targetURL); 122 return true; 123 } 124 return false; 125 } 126 127 override void onDraw(ImageRef!RGBA diffuseMap, ImageRef!L16 depthMap, ImageRef!RGBA materialMap, box2i[] dirtyRects) nothrow @nogc 128 { 129 float textPosx = position.width * 0.5f; 130 float textPosy = position.height * 0.5f; 131 // only draw text which is in dirty areas 132 133 RGBA diffuse = _textColor; 134 int emissive = _textColor.a; 135 bool underline = false; 136 137 if (clickable && isMouseOver) 138 { 139 emissive += 40; 140 underline = true; 141 } 142 else if (clickable && isDragged) 143 { 144 emissive += 80; 145 underline = true; 146 } 147 if (emissive > 255) 148 emissive = 255; 149 diffuse.a = cast(ubyte)(emissive); 150 151 // MAYDO: implement underline? 152 153 foreach(dirtyRect; dirtyRects) 154 { 155 auto croppedDiffuse = diffuseMap.cropImageRef(dirtyRect); 156 vec2f positionInDirty = vec2f(textPosx, textPosy) - dirtyRect.min; 157 croppedDiffuse.fillText(_font, _text, _textSize, _letterSpacing, diffuse, positionInDirty.x, positionInDirty.y); 158 } 159 } 160 161 // Sets _position and resize automatically to adjust with text size and content. 162 void setCenterAndResize(int x, int y) nothrow @nogc 163 { 164 box2i textDimensions = _font.measureText(_text, _textSize, _letterSpacing); 165 int bx = x - textDimensions.width/2 - 1; 166 int by = y - textDimensions.height/2 - 1; 167 int w = textDimensions.width/2 + 1; 168 int h = textDimensions.height/2 + 1; 169 _position = box2i(bx, by, x + w, y + h); 170 } 171 172 protected: 173 174 /// The font used for text. 175 Font _font; 176 177 /// Text to draw 178 string _text; 179 180 /// Size of displayed text in pixels. 181 float _textSize = 16.0f; 182 183 /// Additional space between letters, in pixels. 184 float _letterSpacing = 0.0f; 185 186 /// Diffuse color of displayed text. 187 RGBA _textColor = RGBA(0, 0, 0, 0); 188 }