YSTest  PreAlpha_b400_20130424
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
viewer.hpp
浏览该文件的文档.
1 /*
2  Copyright by FrankHB 2011 - 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 #ifndef YSL_INC_UI_viewer_hpp_
29 #define YSL_INC_UI_viewer_hpp_ 1
30 
31 #include "ycomp.h"
32 #include <ystdex/algorithm.hpp>
33 
35 
37 
38 
42 template<class _tContainer>
44 {
45 public:
50  typedef _tContainer ContainerType;
51  typedef typename _tContainer::size_type SizeType;
52  typedef typename _tContainer::difference_type DifferenceType; \
54 
56  static_assert(std::is_unsigned<SizeType>::value,
57  "Invalid size type found!");
59  static_assert(std::is_signed<DifferenceType>::value,
60  "Invalid difference type found!");
61 
62 private:
68  _tContainer* pContainer;
69  SizeType head;
70  SizeType selected;
71  SizeType length;
72  bool is_selected;
73 
74 public:
80  explicit
81  GSequenceViewer(ContainerType& con)
82  : pContainer(&con), head(0), selected(0), length(1), is_selected(false)
83  {}
84 
85  inline PDefHOp(GSequenceViewer&, ++, )
86  ImplRet(IncreaseSelected(1))
87  inline PDefHOp(GSequenceViewer&, --, )
88  ImplRet(IncreaseSelected(-1))
89  inline PDefHOp(GSequenceViewer&, ++, int) \
91  ImplRet(IncreaseHead(1))
92  inline PDefHOp(GSequenceViewer&, --, int) \
94  ImplRet(IncreaseHead(-1))
95 
99  DefPred(const ynothrow, Selected, is_selected)
100 
104  bool
105  Contains(SizeType i) const
106  {
107  return GetTotal() != 0 && GetLength() != 0
108  && IsInInterval<SizeType>(i - GetHeadIndex(), GetLength());
109  }
110 
111  DefGetter(const ynothrow, SizeType, Total, pContainer->size()) \
113  DefGetter(const ynothrow, SizeType, Length, length)
114  DefGetter(const ynothrow, SizeType, HeadIndex, head)
115  DefGetter(const ynothrow, SizeType, SelectedIndex, selected)
116  DefGetter(const ynothrow, DifferenceType, Offset, IsSelected()
117  ? GetSelectedIndex() - GetHeadIndex() : -1) \
119  DefGetter(const ynothrow, SizeType, Valid, min(GetTotal() - GetHeadIndex(),
120  GetLength()))
121 
127  void
128  SetContainer(ContainerType& con)
129  {
130  if(YB_LIKELY(pContainer != &con))
131  yunseq(pContainer = &con, selected = 0, head = 0, length = 1);
132  }
136  bool
137  SetHeadIndex(SizeType t)
138  {
139  if(t < GetTotal() && t != head)
140  {
141  if(t == 0)
142  MoveViewerToBegin();
143  else if(length + t > GetTotal())
144  MoveViewerToEnd();
145  else
146  head = t;
147  return true;
148  }
149  return false;
150  }
154  bool
155  SetLength(SizeType l)
156  {
157  if(l != length)
158  {
159  length = l;
160  return true;
161  }
162  return false;
163  }
167  bool
168  SetSelectedIndex(SizeType t)
169  {
170  if(t < GetTotal() && !(t == selected && is_selected))
171  {
172  selected = t;
173  RestrictView();
174  is_selected = true;
175  return true;
176  }
177  return false;
178  }
179 
187  bool
188  AdjustForContent()
189  {
190  const auto total(GetTotal());
191 
192  if(total != 0)
193  {
194  if(!(selected < total))
195  selected = total - 1;
196  return RestrictView();
197  }
198  else
199  Reset();
200  return true;
201  }
202 
206  inline void
207  ClearSelected()
208  {
209  is_selected = false;
210  }
211 
212  inline PDefH(GSequenceViewer&, DecreaseHead, DifferenceType d) \
214  ImplRet(IncreaseHead(-d))
215 
216  inline PDefH(GSequenceViewer&, DecreaseSelected, DifferenceType d) \
218  ImplRet(IncreaseSelected(-d))
219 
224  GSequenceViewer&
225  IncreaseHead(DifferenceType d)
226  {
227  int t(head + d);
228 
229  RestrictInInterval(t, 0, int(GetTotal()));
230  SetHeadIndex(t);
231  return *this;
232  }
233 
238  GSequenceViewer&
239  IncreaseSelected(DifferenceType d)
240  {
241  int t(selected + d);
242 
243  RestrictInInterval(t, 0, int(GetTotal()));
244  SetSelectedIndex(t);
245  return *this;
246  }
247 
251  bool
252  MoveViewerToBegin()
253  {
254  if(head)
255  {
256  head = 0;
257  return true;
258  }
259  return false;
260  }
261 
265  bool
266  MoveViewerToEnd()
267  {
268  if(GetTotal() < length)
269  return false;
270  head = GetTotal() - length;
271  return true;
272  }
273 
278  void
279  Reset()
280  {
281  yunseq(head = 0, selected = 0, length = 1, is_selected = false);
282  }
283 
290  bool
291  RestrictSelected()
292  {
293  if(GetTotal() == 0)
294  return false;
295  if(selected < head)
296  selected = head;
297  else if(selected < head + length)
298  return false;
299  else
300  selected = head + length - 1;
301  return true;
302  }
303 
310  bool
311  RestrictView()
312  {
313  if(GetTotal() == 0)
314  return false;
315  if(selected < head)
316  head = selected;
317  else if(selected < head + length)
318  return false;
319  else
320  head = selected + 1 - length;
321  return true;
322  }
323 };
324 
326 
327 YSL_END
328 
329 #endif
330