1 /** 2 * A read-only static text label. 3 * 4 * `Label` wraps the Win32 `"STATIC"` control class with `SS_LEFT` styling. It 5 * displays text and is not interactive (it carries no `WS_TABSTOP`), so it is 6 * skipped in the keyboard tab order. Its preferred size is computed from the 7 * measured extent of its text in the control's own font. 8 */ 9 module deft.controls.label; 10 11 version (Windows): 12 13 import core.sys.windows.windows; 14 15 import deft.controls.control; 16 import deft.util.strings; 17 import deft.widget; 18 19 /// A non-interactive label that displays a single run of static text. 20 class Label : Control 21 { 22 private string text_; 23 24 /// Create a label showing `text` inside `parent`. 25 this(Widget parent, string text) 26 { 27 super(parent, "STATIC", SS_LEFT); 28 setText(text); 29 } 30 31 /// Set the label's text, remembering it for size measurement. 32 override void setText(string text) 33 { 34 text_ = text; 35 super.setText(text); 36 } 37 38 /** 39 * Compute the preferred size from the text extent. 40 * 41 * The control's current font is selected into its device context and the 42 * UTF-16 form of the stored text is measured with `GetTextExtentPoint32W`. 43 * A small height floor keeps short or empty labels from collapsing. 44 */ 45 override Size getPreferredSize() 46 { 47 if (handle is null || text_.length == 0) 48 return Size(0, 20); 49 50 const(wchar)* wtext = text_.toWStringz; 51 int len = 0; 52 while (wtext[len] != '\0') 53 ++len; 54 55 HDC hdc = GetDC(handle); 56 if (hdc is null) 57 return Size(0, 20); 58 59 HFONT font = cast(HFONT) SendMessageW(handle, WM_GETFONT, 0, 0); 60 HGDIOBJ oldFont = font !is null ? SelectObject(hdc, font) : null; 61 62 SIZE sz; 63 GetTextExtentPoint32W(hdc, wtext, len, &sz); 64 65 if (font !is null) 66 SelectObject(hdc, oldFont); 67 ReleaseDC(handle, hdc); 68 69 int height = sz.cy < 20 ? 20 : sz.cy; 70 return Size(sz.cx, height); 71 } 72 }