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 }