YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
ShlReader.cpp
浏览该文件的文档.
1 /*
2  © 2011-2014 FrankHB.
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 "ShlReader.h"
29 #include "ShlExplorer.h"
30 #include YFM_NPL_Lexical
31 #include <sys/stat.h> // for ::stat;
32 
33 namespace YReader
34 {
35 
36 namespace
37 {
38 // ResourceMap GlobalResourceMap;
39 
40 using namespace Text;
41 
42 /*
43 \brief 文本阅读器菜单项。
44 \since build 303
45 */
46 enum MNU_READER : Menu::IndexType
47 {
48  MR_Return = 0,
49  MR_Setting,
50  MR_FileInfo,
52  MR_Bookmark,
53  MR_LineUp,
54  MR_LineDown,
55  MR_ScreenUp,
56  MR_ScreenDown
57 };
58 
59 } // unnamed namespace;
60 
61 
62 ReaderBox::ReaderBox(const Rect& r)
63  : Control(r, MakeBlankBrush()),
64  btnMenu({4, 12, 16, 16}), btnSetting({24, 12, 16, 16}),
65  btnInfo({44, 12, 16, 16}), btnBookmark({64, 12, 16, 16}),
66  btnReturn({84, 12, 16, 16}),
67  btnPrev({104, 12, 16, 16}), btnNext({124, 12, 16, 16}),
68  pbReader({4, 0, 248, 8}), lblProgress({216, 12, 40, 16})
69 {
70  Background = nullptr,
71  SetRenderer(make_unique<BufferedRenderer>()),
72  unseq_apply(ContainerSetter(*this), btnMenu, btnSetting, btnInfo,
73  btnBookmark, btnReturn, btnPrev, btnNext, pbReader, lblProgress);
74  SetBufferRendererAndText(btnMenu, u"M"),
75  SetBufferRendererAndText(btnSetting, u"S"),
76  SetBufferRendererAndText(btnInfo, u"I"),
77  SetBufferRendererAndText(btnBookmark, u"B"),
78  SetBufferRendererAndText(btnReturn, u"R"),
79  SetBufferRendererAndText(btnPrev, u"←"),
80  SetBufferRendererAndText(btnNext, u"→");
81  pbReader.ForeColor = Color(192, 192, 64),
82  lblProgress.SetRenderer(make_unique<BufferedRenderer>()),
83  lblProgress.Background = nullptr,
84  lblProgress.Font.SetSize(12),
85  InitializeProgress();
86 }
87 
88 void
89 ReaderBox::InitializeProgress()
90 {
92 }
93 
94 void
95 ReaderBox::UpdateData(DualScreenReader& reader)
96 {
97  if(YB_LIKELY(reader.IsBufferReady()))
98  {
99  const auto ts(reader.GetTextSize());
100 
101  if(YB_LIKELY(ts != 0))
102  {
103  const auto tp(reader.GetTopPosition());
104  char str[5];
105 
106  std::sprintf(str, "%2u%%", tp * 100 / ts);
107  yunseq(lblProgress.Text = str,
108  lblProgress.ForeColor = reader.GetBottomPosition() == ts
109  ? ColorSpace::Green : ColorSpace::Fuchsia);
110  pbReader.SetMaxValue(ts),
111  pbReader.SetValue(tp);
112  }
113  else
114  InitializeProgress();
115  }
116  else
117  InitializeProgress();
118  unseq_apply([](IWidget& wgt){Invalidate(wgt);}, pbReader, lblProgress);
119 }
120 
121 
123  : DialogBox({32, 32, 200, 108}),
124  lblEncoding({4, 20, 192, 18}),
125  lblSize({4, 40, 192, 18}),
126  lblTop({4, 60, 192, 18}),
127  lblBottom({4, 80, 192, 18})
128 {
129  unseq_apply(ContainerSetter(*this), lblEncoding, lblSize);
130  FetchEvent<TouchHeld>(*this) += OnTouchHeld_Dragging;
131 }
132 
133 void
135 {
136  DialogBox::Refresh(std::move(e));
137 
139  UpdateClipSize(e, GetSizeOf(*this));
140 }
141 
142 void
143 TextInfoBox::UpdateData(DualScreenReader& reader)
144 {
145  yunseq(lblEncoding.Text = "Encoding: " + to_string(reader.GetEncoding())
146  + ';',
147  lblSize.Text = "Size: " + to_string(reader.GetTextSize()) + " B;",
148  lblTop.Text = "Top: " + to_string(reader.GetTopPosition()) + " B;",
149  lblBottom.Text = "Bottom: " + to_string(reader.GetBottomPosition())
150  + " B;"),
151  unseq_apply([](IWidget& wgt){Invalidate(wgt); }, lblEncoding, lblSize);
152 }
153 
154 
156  : Panel(Size(MainScreenWidth, MainScreenHeight)),
157  lblPath({8, 20, 240, 16}),
158  lblSize({8, 40, 240, 16}),
159  lblAccessTime({8, 60, 240, 16}),
160  lblModifiedTime({8, 80, 240, 16}),
161  lblOperations({8, 120, 240, 16})
162 {
163  Background = SolidBrush(ColorSpace::Silver);
164 #if YCL_DS
165  lblOperations.Text = "<↑↓> 滚动一行 <LR> 滚动一屏 <B>退出";
166 #else
167  lblOperations.Text = "<↑↓> 滚动一行 <LR> 滚动一屏 <Esc>退出";
168 #endif
169  AddWidgets(*this, lblPath, lblSize, lblAccessTime, lblModifiedTime,
170  lblOperations);
171 }
172 
173 
175  const shared_ptr<Desktop>& h_dsk_up, const shared_ptr<Desktop>& h_dsk_dn)
176  : ShlDS(h_dsk_up, h_dsk_dn),
177  CurrentPath(pth), fBackgroundTask(), bExit()
178 {}
179 
180 void
182 {
183  if(bExit)
184  return;
185  bExit = true;
186  fBackgroundTask = nullptr;
187  // TODO: Use template %SetShellToNew.
188 // SetShellToNew<ShlExplorer>();
189  const auto h_up(GetMainDesktopHandle());
190  const auto h_dn(GetSubDesktopHandle());
191 
192  PostTask([=]{
193  ResetDSDesktops(*h_up, *h_dn);
194  NowShellTo(ystdex::make_shared<ShlExplorer>(CurrentPath / u"..",
195  h_up, h_dn));
196  }, 0xF8);
197 }
198 
200 ShlReader::LoadBookmarks(const string& group)
201 {
202  BookmarkList bookmarks;
203 
204  try
205  {
206  // TODO: Complete unexpected input handling.
207  ystdex::split(Access<string>(FetchRoot().at("YReader")["Bookmarks"].at(
208  '"' + NPL::MakeEscape(group) + '"')), static_cast<int(&)(
209  int)>(std::isspace), [&](string::iterator b, string::iterator e){
210  try
211  {
212  bookmarks.push_back(stoul(ystdex::ltrim(string(b, e))));
213  }
214  catch(std::invalid_argument&)
215  {}
216  catch(std::out_of_range&)
217  {}
218  });
219  }
220  catch(std::exception& e) // TODO: Logging.
221  {}
222  return bookmarks;
223 }
224 
227 {
228  try
229  {
230  return ReaderSetting((FetchRoot() %= LoadConfiguration().at("YReader"))
231  .at("ReaderSetting").GetContainer());
232  }
233  catch(std::exception& e) // TODO: Logging.
234  {}
235  return {};
236 }
237 
238 void
240 {
241  PostMessage<SM_Paint>(0xE0, {});
242  if(fBackgroundTask)
243  PostTask(fBackgroundTask, 0x20);
244 }
245 
246 void
247 ShlReader::SaveBookmarks(const string& group, const BookmarkList& bookmarks)
248 {
249  try
250  {
251  FetchRoot().at("YReader")["Bookmarks"]['"' + NPL::MakeEscape(group)
252  + '"'].Value = [&]{
253  string str;
254 
255  for(const auto& pos : bookmarks)
256  {
257  str += to_string(pos);
258  str += ' ';
259  }
260  return str;
261  }();
262  }
263  catch(std::exception& e) // TODO: Logging.
264  {}
265 }
266 
267 void
269 {
270  try
271  {
272  auto& root(FetchRoot());
273 
274  root["YReader"]["ReaderSetting"].Value = ValueNode::Container(rs);
275  SaveConfiguration(root);
276  }
277  catch(std::exception& e) // TODO: Logging.
278  {}
279 }
280 
281 
284  reader_box_shown(IsVisible(shl.boxReader))
285 {
286  shl.StopAutoScroll(),
287  unseq_apply(std::bind(Hide, std::placeholders::_1), shl.boxReader,
288  shl.boxTextInfo);
289 }
291 {
292  auto& shl(GetShell());
293 
294  shl.reader.SetVisible(true),
295  shl.boxReader.UpdateData(shl.reader),
296  shl.boxTextInfo.UpdateData(shl.reader);
297  if(reader_box_shown)
298  Show(shl.boxReader);
299 }
300 
301 
303  : BaseSession(shl)
304 {
305  auto& dsk_m(shl.GetMainDesktop());
306  auto& dsk_s(shl.GetSubDesktop());
307  auto& reader(shl.reader);
308  auto& CurrentSetting(shl.CurrentSetting);
309  auto& pnlSetting(shl.pnlSetting);
310 
311  shl.reader.SetVisible(false),
312  yunseq(CurrentSetting.UpColor = dsk_m.Background
314  = dsk_s.Background.target<SolidBrush>()->Color,
315  CurrentSetting.FontColor = reader.GetColor(),
316  CurrentSetting.Font = reader.GetFont());
318  {
319  using ystdex::get_key;
320 
321  size_t i(std::find(Encodings | get_key,
323  reader.GetEncoding()) - Encodings);
324 
325  if(i == arrlen(Encodings))
326  i = 0;
328  AccessWidget<DropDownList>(pnlSetting.dynWgts.WidgetNode,
329  "pnlPage2", "ddlEncoding").Text = Encodings[i].second);
330  }
332 }
334 {
335  auto& shl(GetShell());
336 
337  RemoveWidgets(shl.GetMainDesktop(),
338  shl.pnlSetting.lblAreaUp, shl.pnlSetting.lblAreaDown);
339 }
340 
341 
343  : BaseSession(shl)
344 {
346  Show(shl.pnlBookmark);
347 }
348 
349 
351  const shared_ptr<Desktop>& h_dsk_up, const shared_ptr<Desktop>& h_dsk_dn)
352  : ShlReader(pth, h_dsk_up, h_dsk_dn),
355  CurrentSetting.GetTimerSetting()), tmrScrollActive(false), tmrInput(),
356  nClick(), reader(), boxReader({0, 160, 256, 32}), boxTextInfo(),
357  pnlSetting(), pTextFile(), mhMain(GetSubDesktop()),
358  pnlBookmark(LoadBookmarks(pth), *this), session_ptr()
359 {
360  using namespace std;
361  using namespace placeholders;
362  using ystdex::get_key;
363 
364  const auto exit_session([this]{
365  session_ptr.reset();
366  });
367 
368  unseq_apply(bind(SetVisibleOf, _1, false), boxReader, boxTextInfo,
369  pnlSetting, pnlBookmark);
370  yunseq(
371  reader.ViewChanged = [this]{
372  if(IsVisible(boxReader))
373  boxReader.UpdateData(reader);
374  if(IsVisible(boxTextInfo))
375  boxTextInfo.UpdateData(reader);
376  },
377  mhMain.Roots[&boxReader.btnMenu] = 1U,
378  FetchEvent<Click>(boxReader.btnMenu) += [this]{
379  if(mhMain.IsShowing(1U))
380  mhMain.Hide(1U);
381  else
382  {
383  const auto& pt(LocateForWidget(GetSubDesktop(),
384  boxReader.btnMenu));
385 
386  ShowMenu(1U, Point(pt.X, pt.Y - mhMain[1U].GetHeight()));
387  }
388  },
389  FetchEvent<Click>(boxReader.btnSetting) += [this]{
390  Execute(MR_Setting);
391  },
392  FetchEvent<Click>(boxReader.btnInfo) += [this]{
393  Execute(MR_FileInfo);
394  },
395  FetchEvent<Click>(boxReader.btnBookmark) += [this]{
396  Execute(MR_Bookmark);
397  },
398  FetchEvent<Click>(boxReader.btnReturn) += [this]{
399  Execute(MR_Return);
400  },
401  FetchEvent<Click>(boxReader.btnPrev) += [this]{
402  UpdateReadingList(true);
403  },
404  FetchEvent<Click>(boxReader.btnNext) += [this]{
405  UpdateReadingList(false);
406  },
407  FetchEvent<TouchDown>(boxReader.pbReader) += [this](CursorEventArgs&& e){
408  const auto s(reader.GetTextSize());
409 
410  if(YB_LIKELY(s != 0))
411  Locate(e.Position.X * s / boxReader.pbReader.GetWidth());
412  },
413  FetchEvent<Paint>(boxReader.pbReader) += [this](PaintEventArgs&& e){
414  auto& pb(boxReader.pbReader);
415  const auto mval(pb.GetMaxValue());
416  const auto w(pb.GetWidth() - 2);
417  auto& pt(e.Location);
418 
419  FillRect(e.Target, e.ClipArea, Rect(pt.X + 1 + round(pb.GetValue()
420  * w / mval), pt.Y + 1, round((reader.GetBottomPosition()
421  - GetReaderPosition()) * w / mval), pb.GetHeight() - 2),
423  },
424  FetchEvent<Click>(pnlSetting.btnClose) += exit_session,
425  FetchEvent<Click>(pnlSetting.btnOK) += [&, this]{
426  pnlSetting >> CurrentSetting;
427  tmrScroll.Interval = CurrentSetting.GetTimerSetting();
428  Switch(pnlSetting.current_encoding),
429  reader.SetColor(CurrentSetting.FontColor),
430  reader.SetFont(CurrentSetting.Font);
431  reader.UpdateView();
432  yunseq(GetMainDesktop().Background = pnlSetting.lblAreaUp.Background,
433  GetSubDesktop().Background = pnlSetting.lblAreaDown.Background
434  );
435  if(IsVisible(boxReader))
436  for(auto pr(boxReader.GetChildren()); pr.first != pr.second;
437  ++pr.first)
438  if(dynamic_cast<BufferedRenderer*>(&pr.first->GetRenderer()))
439  Invalidate(*pr.first);
440  },
441  FetchEvent<Click>(pnlSetting.btnOK) += exit_session,
442  FetchEvent<Click>(pnlBookmark.btnClose) += exit_session,
443  FetchEvent<Click>(pnlBookmark.btnOK) += [this]{
444  if(pnlBookmark.lbPosition.IsSelected() && Locate(
445  pnlBookmark.bookmarks[pnlBookmark.lbPosition.GetSelectedIndex()]))
446  boxReader.UpdateData(reader);
447  },
448  FetchEvent<Click>(pnlBookmark.btnOK) += exit_session
449  );
450  {
451  Menu& mnu(*(ynew Menu({}, shared_ptr<Menu::ListType>(new
452  Menu::ListType{"返回", "设置...", "文件信息...", "书签...",
453  "向上一行", "向下一行", "向上一屏", "向下一屏"}), 1u)));
454 
455  mnu.Confirmed += [this](IndexEventArgs&& e){
456  Execute(e.Value);
457  };
458  mhMain += mnu;
459  }
460  ResizeForContent(mhMain[1u]);
461 
462  auto& dsk_m(GetMainDesktop());
463  auto& dsk_s(GetSubDesktop());
464 
465  reader.SetColor(CurrentSetting.FontColor),
466  reader.SetFont(CurrentSetting.Font),
467  yunseq(
468  dsk_m.Background = SolidBrush(CurrentSetting.UpColor),
469  dsk_s.Background = SolidBrush(CurrentSetting.DownColor),
470  FetchEvent<Click>(dsk_s).Add(*this, &ShlTextReader::OnClick),
471  FetchEvent<KeyDown>(dsk_s).Add(*this, &ShlTextReader::OnKeyDown),
472  FetchEvent<KeyHeld>(dsk_s) += OnEvent_Call<KeyDown>
473  );
474  reader.Attach(dsk_m, dsk_s),
475  AddWidgets(dsk_s, boxReader, boxTextInfo, pnlSetting, pnlBookmark);
476  LoadFile(pth);
477  LastRead.DropSubsequent();
478  UpdateButtons();
479  //置默认视图。
480  // TODO: Associate view setting state for user selection.
481  OnClick(CursorEventArgs(dsk_s, 0));
482  RequestFocusCascade(dsk_s);
483 }
484 
486 {
488  SaveGlobalConfiguration(CurrentSetting);
489  LastRead.Insert(CurrentPath, GetReaderPosition());
490 }
491 
492 string
493 ShlTextReader::GetSlice(Bookmark::PositionType pos, string::size_type len)
494 {
495  return CopySliceFrom(reader.GetTextBufferRef(), pos, len);
496 }
497 
498 void
500 {
501  switch(idx)
502  {
503  case MR_Return:
504  Exit();
505  break;
506  case MR_Setting:
507  session_ptr.reset(new SettingSession(*this));
508  break;
509  case MR_Bookmark:
510  session_ptr.reset(new BookmarkSession(*this));
511  break;
512  case MR_FileInfo:
514  Show(boxTextInfo);
515  break;
516  case MR_LineUp:
517  reader.Execute(DualScreenReader::LineUpScroll);
518  break;
519  case MR_LineDown:
520  reader.Execute(DualScreenReader::LineDownScroll);
521  break;
522  case MR_ScreenUp:
523  reader.Execute(DualScreenReader::ScreenUpScroll);
524  break;
525  case MR_ScreenDown:
526  reader.Execute(DualScreenReader::ScreenDownScroll);
527  break;
528  }
529 }
530 
531 void
533 {
534  CurrentPath = pth;
535  pTextFile = make_unique<TextFile>(string(pth).c_str(),
536  std::ios_base::in | std::ios_base::binary, CharSet::Null);
537  reader.LoadText(*pTextFile);
538 
539  const auto text_size(reader.GetTextSize());
540 
542  return pos >= text_size;
543  });
544 }
545 
546 bool
548 {
549  const auto s(reader.GetTextSize());
550 
551  if(YB_LIKELY(s != 0))
552  {
553  const auto old_pos(GetReaderPosition());
554 
555  reader.Locate(pos);
556  if(YB_LIKELY(old_pos != GetReaderPosition()))
557  {
558  LastRead.Insert(CurrentPath, old_pos);
559  LastRead.DropSubsequent();
560  UpdateButtons();
561  return true;
562  }
563  }
564  return false;
565 }
566 
567 void
569 {
570  if(tmrScrollActive)
571  if(YB_UNLIKELY(tmrScroll.Refresh()))
572  {
573  if(CurrentSetting.SmoothScroll)
574  reader.ScrollByPixel(1U);
575  else
576  reader.Execute(DualScreenReader::LineDownScroll);
577  }
578 }
579 
580 void
582 {
583  if(!mhMain.IsShowing(id))
584  {
585  auto& mnu(mhMain[id]);
586 
587  mnu.ClearSelected();
588  switch(id)
589  {
590  case 1u:
591  mnu.SetItemEnabled(MR_LineUp, !reader.IsTextTop());
592  mnu.SetItemEnabled(MR_LineDown, !reader.IsTextBottom());
593  mnu.SetItemEnabled(MR_ScreenUp, !reader.IsTextTop());
594  mnu.SetItemEnabled(MR_ScreenDown, !reader.IsTextBottom());
595  }
596  SetLocationOf(mnu, pt);
597  mhMain.Show(id);
598  }
599 }
600 
601 void
603 {
604  fBackgroundTask = std::bind(&ShlTextReader::Scroll, this);
606  tmrScrollActive = true;
607 }
608 
609 void
611 {
612  reader.AdjustScrollOffset(),
613  fBackgroundTask = nullptr,
614  tmrScrollActive = {};
615 }
616 
617 void
619 {
620  if(enc != Encoding() && pTextFile && bool(*pTextFile)
621  && pTextFile->Encoding != enc)
622  {
623  pTextFile->Encoding = enc;
624  reader.LoadText(*pTextFile);
625  }
626 }
627 
628 void
630 {
631  LastRead.Insert(CurrentPath, GetReaderPosition());
632 
633  const auto& bm(LastRead.Switch(is_prev));
634 
635  if(bm.Path != CurrentPath)
636  LoadFile(bm.Path);
637  if(reader.IsBufferReady())
638  reader.Locate(bm.Position);
639  UpdateButtons();
640 }
641 
642 void
644 {
645  yunseq(Enable(boxReader.btnPrev, !LastRead.IsAtBegin()),
646  Enable(boxReader.btnNext, !LastRead.IsAtEnd()));
647 }
648 
649 void
651 {
652 #if YCL_Win32
653  if(e.Keys[VK_RBUTTON])
654  {
655  ShowMenu(1U, e);
656  return;
657  }
658 #else
659  yunused(e);
660 #endif
661  if(tmrScrollActive)
662  StopAutoScroll();
663  else
664  {
665  if((nClick = tmrInput.RefreshClick(nClick)) > 1)
666  {
667  nClick = 0;
668  StartAutoScroll();
669  }
670  else if(nClick == 0)
671  ++nClick;
672  if(IsVisible(boxReader))
673  {
674  Close(boxReader);
675  reader.Stretch(0);
676  }
677  else
678  {
679  Show(boxReader);
680  reader.Stretch(boxReader.GetHeight());
681  }
682  }
683 }
684 
685 void
687 {
688  using namespace Timers;
689  using namespace KeyCodes;
690 
691  if(e.Strategy != RoutedEventArgs::Tunnel && !mhMain.IsShowing(1u)
692  && RepeatHeld(tmrInput, FetchGUIState().KeyHeldState,
693  TimeSpan(240), TimeSpan(60)))
694  {
695  const auto ntick(HighResolutionClock::now());
696 
697  //这里可以考虑提供暂停,不调整视图。
698  if(tmrScrollActive)
699  {
700  StopAutoScroll();
701  return;
702  }
703 
704  const auto& k(e.GetKeys());
705 
706  if(k.count() != 1)
707  return;
708  if(k[YCL_KEY_Start])
709  {
710  StartAutoScroll();
711  return;
712  }
713  if(k[KeyCodes::Enter])
714  reader.UpdateView();
715  else if(k[Esc])
716  Exit();
717  else if(k[Up])
718  reader.Execute(DualScreenReader::LineUpScroll);
719  else if(k[Down])
720  reader.Execute(DualScreenReader::LineDownScroll);
721  else if(k[YCL_KEY(X)] || k[YCL_KEY(Y)])
722  {
723  auto size(reader.GetFont().GetSize());
724 
725  e.Handled = true;
726  if(k[YCL_KEY(X)])
727  {
728  if(YB_LIKELY(size > Font::MinimalSize))
729  --size;
730  else
731  return;
732  }
733  else if(YB_LIKELY(size < Font::MaximalSize))
734  ++size;
735  else
736  return;
737  reader.SetFontSize(size);
738  reader.UpdateView();
739  }
740  else if(k[YCL_KEY(L)])
741  {
742  if(YB_LIKELY(reader.GetLineGap() != 0))
743  reader.SetLineGap(reader.GetLineGap() - 1);
744  }
745  else if(k[YCL_KEY(R)])
746  {
747  if(YB_LIKELY(reader.GetLineGap() != 12))
748  reader.SetLineGap(reader.GetLineGap() + 1);
749  }
750  else if(k[Left])
751  // else if(k[PgUp])
752  reader.Execute(DualScreenReader::ScreenUpScroll);
753  else if(k[Right])
754  // else if(k[PgDn])
755  reader.Execute(DualScreenReader::ScreenDownScroll);
756  else
757  return;
758  tmrInput.Delay(HighResolutionClock::now() - ntick);
759  e.Handled = true;
760  }
761 }
762 
763 
765  const shared_ptr<Desktop>& h_dsk_up, const shared_ptr<Desktop>& h_dsk_dn)
766  : ShlReader(pth, h_dsk_up, h_dsk_dn),
767  HexArea(Rect({}, MainScreenWidth, MainScreenHeight)), pnlFileInfo()
768 {
769  HexArea.SetRenderer(make_unique<BufferedRenderer>(true));
770  yunseq(
771  FetchEvent<KeyDown>(HexArea) += [this](KeyEventArgs&& e){
772  auto& keys(e.Keys);
773 
774  if(keys.count() == 1 && keys[KeyCodes::Esc])
775  Exit();
776  },
777  HexArea.ViewChanged += [this](HexViewArea::ViewArgs&&){
778  pnlFileInfo.lblSize.Text = u"当前位置: "
779  + String(to_string(HexArea.GetModel().GetPosition())
780  + " / " + to_string(HexArea.GetModel().GetSize()));
781  Invalidate(pnlFileInfo.lblSize);
782  }
783  );
784 
785  auto& dsk_m(GetMainDesktop());
786  auto& dsk_s(GetSubDesktop());
787  const string& path_str(pth);
788 
789  pnlFileInfo.lblPath.Text = u"文件路径:" + String(pth);
790 
791  struct ::stat file_stat;
792 
793  //在 DeSmuME 上无效; iDSL + DSTT 上访问时间精确不到日,修改时间正常。
794  ::stat(path_str.c_str(), &file_stat);
795  yunseq(
796  pnlFileInfo.lblAccessTime.Text = u"访问时间:"
797  + String(TranslateTime(file_stat.st_atime)),
798  pnlFileInfo.lblModifiedTime.Text = u"修改时间:"
799  + String(TranslateTime(file_stat.st_mtime))
800  );
801  dsk_m += pnlFileInfo;
802  HexArea.Load(path_str.c_str());
803  HexArea.UpdateData(0);
804  HexArea.ViewChanged(HexViewArea::ViewArgs(HexArea, true));
805  dsk_s += HexArea;
806  RequestFocusCascade(HexArea);
807 }
808 
809 } // namespace YReader;
810 
ReadingList & LastRead
近期浏览记录。
Definition: ShlReader.h:248
YF_API string MakeEscape(const string &)
转义字符串:替换指定字符串中的可转义字符。
Definition: Lexical.cpp:191
set< ValueNode > Container
Definition: ValueNode.h:48
bool Locate(Bookmark::PositionType)
定位到文本中的指定位置:更新阅读器状态、阅读列表和按钮状态。
Definition: ShlReader.cpp:547
pt pt Y const IWidget &wgt const IWidget &wgt GetSizeOf
无效化:使相对于部件的子部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: ywidget.h:156
Drawing::Color Color
Definition: YBrush.h:49
Shell 连接会话。
Definition: ShellHelper.h:67
GValueEventArgs< MTextList::IndexType > IndexEventArgs
索引事件。
Definition: textlist.h:47
const ValueNode & at(const string &) const
Definition: ValueNode.cpp:83
YF_API void SetLocationOf(IWidget &, const Point &)
设置部件左上角所在位置(相对于容器的偏移坐标)。
Definition: ywidget.cpp:73
yconstexpr EncodingInfoItem Encodings[]
编码信息。
Definition: ShellHelper.h:101
virtual void Refresh(PaintEventArgs &&)
刷新:按指定参数绘制界面并更新状态。
Definition: ShlReader.cpp:134
YF_API GUIState & FetchGUIState()
取默认图形用户界面公共状态。
Definition: ygui.cpp:442
static yconstexpr FontSize MinimalSize
Definition: Font.h:550
#define yunused(...)
标记未使用的表达式。
Definition: ydef.h:697
bool tmrScrollActive
滚屏计时器激活状态。
Definition: ShlReader.h:265
YF_API ValueNode & FetchRoot()
取值类型根节点。
size_t arrlen(_type(&)[_vN])
计算指定数组类型对象的长度。
Definition: utility.hpp:196
按键输入事件参数类。
Definition: ywgtevt.h:167
YF_API void FillRect(const Graphics &g, const Rect &, Color c)
填充标准矩形。
Definition: ydraw.cpp:146
YF_API void Invalidate(IWidget &, const Rect &)
无效化:使相对于部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: ywidget.cpp:111
Timers::Timer tmrScroll
滚屏计时器。
Definition: ShlReader.h:260
Label lblAreaUp
标签:文本区域示例。
ValueNode WidgetNode
Definition: Loader.h:251
部件绘制参数。
Definition: ywgtevt.h:276
std::function< void()> fBackgroundTask
背景任务:用于滚屏。
Definition: ShlReader.h:154
void Exit()
退出阅读器:停止后台任务并发送消息准备切换至 ShlExplorer 。
Definition: ShlReader.cpp:181
YF_API const char * TranslateTime(const std::tm &, const char *=DefaultTimeFormat)
格式化时间字符串。
Definition: ShellHelper.cpp:84
void Switch(Text::Encoding)
切换编码。
Definition: ShlReader.cpp:618
bool bExit
退出标识。
Definition: ShlReader.h:161
void UpdateButtons()
更新按钮状态。
Definition: ShlReader.cpp:643
YF_API bool Enable(IWidget &, bool=true)
设置部件可用性,且当可用性改变时无效化部件区域。
Definition: ycontrol.cpp:90
文本阅读器 Shell 。
Definition: ShlReader.h:215
size_t PositionType
文件位置类型。
Definition: ReadingList.h:49
面板。
Definition: ypanel.h:45
YF_API void OnTouchHeld_Dragging(CursorEventArgs &&)
处理屏幕接触移动事件:拖放按下部件。
Definition: ycontrol.cpp:144
阅读器设置。
Definition: ReaderSetting.h:41
ValueObject Value
Definition: ValueNode.h:59
YF_API void Hide(IWidget &)
隐藏部件。
Definition: ywidget.cpp:103
void split(_tIn b, _tIn e, _fPred is_delim, _fInsert insert)
以指定字符分割字符序列。
Definition: string.hpp:279
Button btnNext
前进按钮。
Definition: ShlReader.h:80
#define YCL_KEY_Start
Definition: Input.h:46
void unseq_apply(_fCallable &&f, _tParams &&...args)
无序调用。
Definition: functional.hpp:144
void StopAutoScroll()
停止自动滚屏。
Definition: ShlReader.cpp:610
~ShlTextReader() override
析构:释放资源。
Definition: ShlReader.cpp:485
对话框。
Definition: uicontx.h:46
#define ynew
Definition: ynew.h:205
YF_API void Show(IWidget &)
显示部件。
Definition: ywidget.cpp:206
void RemoveWidgets(_tCon &con, _tWidgets &...wgts)
从部件容器移除子部件。
Definition: yuicont.h:428
void AddWidgets(_tCon &con, _tWidgets &...wgts)
向部件容器添加子部件。
Definition: yuicont.h:400
控件。
Definition: ycontrol.h:275
YF_API void SaveConfiguration(const ValueNode &)
保存默认配置。
YF_API void Execute(GUIApplication &, shared_ptr< Shell >=make_shared< Shells::GUIShell >())
执行程序主消息循环。
size_t ID
菜单标识类型。
Definition: menu.h:55
String Text
标签文本。
Definition: label.h:76
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
Label lblTop
指示迭代器位置。
Definition: ShlReader.h:115
unique_ptr< TextFile > pTextFile
Definition: ShlReader.h:284
BookmarkPanel pnlBookmark
书签管理面板。
Definition: ShlReader.h:291
GBinaryGroup< SPos > Point
屏幕二维点(直角坐标表示)。
Definition: ygdibase.h:235
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
void UpdateData(DualScreenReader &)
更新进度数据。
Definition: ShlReader.cpp:95
IO::Path CurrentPath
当前路径。
Definition: ShlReader.h:149
YF_API ValueNode LoadConfiguration(bool={})
载入默认配置。
static void SaveGlobalConfiguration(const ReaderSetting &)
保存阅读器配置。
Definition: ShlReader.cpp:268
void OnClick(CursorEventArgs &&)
Definition: ShlReader.cpp:650
static BookmarkList LoadBookmarks(const string &)
Definition: ShlReader.cpp:200
ProgressBar pbReader
Definition: ShlReader.h:81
_tWidget & wgt
Definition: ywgtevt.h:596
bool Activate(const shared_ptr< Shell > &hShl)
激活 Shell 对象:控制权转移给此对象以维持单线程运行。
Definition: yapp.h:164
void Show(Menu::ID, ZOrderType=DefaultMenuZOrder)
按指定 Z 顺序显示菜单组中菜单标识指定的菜单。
Definition: menu.cpp:300
屏幕标准矩形:表示屏幕矩形区域。
Definition: ygdibase.h:416
size_t RefreshClick(size_t, const Duration &=Timers::TimeSpan(400))
重复检测连续点击状态。
Definition: ygui.cpp:99
ShlHexBrowser(const IO::Path &, const shared_ptr< Desktop > &={}, const shared_ptr< Desktop > &={})
构造:使用指定路径和上下屏幕。
Definition: ShlReader.cpp:764
GSStringTemplate< char >::basic_string string
Definition: ycont.h:164
void ShowMenu(Menu::ID, const Point &)
Definition: ShlReader.cpp:581
void Scroll()
当自动滚屏有效状态为 true 时超时自动滚屏。
Definition: ShlReader.cpp:568
表示菜单键(如 Menu 和 Win )。
Definition: Keys.h:129
YF_API void RequestFocusCascade(IWidget &)
级联请求部件及上层容器焦点。
Definition: yfocus.cpp:138
vector< Bookmark::PositionType > BookmarkList
书签列表类型。
Definition: ReadingList.h:82
空字符集。
Definition: encoding.h:56
子部件绘制仿函数。
Definition: ShellHelper.h:477
void Execute(IndexEventArgs::ValueType)
执行阅读器命令。
Definition: ShlReader.cpp:499
TextInfoBox boxTextInfo
Definition: ShlReader.h:281
errno_t NowShellTo(const shared_ptr< Shell > &hShl)
向句柄指定的 Shell 对象转移线程控制权。
Definition: ShellHelper.h:187
void LoadFile(const IO::Path &)
读取文件。
Definition: ShlReader.cpp:532
_tString && ltrim(_tString &&str, typename string_traits< _tString >::const_pointer t=&to_array< typename string_traits< _tString >::value_type >("\n\r\t\v ")[0])
删除字符串中指定的连续前缀字符。
Definition: string.hpp:222
void Insert(const IO::Path &, size_t)
插入阅读记录。
Definition: ReadingList.cpp:51
p1 p1 Y
Definition: ydraw.h:188
SettingPanel pnlSetting
设置面板。
Definition: ShlReader.h:283
Button btnPrev
后退按钮。
Definition: ShlReader.h:75
_type & parameterize_static_object()
类型参数化静态对象。
Definition: utility.hpp:276
std::string to_string(unsigned char val)
转换为字符串。
Definition: string.hpp:353
String FetchEncodingString(MTextList::IndexType)
取编码字符串。
Color
控制台颜色枚举。
Definition: Video.h:458
ShlReader(const IO::Path &, const shared_ptr< Desktop > &={}, const shared_ptr< Desktop > &={})
构造:使用指定路径和上下桌面。
Definition: ShlReader.cpp:174
YF_API void ResetDSDesktops(Desktop &, Desktop &)
以默认屏幕复位两个桌面。
Definition: shlds.cpp:60
static yconstexpr FontSize MaximalSize
Definition: Font.h:550
unique_ptr< BaseSession > session_ptr
Definition: ShlReader.h:295
void OnKeyDown(KeyEventArgs &&)
Definition: ShlReader.cpp:686
#define YCL_KEY(X)
Definition: Input.h:45
单色画刷。
Definition: YBrush.h:46
bounds & r
Definition: ydraw.h:220
void erase_all_if(_tRange &c, _fPred pred)
删除指定序列范围中满足条件的元素。
Definition: container.hpp:416
void UpdateReadingList(bool)
更新近期浏览记录并更新按钮状态。
Definition: ShlReader.cpp:629
ReaderSetting CurrentSetting
当前阅读器设置。
Definition: ShlReader.h:253
void UpdateData(DualScreenReader &)
Definition: ShlReader.cpp:143
#define YB_LIKELY(expr)
Definition: ydef.h:297
Color ForeColor
默认前景色。
Definition: ywidget.h:375
void SetBufferRendererAndText(_tWidget &wgt, const String &s)
设置部件渲染器为 BufferedRenderer 及部件的 Text 成员。
Definition: ShellHelper.h:504
ShlTextReader(const IO::Path &, const shared_ptr< Desktop > &={}, const shared_ptr< Desktop > &={})
构造:使用指定路径和上下桌面。
Definition: ShlReader.cpp:350
virtual void Refresh(PaintEventArgs &&)
刷新:按指定参数绘制界面并更新状态。
Definition: ywidget.cpp:264
std::chrono::milliseconds TimeSpan
低精度时间间隔。
Definition: ytimer.h:85
隧道事件:向下遍历视图树时触发。
Definition: ywgtevt.h:103
DualScreenReader reader
Definition: ShlReader.h:279
const first_tag get_key
Definition: iterator.hpp:784
void StartAutoScroll()
开始自动滚屏。
Definition: ShlReader.cpp:602
void ResizeForContent(TextList &tl)
Definition: textlist.cpp:423
阅读记录。
Definition: ReadingList.h:90
屏幕区域大小。
Definition: ygdibase.h:249
InputTimer tmrInput
按键计时器。
Definition: ShlReader.h:271
static ReaderSetting LoadGlobalConfiguration()
载入阅读器配置。
Definition: ShlReader.cpp:226
string CopySliceFrom(TextFileBuffer &buf, size_t pos, size_t len) ythrow(std
Definition: textmgr.cpp:258
指针设备输入事件参数类。
Definition: ywgtevt.h:183
void OnInput() override
处理输入消息:发送绘制消息,当处于滚屏状态时自动执行滚屏。
Definition: ShlReader.cpp:239
Shell 阅读器框架。
void Close(IWidget &wgt)
Definition: ywidget.cpp:95
ReaderBox(const Rect &)
Definition: ShlReader.cpp:62
void PostTask(_fCallable &&f, Messaging::Priority prior=Messaging::NormalPriority)
通过消息队列部署后任务。
Definition: Task.h:43
_type ValueType
值类型。
Definition: ywgtevt.h:255
文件浏览器。
BookmarkList bookmarks
当前打开文件的书签列表。
Definition: BookmarkUI.h:60
GValueEventArgs< bool > ViewArgs
视图参数类型。
Definition: HexBrowser.h:156
YF_API bool RepeatHeld(InputTimer &, InputTimer::HeldStateType &, const Timers::Duration &, const Timers::Duration &)
向指定计时器传递参数,根据状态重复按键。
Definition: ygui.cpp:117
static void SaveBookmarks(const string &, const BookmarkList &)
Definition: ShlReader.cpp:247
size_t nClick
记录点击次数。
Definition: ShlReader.h:276