YSTest: ShlExplorer.cpp 源文件

YSTest PreAlpha_b400_20130424 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
ShlExplorer.cpp
浏览该文件的文档.
1 ﻿/*
2 Copyright by FrankHB 2013.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #include "ShlExplorer.h"
29 #include "ShlReader.h"
30
31 YSL_BEGIN_NAMESPACE(YReader)
32
33 using ystdex::polymorphic_downcast;
34
35 namespace
36 {
37
38 namespace EnrtySpace
39 {
40 typedef enum
41 {
42 Empty,
43 Now,
44 Parent,
45 Directory,
46 Text,
47 Hex
48 } EntryType;
49 }
50
51 EnrtySpace::EntryType
52 GetEntryType(const string& path)
53 {
54 using namespace EnrtySpace;
55
56 if(path.empty())
57 return Empty;
58 if(path == IO::FS_Now)
59 return Now;
60 if(path == IO::FS_Parent)
61 return Parent;
62 if(*path.rbegin() == YCL_PATH_DELIMITER)
63 return Directory;
64
65 static yconstexpr const char* exts[]{
66 "txt", "c", "cpp", "h", "hpp", "ini", "xml"};
67 auto npath(IO::GetExtensionOf(path));
68
69 for(auto& c : npath)
70 c = std::tolower(c);
71
72 const auto ext(IO::GetExtensionOf(path));
73
74 if(std::any_of(exts, exts + arrlen(exts), [&](const char* str){
75 return std::strcmp(ext.c_str(), str) == 0;
76 }))
77 return Text;
78 return Hex;
79 }
80 EnrtySpace::EntryType
81 GetEntryType(const IO::Path& path)
82 {
83 return GetEntryType(path.GetNativeString());
84 }
85
86 bool
87 CheckReaderEnability(FileBox& fb, CheckBox& hex)
88 {
89 if(fb.IsSelected())
90 {
91 using namespace EnrtySpace;
92
93 switch(GetEntryType(fb.GetList()[fb.GetSelectedIndex()]))
94 {
95 case Text:
96 return true;
97 case Hex:
98 return hex.IsTicked();
99 default:
100 ;
101 }
102 }
103 return false;
104 }
105
107 void
108 CheckBackgroundPreview(CheckButton& cbPreview, size_t up_i, size_t dn_i)
109 {
110 if(cbPreview.IsTicked())
111 {
112 auto& app(FetchGlobalInstance<DSApplication>());
113
114 app.GetScreenUp().Update(FetchImage(up_i)->GetBufferPtr());
115 app.GetScreenDown().Update(FetchImage(dn_i)->GetBufferPtr());
116 platform::WaitForInput();
117 }
118 }
119
120 } // unnamed namespace;
121
122
123 ShlExplorer::ShlExplorer(const IO::Path& path,
124 const shared_ptr<Desktop>& h_dsk_up, const shared_ptr<Desktop>& h_dsk_dn)
125 : ShlDS(h_dsk_up, h_dsk_dn),
126 lblTitle({16, 20, 220, 22}), lblPath({8, 48, 240, 48}),
127 lblInfo({8, 100, 240, 64}), fbMain({4, 6, 248, 128}),
128 btnTest({115, 165, 65, 22}), btnOK({185, 165, 65, 22}),
129 btnMenu({4, 165, 72, 22}), pnlSetting({10, 40, 224, 136}),
130 cbHex({142, 142, 103, 18}), cbFPS({10, 90, 73, 18}),
131 cbPreview({10, 110, 115, 18}), lblDragTest({4, 4, 104, 22}),
132 btnEnterTest({8, 32, 104, 22}), btnTestEx({48, 60, 156, 22}),
133 btnPrevBackground({114, 90, 30, 22}),
134 btnNextBackground({164, 90, 30, 22}),
135 pFrmAbout(make_unique<FrmAbout>()), mhMain(*GetDesktopDownHandle()),
136 fpsCounter(500000000ULL)
137 {
138 static int up_i(1);
139 auto& dsk_up(GetDesktopUp());
140 auto& dsk_dn(GetDesktopDown());
141
142 AddWidgets(pnlSetting, cbFPS, cbPreview, btnEnterTest, lblDragTest,
143 btnTestEx, btnPrevBackground, btnNextBackground),
144 AddWidgets(dsk_up, lblTitle, lblPath, lblInfo),
145 AddWidgets(dsk_dn, fbMain, btnTest, btnOK, btnMenu, cbHex),
146 AddWidgetsZ(dsk_dn, DefaultWindowZOrder, pnlSetting, *pFrmAbout),
147 //启用缓存。
148 fbMain.SetRenderer(make_unique<BufferedRenderer>(true)),
149 pnlSetting.SetRenderer(make_unique<BufferedRenderer>()),
150 SetVisibleOf(pnlSetting, false),
151 SetVisibleOf(*pFrmAbout, false),
152 yunseq(
153 dsk_up.Background = ImageBrush(FetchImage(1)),
154 dsk_dn.Background = ImageBrush(FetchImage(2)),
155 lblTitle.Text = G_APP_NAME,
156 lblPath.AutoWrapLine = true, lblPath.Text = path,
157 lblInfo.AutoWrapLine = true, lblInfo.Text = u"文件列表：请选择一个文件。",
158 // TODO: Show current working directory properly.
159 btnTest.Text = u"设置(X)",
160 btnOK.Text = u"确定(A)",
161 #if YCL_MINGW32
162 btnMenu.Text = u"菜单(P)",
163 #else
164 btnMenu.Text = u"菜单(Start)",
165 #endif
166 cbHex.Text = u"显示十六进制",
167 cbFPS.Text = u"显示 FPS",
168 cbPreview.Text = u"切换背景时预览",
169 pnlSetting.Background = SolidBrush(Color(248, 248, 120)),
170 lblDragTest.HorizontalAlignment = TextAlignment::Left,
171 //btnTestEx.Enabled = false,
172 btnTestEx.Text = u"附加测试",
173 btnTestEx.HorizontalAlignment = TextAlignment::Left,
174 btnTestEx.VerticalAlignment = TextAlignment::Down,
175 btnEnterTest.Text = u"边界测试",
176 btnEnterTest.HorizontalAlignment = TextAlignment::Right,
177 btnEnterTest.VerticalAlignment = TextAlignment::Up,
178 btnPrevBackground.Text = u"<<",
179 btnNextBackground.Text = u">>",
180 fbMain.SetPath(path),
181 cbHex.Background = SolidBrush(Color(0xFF, 0xFF, 0xE0)),
182 Enable(btnTest),
183 Enable(btnOK, false),
184 Enable(btnPrevBackground, false),
185 dsk_dn.BoundControlPtr = std::bind(&ShlExplorer::GetBoundControlPtr,
186 this, std::placeholders::_1),
187 FetchEvent<KeyUp>(dsk_dn) += OnKey_Bound_TouchUpAndLeave,
188 FetchEvent<KeyDown>(dsk_dn) += OnKey_Bound_EnterAndTouchDown,
189 FetchEvent<KeyPress>(dsk_dn) += OnKey_Bound_Click,
190 fbMain.GetViewChanged() += [this](UIEventArgs&&){
191 lblPath.Text = fbMain.GetPath();
192 Invalidate(lblPath);
193 },
194 fbMain.GetSelected() += [this](IndexEventArgs&&){
195 Enable(btnOK, CheckReaderEnability(fbMain, cbHex));
196 },
197 FetchEvent<Click>(btnTest) += [this](TouchEventArgs&&){
198 SwitchVisible(pnlSetting);
199 },
200 FetchEvent<Click>(btnOK) += [this](TouchEventArgs&&){
201 if(fbMain.IsSelected())
202 {
203 const auto& path(fbMain.GetPath());
204 const string& s(path.GetNativeString());
205
206 if(!IO::ValidatePath(s) && ufexists(s))
207 {
208 const auto h_up(GetDesktopUpHandle());
209 const auto h_dn(GetDesktopDownHandle());
210 const bool b(GetEntryType(s) == EnrtySpace::Text
211 && !cbHex.IsTicked());
212
213 PostMessage<SM_TASK>(0xF8, [=]{
214 ResetDSDesktops(*h_up, *h_dn);
215 if(b)
216 NowShellTo(ystdex::make_shared<ShlTextReader>(path,
217 h_up, h_dn));
218 else
219 NowShellTo(ystdex::make_shared<ShlHexBrowser>(path,
220 h_up, h_dn));
221 // TODO: Use G++ 4.8 or later.
222 // SetShellTo(make_shared<ShlTextReader>(path));
223 // SetShellToNew<ShlTextReader>(path);
224 });
225 }
226 }
227 },
228 FetchEvent<Click>(cbFPS) += [this](TouchEventArgs&&){
229 SetInvalidationOf(GetDesktopDown());
230 },
231 FetchEvent<Click>(cbHex) += [this](TouchEventArgs&&){
232 Enable(btnOK, CheckReaderEnability(fbMain, cbHex));
233 SetInvalidationOf(GetDesktopDown());
234 },
235 FetchEvent<Move>(pnlSetting) += [this](UIEventArgs&&){
236 lblDragTest.Text = to_string(GetLocationOf(pnlSetting)) + ';';
237 Invalidate(lblDragTest);
238 },
239 FetchEvent<TouchMove>(pnlSetting) += OnTouchMove_Dragging,
240 #if YCL_DS
241 FetchEvent<TouchDown>(pnlSetting) += [this](TouchEventArgs&&){
242 struct ::mallinfo t(::mallinfo());
243
244 lblInfo.Text = ystdex::sfmt("%d,%d,%d,%d,%d;",
245 t.arena, t.ordblks, t.uordblks, t.fordblks, t.keepcost);
246 Invalidate(lblInfo);
247 },
248 #endif
249 FetchEvent<Click>(pnlSetting) += [this](TouchEventArgs&&){
250 yunseq(
251 lblDragTest.ForeColor = GenerateRandomColor(),
252 lblTitle.ForeColor = GenerateRandomColor()
253 );
254 Invalidate(pnlSetting);
255 },
256 FetchEvent<Click>(btnTestEx) += [this](TouchEventArgs&& e){
257 const auto& k(e.GetKeys());
258 auto& btn(polymorphic_downcast<Button&>(e.GetSender()));
259
260 if(lblTitle.Background)
261 lblTitle.Background = nullptr;
262 else
263 lblTitle.Background = SolidBrush(GenerateRandomColor());
264 lblInfo.Text = btn.Text + u", " + String(to_string(
265 FetchImageLoadTime())) + u";\n" + String(k.to_string());
266 Invalidate(lblTitle),
267 Invalidate(lblInfo);
268 },
269 FetchEvent<Enter>(btnEnterTest) += [](TouchEventArgs&& e){
270 auto& btn(ystdex::polymorphic_downcast<Button&>(e.GetSender()));
271
272 btn.Text = u"Enter: " + String(to_string(e));
273 Invalidate(btn);
274 },
275 FetchEvent<Leave>(btnEnterTest) += [](TouchEventArgs&& e){
276 auto& btn(ystdex::polymorphic_downcast<Button&>(e.GetSender()));
277
278 btn.Text = u"Leave: " + String(to_string(e));
279 Invalidate(btn);
280 },
281 mhMain.Roots[&btnMenu] = 1u,
282 FetchEvent<Click>(btnMenu) += [this](TouchEventArgs&&){
283 auto& mnu(mhMain[1u]);
284
285 if(mhMain.IsShowing(1u))
286 {
287 mhMain.HideAll();
288 mnu.ClearSelected();
289 }
290 else
291 mhMain.Show(1u);
292 Invalidate(mnu);
293 },
294 FetchEvent<Click>(btnPrevBackground) += [this](TouchEventArgs&&){
295 auto& dsk_up(GetDesktopUp());
296 auto& dsk_dn(GetDesktopDown());
297
298 if(up_i > 1)
299 {
300 --up_i;
301 Enable(btnNextBackground);
302 }
303 if(up_i == 1)
304 Enable(btnPrevBackground, false);
305 yunseq(dsk_up.Background = ImageBrush(FetchImage(up_i)),
306 dsk_dn.Background = ImageBrush(FetchImage(up_i + 1)));
307 CheckBackgroundPreview(cbPreview, up_i, up_i + 1);
308 SetInvalidationOf(dsk_up),
309 SetInvalidationOf(dsk_dn);
310 },
311 FetchEvent<Click>(btnNextBackground) += [this](TouchEventArgs&&){
312 auto& dsk_up(GetDesktopUp());
313 auto& dsk_dn(GetDesktopDown());
314
315 if(up_i < 5)
316 {
317 ++up_i;
318 Enable(btnPrevBackground);
319 }
320 if(up_i == 5)
321 Enable(btnNextBackground, false);
322 yunseq(dsk_up.Background = ImageBrush(FetchImage(up_i)),
323 dsk_dn.Background = ImageBrush(FetchImage(up_i + 1)));
324 CheckBackgroundPreview(cbPreview, up_i, up_i + 1);
325 SetInvalidationOf(dsk_up),
326 SetInvalidationOf(dsk_dn);
327 }
328 );
329 RequestFocusCascade(fbMain),
330 SetInvalidationOf(dsk_up),
331 SetInvalidationOf(dsk_dn);
332
333 auto& m1(*(ynew Menu({},
334 share_raw(new TextList::ListType{u"测试", u"关于", u"退出"}), 1u)));
335 auto& m2(*(ynew Menu({},
336 share_raw(new TextList::ListType{u"项目1", u"项目2"}), 2u)));
337
338 m1.GetConfirmed() += [this](IndexEventArgs&& e){
339 switch(e.Value)
340 {
341 case 1U:
342 YAssert(bool(pFrmAbout), "Null pointer found");
343
344 Show(*pFrmAbout);
345 break;
346 case 2U:
347 YSLib::PostQuitMessage(0);
348 }
349 },
350 #if YCL_MINGW32
351 m2.GetConfirmed() += [this](IndexEventArgs&& e){
352 MinGW32::TestFramework(e.Value);
353 },
354 #endif
355 mhMain += m1, mhMain += m2,
356 m1 += make_pair(0u, &m2);
357 ResizeForContent(m1), ResizeForContent(m2),
358 SetLocationOf(m1, Point(btnMenu.GetX(), btnMenu.GetY() - m1.GetHeight()));
359 //m1.SetWidth(btnMenu.GetWidth() + 20);
360 }
361
362 void
363 ShlExplorer::OnPaint()
364 {
365 // NOTE: Overriding member function %OnInput using %SM_TASK is also valid
366 // because the %SM_INPUT message is sent continuously, but less efficient.
367 if(cbFPS.IsTicked())
368 {
369 using namespace ColorSpace;
370
371 const u32 t(fpsCounter.Refresh());
372
373 if(t != 0)
374 {
375 auto& g(ystdex::polymorphic_downcast<BufferedRenderer&>(
376 GetDesktopUp().GetRenderer()).GetContext());
377 yconstexpr Rect r(176, 0, 80, 20);
378 char strt[20];
379
380 std::sprintf(strt, "FPS: %u.%03u", t / 1000, t % 1000);
381 FillRect(g, r, Blue);
382 DrawText(g, r, strt, DefaultMargin, White, false);
383 bUpdateUp = true;
384 }
385 }
386 }
387
388 IWidget*
389 ShlExplorer::GetBoundControlPtr(const KeyInput& k)
390 {
391 if(k.count() == 1)
392 {
393 if(k[YCL_KEY(X)])
394 return &btnTest;
395 if(k[YCL_KEY(A)])
396 return &btnOK;
397 }
398 return nullptr;
399 }
400
401 YSL_END_NAMESPACE(YReader)
402