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