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 }