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 }