1 /**
2  * Status bar control.
3  *
4  * `StatusBar` wraps the native `"msctls_statusbar32"` common control. A status
5  * bar auto-docks itself to the bottom of its parent's client area in response
6  * to `WM_SIZE`; the host window forwards `WM_SIZE` to it and reserves
7  * `getHeight()` pixels at the bottom. The bar can show a single line of text or
8  * be split into several parts.
9  */
10 module deft.controls.statusbar;
11 
12 version (Windows):
13 
14 import core.sys.windows.windows;
15 import core.sys.windows.commctrl;
16 
17 import deft.controls.control;
18 import deft.util.strings;
19 import deft.widget;
20 
21 /// A native status bar docked to the bottom of its parent window.
22 class StatusBar : Control
23 {
24 	/**
25 	 * Create a status bar as a child of `parent`.
26 	 *
27 	 * The bar is given a size grip (`SBARS_SIZEGRIP`) and positions itself; an
28 	 * initial `WM_SIZE` is sent so it docks to the bottom of the parent.
29 	 */
30 	this(Widget parent)
31 	{
32 		super(parent, "msctls_statusbar32", SBARS_SIZEGRIP);
33 		SendMessageW(handle, WM_SIZE, 0, 0);
34 	}
35 
36 	/// Set the text of the default (single) part.
37 	override void setText(string text)
38 	{
39 		if (handle)
40 			SendMessageW(handle, SB_SETTEXTW, 0, cast(LPARAM) text.toWStringz);
41 	}
42 
43 	/**
44 	 * Divide the bar into parts.
45 	 *
46 	 * `widths` holds the right-edge x coordinate of each part; a final value of
47 	 * `-1` extends the last part to the right edge of the bar.
48 	 */
49 	void setParts(int[] widths)
50 	{
51 		if (handle)
52 			SendMessageW(handle, SB_SETPARTS, cast(WPARAM) widths.length,
53 				cast(LPARAM) widths.ptr);
54 	}
55 
56 	/// Set the text of part `part` (zero-based).
57 	void setPartText(int part, string text)
58 	{
59 		if (handle)
60 			SendMessageW(handle, SB_SETTEXTW, cast(WPARAM) part,
61 				cast(LPARAM) text.toWStringz);
62 	}
63 
64 	/// The control's current height in pixels, or `0` if it has no handle.
65 	int getHeight()
66 	{
67 		RECT rc;
68 		if (handle && GetWindowRect(handle, &rc))
69 			return rc.bottom - rc.top;
70 		return 0;
71 	}
72 
73 	/// Re-dock the bar by forwarding a `WM_SIZE` to it.
74 	void reposition()
75 	{
76 		if (handle)
77 			SendMessageW(handle, WM_SIZE, 0, 0);
78 	}
79 
80 	/// The bar fills its parent's width; its preferred height is its own height.
81 	override Size getPreferredSize()
82 	{
83 		return handle ? Size(0, getHeight()) : Size(0, 22);
84 	}
85 }