1
2
3
4
5
6 using System;
7 using System.Collections;
8
9 namespace System.Screen
10 {
11 public enum MessageBoxButtons
12 {
13 none = 0, ok = 1 << 0, cancel = 1 << 1, yes = 1 << 2, no = 1 << 3
14 }
15
16 public class MessageBoxCreateParams
17 {
18 public nothrow MessageBoxCreateParams() :
19 controlCreateParams()
20 {
21 }
22 public nothrow MessageBoxCreateParams& Defaults()
23 {
24 return *this;
25 }
26 public nothrow MessageBoxCreateParams& Caption(const string& caption_)
27 {
28 caption = caption_;
29 return *this;
30 }
31 public nothrow MessageBoxCreateParams& Text(const string& text_)
32 {
33 text = text_;
34 return *this;
35 }
36 public nothrow MessageBoxCreateParams& Buttons(MessageBoxButtons buttons_)
37 {
38 buttons = buttons_;
39 return *this;
40 }
41 public ControlCreateParams controlCreateParams;
42 public string caption;
43 public string text;
44 public MessageBoxButtons buttons;
45 }
46
47 public class MessageBox : Window
48 {
49 public nothrow MessageBox(MessageBoxCreateParams& createParams) : base(createParams.controlCreateParams), caption(createParams.caption), text(createParams.text), buttons(createParams.buttons)
50 {
51 InvalidateGuard guard(this, InvalidateKind.invalidateIfNotDefault);
52 bool setLoc = false;
53 if (Location().IsDefault())
54 {
55 SetLocation(Point(0, 0));
56 setLoc = true;
57 }
58 if (GetSize().IsDefault())
59 {
60 SetSize(Size(40, 4));
61 }
62 if (ForeColor() == ConsoleColor.defaultColor)
63 {
64 SetForeColor(ConsoleColor.black);
65 }
66 if (BackColor() == ConsoleColor.defaultColor)
67 {
68 SetBackColor(ConsoleColor.cyan);
69 }
70 if (buttons == MessageBoxButtons.none)
71 {
72 buttons = MessageBoxButtons.ok;
73 }
74 if ((buttons & MessageBoxButtons.ok) != MessageBoxButtons.none)
75 {
76 Button* okButton = Button.OK();
77 okButton->SetDefault();
78 AddChild(okButton);
79 }
80 if ((buttons & MessageBoxButtons.yes) != MessageBoxButtons.none)
81 {
82 Button* yesButton = Button.Yes();
83 AddChild(yesButton);
84 }
85 if ((buttons & MessageBoxButtons.no) != MessageBoxButtons.none)
86 {
87 Button* noButton = Button.No();
88 AddChild(noButton);
89 }
90 if ((buttons & MessageBoxButtons.cancel) != MessageBoxButtons.none)
91 {
92 Button* cancelButton = Button.Cancel();
93 AddChild(cancelButton);
94 }
95 Measure(setLoc);
96 Control* firstFocusableControl = FirstFocusabledControl();
97 if (firstFocusableControl != null)
98 {
99 firstFocusableControl->SetFocus();
100 }
101 }
102 public override nothrow Button* DefaultButton() const
103 {
104 Component* child = Controls().FirstChild();
105 while (child != null)
106 {
107 if (child is Button*)
108 {
109 Button* button = cast<Button*>(child);
110 if (button->IsDefault())
111 {
112 return button;
113 }
114 }
115 child = child->NextSibling();
116 }
117 return null;
118 }
119 public override void OnWriteScreen(WriteScreenEventArgs& args)
120 {
121 base->OnWriteScreen(args);
122 Rect rect = GetRect();
123 WriteBox(rect, ForeColor(), BackColor());
124 if (!caption.IsEmpty())
125 {
126 WriteCaption(u" " + ToUtf32(caption) + u" ");
127 }
128 if (!text.IsEmpty())
129 {
130 WriteText();
131 }
132 WriteChildren(args);
133 }
134 private void Measure(bool setLoc)
135 {
136 Size sz = GetSize();
137 Rect rect = GetRect();
138 rect.Inflate(1, 1);
139 SetLocation(rect.location);
140 SetSize(rect.size);
141 List<Control*> children;
142 float sw = MeasureChildWidth(sz.w, children);
143 textLines = SplitIntoLines(ToUtf32(text), sz.w - 4);
144 sz.h = Max(sz.h, 4 + cast<int>(textLines.Count()));
145 SetSize(sz);
146 if (setLoc)
147 {
148 int x = Max(cast<int>(0), (TerminalWindowWidth() - sz.w) / 2);
149 int y = Max(cast<int>(0), (TerminalWindowHeight() - sz.h) / 2);
150 SetLocation(Point(x, y));
151 }
152 SetChildLocations(sw, sz.h - 1, children);
153 }
154 private float MeasureChildWidth(int& width, List<Control*>& children)
155 {
156 Component* child = Controls().FirstChild();
157 while (child != null)
158 {
159 if (child is Control*)
160 {
161 Control* control = cast<Control*>(child);
162 children.Add(control);
163 }
164 child = child->NextSibling();
165 }
166 int w = 0;
167 for (Control* control : children)
168 {
169 Size sz = control->GetSize();
170 w = w + sz.w;
171 }
172 if (width < w)
173 {
174 width = w;
175 }
176 float sw = (cast<float>(width) - cast<float>(w)) / (children.Count() + 1);
177 return sw;
178 }
179 private void SetChildLocations(float sw, int height, List<Control*>& children)
180 {
181 Point loc = Location();
182 loc.x = loc.x + cast<int>(sw);
183 if (children.Count() > 1)
184 {
185 loc.x = loc.x + 1;
186 }
187 loc.y = loc.y + height - 1;
188 for (Control* child : children)
189 {
190 child->SetLocation(loc);
191 Size sz = child->GetSize();
192 loc.x = loc.x + sz.w + cast<int>(sw);
193 }
194 }
195 private void WriteCaption(const ustring& captionStr)
196 {
197 Point loc = Location();
198 Size sz = GetSize();
199 int offset = Max(cast<int>(0), cast<int>(sz.w - captionStr.Length()));
200 int x = loc.x + offset / 2;
201 int y = loc.y;
202 SetCursorPos(x, y);
203 Terminal.Out() << captionStr;
204 }
205 private void WriteText()
206 {
207 Point loc = Location();
208 Size sz = GetSize();
209 int x = loc.x + 2;
210 int y = loc.y + 1;
211 for (const ustring& line : textLines)
212 {
213 int offset = Max(cast<int>(0), cast<int>((sz.w - 4 - line.Length()) / 2));
214 SetCursorPos(x + offset, y);
215 Terminal.Out() << line;
216 y = y + 1;
217 }
218 }
219 private void WriteChildren(WriteScreenEventArgs& args)
220 {
221 Component* child = Controls().FirstChild();
222 while (child != null)
223 {
224 if (child is Control*)
225 {
226 Control* control = cast<Control*>(child);
227 control->OnWriteScreen(args);
228 }
229 child = child->NextSibling();
230 }
231 }
232 private string caption;
233 private string text;
234 private List<ustring> textLines;
235 private MessageBoxButtons buttons;
236
237 }
238 }