1
2
3
4
5
6 using System;
7
8 namespace System.Screen
9 {
10 public abstract class StatusBarItem : Component
11 {
12 public virtual void Measure(Point& loc, bool afterSpring) {}
13 public virtual void WriteScreen() {}
14 public nothrow void SetStatusBar(StatusBar* statusBar_)
15 {
16 statusBar = statusBar_;
17 }
18 public nothrow StatusBar* GetStatusBar() const
19 {
20 return statusBar;
21 }
22 private StatusBar* statusBar;
23 }
24
25 public class StatusBarTextItem : StatusBarItem
26 {
27 public StatusBarTextItem(const string& text_) : text(ToUtf32(text_)), minWidth(0)
28 {
29 }
30 public nothrow int MinWidth() const
31 {
32 return minWidth;
33 }
34 public nothrow void SetMinWidth(int minWidth_)
35 {
36 minWidth = minWidth_;
37 }
38 public void SetText(const string& text_)
39 {
40 text = ToUtf32(text_);
41 StatusBar* statusBar = GetStatusBar();
42 statusBar->SetChanged();
43 statusBar->Invalidate();
44 }
45 public override void Measure(Point& loc, bool afterSpring)
46 {
47 location = loc;
48 int width = Max(minWidth, cast<int>(text.Length()));
49 if (afterSpring)
50 {
51 location.x = location.x - width;
52 loc = location;
53 loc.x = loc.x - 1;
54 }
55 else
56 {
57 loc.x = loc.x + width + 1;
58 }
59 }
60 public override void WriteScreen()
61 {
62 SetCursorPos(location.x, location.y);
63 Terminal.Out() << text;
64 }
65 private Point location;
66 private int minWidth;
67 private ustring text;
68 }
69
70 public class StatusBarSpringItem : StatusBarItem
71 {
72 }
73
74 public class StatusBarCreateParams
75 {
76 public nothrow StatusBarCreateParams() : controlCreateParams()
77 {
78 }
79 public nothrow StatusBarCreateParams& Defaults()
80 {
81 return *this;
82 }
83 public ControlCreateParams controlCreateParams;
84 }
85
86 public enum StatusBarFlags
87 {
88 none = 0, changed = 1 << 0
89 }
90
91 public class StatusBar : ContainerControl
92 {
93 public nothrow StatusBar(StatusBarCreateParams& createParams) : base(createParams.controlCreateParams)
94 {
95 InvalidateGuard guard(this, InvalidateKind.dontInvalidate);
96 if (Location().IsDefault())
97 {
98 SetLocation(Point(0, TerminalWindowHeight() - 1));
99 }
100 if (GetSize().IsDefault())
101 {
102 SetSize(Size(TerminalWindowWidth(), 1));
103 }
104 if (ForeColor() == ConsoleColor.defaultColor)
105 {
106 SetForeColor(ConsoleColor.black);
107 }
108 if (BackColor() == ConsoleColor.defaultColor)
109 {
110 SetBackColor(ConsoleColor.gray);
111 }
112 SetChanged();
113 }
114 public nothrow bool IsChanged() const
115 {
116 return (flags & StatusBarFlags.changed) != StatusBarFlags.none;
117 }
118 public nothrow void SetChanged()
119 {
120 flags = cast<StatusBarFlags>(flags | StatusBarFlags.changed);
121 }
122 public nothrow void ResetChanged()
123 {
124 flags = cast<StatusBarFlags>(flags & ~StatusBarFlags.changed);
125 }
126 public void AddItem(StatusBarItem* item)
127 {
128 item->SetStatusBar(this);
129 Controls().AddChild(item);
130 }
131 public override void OnWriteScreen(WriteScreenEventArgs& args)
132 {
133 Control* focusedControl = Application.Instance().FocusedControl();
134 base->OnWriteScreen(args);
135 Rect rect = args.GetRect();
136 if (rect.IsDefault())
137 {
138 rect = GetRect();
139 }
140 Clear(rect, ForeColor(), BackColor());
141 if (IsChanged())
142 {
143 Measure();
144 }
145 Component* child = Controls().FirstChild();
146 while (child != null)
147 {
148 if (child is StatusBarItem*)
149 {
150 StatusBarItem* item = cast<StatusBarItem*>(child);
151 item->WriteScreen();
152 }
153 child = child->NextSibling();
154 }
155 focusedControl->SetFocus();
156 }
157 private void Measure()
158 {
159 Point loc = Location();
160 loc.x = loc.x + 1;
161 Component* child = Controls().FirstChild();
162 while (child != null)
163 {
164 if (child is StatusBarSpringItem*)
165 {
166 break;
167 }
168 else if (child is StatusBarItem*)
169 {
170 StatusBarItem* item = cast<StatusBarItem*>(child);
171 item->Measure(loc, false);
172 }
173 child = child->NextSibling();
174 }
175 Size sz = GetSize();
176 loc = Location();
177 loc.x = loc.x + sz.w - 1;
178 child = Controls().LastChild();
179 while (child != null)
180 {
181 if (child is StatusBarSpringItem*)
182 {
183 break;
184 }
185 else if (child is StatusBarItem*)
186 {
187 StatusBarItem* item = cast<StatusBarItem*>(child);
188 item->Measure(loc, true);
189 }
190 child = child->PrevSibling();
191 }
192 }
193 private StatusBarFlags flags;
194 }
195 }