1 // Written in the D programming language.
2
3 /**
4 This module contains definition for status line control.
5
6 Status line is usually shown in the bottom of window, and shows status of app.
7
8 Contains one or more text and/or icon items
9
10 Synopsis:
11
12 ----
13 import dlangui.widgets.statusline;
14
15 ----
16
17 Copyright: Vadim Lopatin, 2015
18 License: Boost License 1.0
19 Authors: Vadim Lopatin, coolreader.org@gmail.com
20 */
21 module dlangui.widgets.statusline;
22
23 import dlangui.widgets.layouts;
24 import dlangui.widgets.controls;
25 import dlangui.widgets.editors;
26
27 class StatusLinePanelBase : HorizontalLayout {
28 this(string ID) {
29 super(ID);
30 }
31 }
32
33 class StatusLineTextPanel : StatusLinePanelBase {
34 protected TextWidget _text;
35 this(string ID) {
36 super(ID);
37 _text = new TextWidget(null, ""d);
38 addChild(_text);
39 }
40 /// returns widget content text (override to support this)
41 override @property dstring text() const { return _text.text; }
42 /// sets widget content text (override to support this)
43 override @property Widget text(dstring s) { _text.text = s; return this; }
44 /// sets widget content text (override to support this)
45 override @property Widget text(UIString s) { _text.text = s; return this; }
46 }
47
48 class StatusLineIconPanel : StatusLinePanelBase {
49 protected ImageWidget _icon;
50 this(string ID) {
51 super(ID);
52 _icon = new ImageWidget(null);
53 addChild(_icon);
54 }
55 @property string iconId() {
56 return _icon.drawableId;
57 }
58 @property void iconId(string icon) {
59 _icon.drawableId = icon;
60 }
61 }
62
63 class StatusLineTextAndIconPanel : StatusLineTextPanel {
64 protected ImageWidget _icon;
65 this(string ID) {
66 super(ID);
67 _icon = new ImageWidget(null);
68 _icon.minWidth = WIDGET_STYLE_CONSOLE ? 1 : 20;
69 _icon.minHeight = WIDGET_STYLE_CONSOLE ? 1 : 20;
70 _icon.alignment = Align.Center;
71 addChild(_icon);
72 }
73 @property string iconId() {
74 return _icon.drawableId;
75 }
76 @property void iconId(string icon) {
77 _icon.drawableId = icon;
78 }
79 }
80
81 class StatusLineBackgroundOperationPanel : StatusLineTextAndIconPanel {
82 this(string ID) {
83 super(ID);
84 visibility = Visibility.Gone;
85 }
86 protected uint animationProgress;
87 /// show / update / animate background operation status; when both parameters are nulls, hide background op status panel
88 void setBackgroundOperationStatus(string icon, dstring statusText) {
89 if (icon || statusText) {
90 visibility = Visibility.Visible;
91 text = statusText;
92 iconId = icon;
93 animationProgress = (animationProgress + 30) % 512;
94 uint a = animationProgress;
95 if (a >= 256)
96 a = 512 - a;
97 _icon.backgroundColor((a << 24) | (0x00FF00));
98 } else {
99 visibility = Visibility.Gone;
100 }
101 }
102 }
103
104 class StatusLineEditorStatePanel : StatusLineTextPanel {
105 EditorStateInfo _editorState;
106
107 this(string ID = "statusLineEditorStateLabel") {
108 super(ID);
109 _text.alignment = Align.VCenter | Align.Right;
110 //_text.backgroundColor = 0x80FF0000;
111 //backgroundColor = 0x8000FF00;
112 updateSize();
113 visibility = Visibility.Gone;
114 }
115
116 dstring makeStateString() {
117 if (!_editorState.active)
118 return null;
119 import std.string : format;
120 return "%d : %d ch=0x%05x %s "d.format(_editorState.line, _editorState.col, _editorState.character, _editorState.replaceMode ? "OVR"d : "INS"d);
121 }
122
123 private void updateSize() {
124 FontRef fnt = font;
125 Point sz = fnt.textSize(" ch=0x00000 000000 : 000 INS "d);
126 _text.minWidth = sz.x;
127 }
128
129 /// handle theme change: e.g. reload some themed resources
130 override void onThemeChanged() {
131 super.onThemeChanged();
132 updateSize();
133 }
134
135 void setState(Widget source, ref EditorStateInfo editorState) {
136 if (editorState != _editorState) {
137 _editorState = editorState;
138 text = makeStateString();
139 Visibility newVisibility = _editorState.active ? Visibility.Visible : Visibility.Gone;
140 if (newVisibility != visibility)
141 visibility = newVisibility;
142 }
143 }
144 }
145
146 /// Status line control
147 class StatusLine : HorizontalLayout, EditorStateListener {
148 protected TextWidget _defStatus;
149 protected StatusLineBackgroundOperationPanel _backgroundOperationPanel;
150 protected StatusLineEditorStatePanel _editorStatePanel;
151 this() {
152 super("STATUS_LINE");
153 styleId = STYLE_STATUS_LINE;
154 initialize();
155 }
156 void initialize() {
157 _defStatus = new TextWidget("STATUS_LINE_TEXT");
158 _defStatus.layoutWidth(FILL_PARENT);
159 _defStatus.text = " "d;
160 addChild(_defStatus);
161 _backgroundOperationPanel = new StatusLineBackgroundOperationPanel("BACKGROUND_OP_STATUS");
162 _editorStatePanel = new StatusLineEditorStatePanel("EDITOR_STATE_PANEL");
163 addChild(_backgroundOperationPanel);
164 addChild(_editorStatePanel);
165 }
166 /// set text to show in status line in specific panel
167 void setStatusText(string itemId, dstring value) {
168 _defStatus.text = value;
169 }
170 /// set text to show in status line
171 void setStatusText(dstring value) {
172 setStatusText(null, value);
173 }
174 /// show / update / animate background operation status; when both parameters are nulls, hide background op status panel
175 void setBackgroundOperationStatus(string icon, dstring statusText = null) {
176 _backgroundOperationPanel.setBackgroundOperationStatus(icon, statusText);
177 }
178
179 /// EditorStateListener implementation
180 override void onEditorStateUpdate(Widget source, ref EditorStateInfo editorState) {
181 _editorStatePanel.setState(source, editorState);
182 }
183
184 void hideEditorState() {
185 EditorStateInfo editorState;
186 _editorStatePanel.setState(null, editorState);
187 }
188 }