YSTest: viewer.hpp 源文件

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
34 YSL_BEGIN
35
36 YSL_BEGIN_NAMESPACE(UI)
37
38
42 template<class _tContainer>
43 class GSequenceViewer
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
325 YSL_END_NAMESPACE(UI)
326
327 YSL_END
328
329 #endif
330