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 
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 }
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());
117  }
118 }
119 
120 } // unnamed namespace;
121 
122 
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 
144  AddWidgets(dsk_up, lblTitle, lblPath, lblInfo),
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();
193  },
194  fbMain.GetSelected() += [this](IndexEventArgs&&){
195  Enable(btnOK, CheckReaderEnability(fbMain, cbHex));
196  },
197  FetchEvent<Click>(btnTest) += [this](TouchEventArgs&&){
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&&){
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);
247  },
248 #endif
249  FetchEvent<Click>(pnlSetting) += [this](TouchEventArgs&&){
250  yunseq(
251  lblDragTest.ForeColor = GenerateRandomColor(),
252  lblTitle.ForeColor = GenerateRandomColor()
253  );
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());
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;
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;
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  );
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:
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);
358  SetLocationOf(m1, Point(btnMenu.GetX(), btnMenu.GetY() - m1.GetHeight()));
359  //m1.SetWidth(btnMenu.GetWidth() + 20);
360 }
361 
362 void
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*
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