YSTest: TreeView.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

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

- 文件列表
- 文件成员

TreeView.cpp
浏览该文件的文档.
1 /*
2 © 2014-2016 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 "YSLib/UI/YModules.h"
29 #include YFM_YSLib_UI_TreeView
30 #include <ystdex/utility.hpp> // for ystdex::as_const;
31
32 namespace YSLib
33 {
34
35 namespace UI
36 {
37
38 namespace
39 {
40
45 template<class _tNode, typename _fCallable, typename _fPred, class _tPath>
46 void
47 bind_node(const _tNode& node, _fCallable f, _fPred pred, const _tPath& pth,
48 size_t depth = 0)
49 {
50 if(!node.empty() && pred(pth, depth))
51 {
52 auto cur_path(pth);
53
54 cur_path.push_back(0),
55 ++depth;
56 for(const auto& nd : node)
57 {
58 f(nd, cur_path, depth);
59 bind_node(nd, f, pred, cur_path, depth);
60 ++cur_path.back();
61 }
62 }
63 }
64
65 } // unnamed namespace;
66
67 TreeList::TreeList(const Rect& r, const shared_ptr<ListType>& h,
68 const pair<Color, Color>& hilight_pair)
69 : TextList(r, h, hilight_pair)
70 {
71 auto& unit(GetUnitRef());
72
73 yunseq(
74 FetchEvent<KeyDown>(*this) += [&](KeyEventArgs&& e){
75 if(!GetList().empty() && IsSelected())
76 {
77 using namespace KeyCodes;
78 const auto& k(e.GetKeys());
79
80 if(k.count() == 1)
81 {
82 if(k[Left])
83 {
84 const auto idx(GetSelectedIndex());
85
86 if(CollapseNode(idx) == NodeState::Expanded)
87 UpdateView(*this);
88 else
89 {
90 auto i(indent_map.lower_bound(idx));
91
92 SetSelected(
93 i != indent_map.cbegin() ? (--i)->first : 0);
94 }
95 }
96 else if(k[Right])
97 {
98 const auto idx(GetSelectedIndex());
99 const auto st(ExpandNode(idx));
100
101 if(st == NodeState::Branch)
102 UpdateView(*this);
103 else if(st == NodeState::Expanded)
104 {
105 const auto i(indent_map.lower_bound(idx + 1));
106
107 if(i != indent_map.cend() && i->first > idx)
108 SetSelected(idx + 1);
109 }
110 }
111 }
112 }
113 e.Handled = true;
114 },
115 FetchEvent<TouchDown>(unit) += [this](CursorEventArgs&& e){
116 const auto st(QueryNodeState(idxShared));
117
118 if(st != NodeState::None)
119 {
120 Rect box(GetIndentBox());
121
122 // XXX: Conversion to 'SPos' might be implementation-defined.
123 box.X += SPos(GetIndentWidth(idxShared));
124 if(box.Contains(e) || FetchGUIState().RefreshTap(e) > 1)
125 {
126 ExpandOrCollapseNodeImpl(st, idxShared);
127 UpdateView(*this);
128 }
129 }
130 },
131 FetchEvent<CursorOver>(unit) += [this](CursorEventArgs&& e)
132 {
133 if(QueryNodeState(idxShared) != NodeState::None)
134 {
135 const Rect& box(GetIndentBoxBounds(idxShared));
136 const auto old(idxCursorOver);
137
138 idxCursorOver = box.Contains(e) ? idxShared : size_t(-1);
139 if(old != idxCursorOver)
140 Invalidate(e.GetSender(), box);
141 }
142 },
143 FetchEvent<Leave>(unit) += [this]{
144 if(idxCursorOver != size_t(-1)
145 && QueryNodeState(idxCursorOver) != NodeState::None)
146 {
147 Invalidate(GetUnitRef(), GetIndentBoxBounds(idxCursorOver));
148 idxCursorOver = size_t(-1);
149 }
150 },
151 // TODO: Add %AddFront method.
152 FetchEvent<Paint>(unit).Add([this](PaintEventArgs&& e){
153 tmp_margin_left = LabelBrush.Margin.Left;
154 // XXX: Conversion to 'SPos' might be implementation-defined.
155 LabelBrush.Margin.Left += SPos(GetIndentWidth(idxShared));
156 switch(QueryNodeState(idxShared))
157 {
158 case NodeState::Branch:
159 DrawArrow(e.Target, e.ClipArea, GetIndentBox() + Vec(e.Location.X,
160 e.Location.Y - 1), 5, RDeg0, idxCursorOver == idxShared
161 ? CursorOverColor : LabelBrush.ForeColor, true);
162 break;
163 case NodeState::Expanded:
164 // XXX: Conversion to 'SPos' might be implementation-defined.
165 DrawCornerArrow(e.Target, e.ClipArea, e.Location
166 + Vec(LabelBrush.Margin.Left - SPos(UnitIndent) + 2, 2), 7,
167 RDeg0, idxCursorOver == idxShared ? CursorOverColor
168 : LabelBrush.ForeColor);
169 break;
170 default:
171 ;
172 }
173 }, BackgroundPriority - 1).Add([this]{
174 LabelBrush.Margin.Left = tmp_margin_left;
175 }, 0)
176 );
177 }
178 ImplDeDtor(TreeList)
179
180 String
181 TreeList::DefaultExtractText(const ValueNode& node)
182 {
183 return Access<string>(node);
184 }
185
186 String
187 TreeList::ExtractNodeName(const ValueNode& node)
188 {
189 return node.GetName();
190 }
191
192 Rect
193 TreeList::GetIndentBox() const
194 {
195 // XXX: Conversion to 'SPos' might be implementation-defined.
196 return Rect(LabelBrush.Margin.Left - SPos(UnitIndent) - 2, 0,
197 GetIndentBoxSize());
198 }
199 Rect
200 TreeList::GetIndentBoxBounds(size_t idx) const
201 {
202 // XXX: Conversion to 'SPos' might be implementation-defined.
203 return GetIndentBox() + Vec(SPos(GetIndentWidth(idx)),
204 (ptrdiff_t(idx) - ptrdiff_t(idxShared)) * SPos(GetItemHeight()));
205 }
206
207 SDst
208 TreeList::GetIndentWidth(IndexType idx) const
209 {
210 const auto i(indent_map.lower_bound(idx));
211
212 return SDst((i != indent_map.cend() ? i->second : 0) * UnitIndent);
213 // TODO: Use more concrete exception class.
214 // throw std::runtime_error("Invalid tree list state found.");
215 }
216 TreeList::NodePath
217 TreeList::GetNodePath(TreeList::IndexType idx) const
218 {
219 const auto i(indent_map.lower_bound(idx));
220
221 if(i != indent_map.cend())
222 {
223 auto indent(i->second);
224 vector<IndexType> seq(indent);
225 size_t n(0);
226 pair<IndexType, IndentType> last(idx, indent);
227
228 std::for_each(ystdex::make_reverse_iterator(i), indent_map.crend(),
229 [&](decltype(*indent_map.crend()) pr){
230 if(last.second <= indent)
231 {
232 YAssert(pr.first < last.first, "Invalid state found.");
233 n += last.first - pr.first;
234 }
235 if(pr.second < indent)
236 {
237 YAssert(indent > 0, "Invalid indent found");
238 seq[indent - 1] += n - 1;
239 yunseq(n = 0, indent = pr.second);
240 }
241 last = pr;
242 });
243 YAssert(indent > 0, "Invalid indent found");
244 seq[indent - 1] += n + last.first;
245 return seq;
246 }
247 return {};
248 }
249 const ValueNode&
250 TreeList::GetNodeRef(IndexType idx) const
251 {
252 return AccessNode(TreeRoot, GetNodePath(idx));
253 }
254
255 void
256 TreeList::Bind(size_t max_depth)
257 {
258 IndentMap imap;
259 ListType lst;
260 decltype(expanded) exp;
261 // TODO: Simplify using tuple or similar construct?
262 #if false
263 // XXX: These checks cannot be used since %propagate_on_container_swap or
264 // ISO C++17 %is_always_equal member of %allocator_traits
265 // is not used and container types are meeting nothrow swapping guarantee
266 // but not noexcept specificication yet.
267 static_assert(ystdex::is_nothrow_swappable<ListType>(),
268 "Invalid type found.");
269 static_assert(ystdex::is_nothrow_swappable<IndentMap>(),
270 "Invalid type found.");
271 static_assert(ystdex::is_nothrow_swappable<decltype(exp)>(),
272 "Invalid type found.");
273 #endif
274 IndentType indent(1);
275 auto index(IndexType(-1));
276 const auto bind_insert([&](size_t depth){
277 imap.emplace(index, indent);
278 indent = depth;
279 });
280
281 // TODO: Optimize implementation.
282 // TODO: Merge implementation with %ExpandOrCollapseNodeImpl?
283 bind_node(TreeRoot, [&, this](const ValueNode& node,
284 const NodePath& pth, size_t depth){
285 lst.push_back(ExtractText(node));
286 if(indent != depth)
287 bind_insert(depth);
288 if(depth < max_depth && !node.empty())
289 exp.insert(pth);
290 ++index;
291 }, [&](const NodePath&, size_t depth) ynothrow -> bool{
292 if(depth < max_depth)
293 return true;
294 bind_insert(depth);
295 return {};
296 }, NodePath());
297 if(index != IndexType(-1))
298 imap.emplace(index, indent);
299 std::swap(GetListRef(), lst),
300 std::swap(indent_map, imap),
301 std::swap(expanded, exp);
302 }
303
304 TreeList::NodeState
305 TreeList::ExpandOrCollapseNode(NodeState expected, size_t idx)
306 {
307 const auto st(QueryNodeState(idx));
308
309 if(st == expected)
310 ExpandOrCollapseNodeImpl(expected, idx);
311 return st;
312 }
313
314 void
315 TreeList::ExpandOrCollapseNodeImpl(NodeState st, size_t idx)
316 {
317 YAssert(QueryNodeState(idx) == st, "Invalid internal state found."),
318 YAssert(st != NodeState::None, "Invalid state argument found.");
319
320 const auto& branch_pth(GetNodePath(idx));
321
322 if(YB_UNLIKELY(branch_pth.empty()))
323 throw std::runtime_error("Invalid state found.");
324 // FIXME: Strong exception safety guarantee.
325 if(st == NodeState::Branch)
326 {
327 Expand(idx);
328 // TODO: Check state.
329 expanded.insert(branch_pth);
330
331 const auto& branch(AccessNode(TreeRoot, branch_pth));
332 auto i(ystdex::as_const(indent_map).lower_bound(idx));
333
334 YAssert(i != indent_map.cend(), "Invalid state found.");
335
336 const auto idt(i->second);
337 auto j(i);
338
339 if(i->first != idx)
340 j = indent_map.emplace_hint(i, idx, idt);
341 else
342 {
343 ++i;
344 YAssert(i == indent_map.cend() || i->second <= idt,
345 "Invalid state found.");
346 }
347
348 IndexType index(idx);
349 IndentType indent(idt + 1);
350 vector<pair<IndexType, IndentType>> vec_ins;
351 vector<String> text_list;
352 const auto bind_insert([&](size_t depth){
353 vec_ins.emplace_back(index, indent);
354 indent = depth;
355 });
356
357 // TODO: Optimize implementation.
358 // TODO: Merge implementation with %Bind?
359 bind_node(branch,
360 [&, this](const ValueNode& node, const NodePath&, size_t depth){
361 text_list.push_back(ExtractText(node));
362 if(indent != depth)
363 bind_insert(depth);
364 ++index;
365 }, [&, this](const NodePath& pth, size_t depth) -> bool{
366 if(ystdex::exists(expanded, pth))
367 return true;
368 bind_insert(depth);
369 return {};
370 }, branch_pth, idt);
371 YAssert(index != idx, "Invalid state found.");
372 vec_ins.emplace_back(index, indent);
373 YAssert(vec_ins.back().first > j->first,
374 "Invalid insertion sequence found");
375 // FIXME: Strong exception safety guarantee.
376 // NOTE: See $2014-09 @ %Documentation::Workflow::Annual2014.
377 {
378 // XXX: Use %std::make_move_iterator if proper.
379 vector<pair<IndentType, IndexType>>
380 vec(i, indent_map.cend());
381 const auto n(vec_ins.back().first - j->first);
382
383 for(auto& pr : vec)
384 pr.first += n;
385 i = ystdex::insert_reversed(indent_map,
386 indent_map.erase(i, indent_map.end()),
387 vec.rbegin(), vec.rend());
388 }
389 ystdex::insert_reversed(indent_map, i,
390 vec_ins.crbegin(), vec_ins.crend());
391
392 auto& lst(GetListRef());
393
394 // XXX: Reuse previous operation.
395 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63500.
396 #if defined(_GLIBCXX_DEBUG) && YB_IMPL_GNUCPP < 40902
397 lst.insert(lst.cbegin() + ptrdiff_t(idx) + 1, text_list.begin(),
398 text_list.end());
399 #else
400 lst.insert(lst.cbegin() + ptrdiff_t(idx) + 1, std::make_move_iterator(
401 text_list.begin()), std::make_move_iterator(text_list.end()));
402 #endif
403 }
404 else
405 {
406 auto i(ystdex::as_const(indent_map).find(idx));
407
408 YAssert(i != indent_map.cend(), "Invalid state found.");
409
410 const auto idt(i->second);
411
412 if(++i != indent_map.cend())
413 {
414 auto& lst(GetListRef());
415
416 YAssert(idx < i->first, "Invalid state found.");
417 YAssert(i->first < lst.size(), "Invalid list found.");
418
419 auto j(std::find_if_not(i, indent_map.cend(),
420 [&, idt](decltype(*i) pr) ynothrow{
421 return idt < pr.second;
422 }));
423
424 const auto n(std::prev(j)->first - idx);
425
426 // XXX: Conversion to 'SPos' might be implementation-defined.
427 yunseq(ystdex::erase_n(lst, std::next(lst.cbegin(),
428 ptrdiff_t(idx + 1)), ptrdiff_t(n)), indent_map.erase(i, j));
429 #if true
430 {
431 // XXX: Use %std::make_move_iterator if proper.
432 vector<pair<IndentType, IndexType>>
433 vec(j, indent_map.cend());
434
435 for(auto& pr : vec)
436 pr.first -= n;
437 ystdex::insert_reversed(indent_map, indent_map.erase(j,
438 indent_map.end()), vec.rbegin(), vec.rend());
439 }
440 #else
441 // NOTE: See $2014-09 @ %Documentation::Workflow::Annual2014.
442 for(; j != indent_map.cend(); ++j)
443 j = ystdex::replace_value(indent_map, j->first,
444 [n](decltype(*indent_map.cbegin()) pr){
445 return make_pair(pr.first - n, pr.second);
446 });
447 #endif
448 // TODO: Check state.
449 expanded.erase(branch_pth);
450 Collapse(idx);
451 }
452 }
453 }
454
455 TreeList::NodeState
456 TreeList::QueryNodeState(IndexType idx) const
457 {
458 if(!GetNodeRef(idx).empty())
459 {
460 auto i(indent_map.find(idx));
461 const auto e(indent_map.cend());
462
463 if(i != e)
464 {
465 const auto indent(i->second);
466
467 // TODO: Optimize.
468 return ++i != e && i->second == indent + 1
469 && ystdex::exists(expanded, GetNodePath(idx))
470 ? NodeState::Expanded : NodeState::Branch;
471 }
472 }
473 return NodeState::None;
474 }
475
476
477 TreeView::TreeView(const Rect& r, const shared_ptr<ListType>& h)
478 : ListBox(r, unique_ptr<TextList>(new TreeList(Rect(r.GetSize()), h)))
479 {}
480 ImplDeDtor(TreeView)
481
482 } // namespace UI;
483
484 } // namespace YSLib;
485
YSLib::UI::TreeList
树形列表。
Definition: TreeView.h:50
ystdex::make_reverse_iterator
std::reverse_iterator< _tIter > make_reverse_iterator(_tIter i)
构造反向迭代器。
Definition: iterator_op.hpp:107
YSLib::UI::TextList::UpdateView
YF_API void UpdateView(TextList &, bool is_active={})
更新文本列表视图。
Definition: ListControl.cpp:425
YSLib::UI::TextList::SetSelected
void SetSelected(ListType::size_type)
按指定项目索引设置选中项目。
Definition: ListControl.cpp:275
YSLib::Drawing::Rect::Contains
bool Contains(SPos px, SPos py) const ynothrow
判断点 (px, py) 是否在矩形内或边上。
Definition: YGDIBase.cpp:92
ystdex::swap
void swap(container_adaptor< _tSeqCon > &x, container_adaptor< _tSeqCon > &y)
Definition: container.hpp:179
YSLib::UI::TreeList::CursorOverColor
Color CursorOverColor
响应 CursorOver 事件时节点分支图标的颜色。
Definition: TreeView.h:80
YSLib::UI::TreeList::QueryNodeState
NodeState QueryNodeState(IndexType) const
查询指定索引的列表项对应的节点状态。
Definition: TreeView.cpp:456
YSLib::UI::TreeView::TreeView
TreeView(const Rect &={}, const shared_ptr< ListType > &={})
Definition: TreeView.cpp:477
platform::KeyCodes
本机按键编码。
Definition: Keys.h:203
utility.hpp
实用设施。
YSLib::UI::FetchGUIState
GUIState & FetchGUIState() ynothrow
Definition: YGUI.cpp:508
YSLib::UI::TreeList::NodePath
vector< IndexType > NodePath
Definition: TreeView.h:65
YSLib::UI::MLabel::Margin
Drawing::Padding Margin
文本和容器的间距。
Definition: Label.h:79
YSLib::UI::MTextList::ListType
vector< ItemType > ListType
列表类型。
Definition: ListControl.h:142
YSLib::UI::AMUnitControlList::GetUnitRef
IWidget & GetUnitRef() const ImplI(AMUnitList)
Definition: ListControl.cpp:50
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:45
YSLib::UI::TreeList::TreeRoot
ValueNode TreeRoot
数据源。
Definition: TreeView.h:85
YSLib::UI::TreeList::ExtractText
std::function< String(const ValueNode &)> ExtractText
提取文本。
Definition: TreeView.h:75
YSLib::UI::empty
!sv empty()&&sv.front()!
YSLib::Drawing::GBinaryGroup::X
_type X
Definition: YGDIBase.h:63
YSLib::UI::MLabel::ForeColor
Color ForeColor
默认前景色。
Definition: Label.h:77
YSLib::UI::TreeList::NodeState::Branch
YSLib::UI::TreeList::tmp_margin_left
SPos tmp_margin_left
Definition: TreeView.h:107
YSLib::UI::TreeList::CollapseNode
CollapseNode
Definition: TreeView.h:175
YSLib::UI::TreeList::Expand
GEvent< void(IndexType)> Expand
展开节点前的回调。
Definition: TreeView.h:70
YSLib::UI::TreeList::IndentType
size_t IndentType
缩进类型：用于表示视图中项目的层次。
Definition: TreeView.h:54
YSLib::AccessNode
name name name name YF_API ValueNode & AccessNode(ValueNode &, size_t)
Definition: ValueNode.cpp:81
YSLib::UI::TreeList::GetIndentWidth
const IndentMap indent_map SDst GetIndentWidth(IndexType) const
Definition: TreeView.cpp:208
YSLib::Text::String
YSLib 标准字符串（使用 UCS-2 作为内部编码）。
Definition: YString.h:46
YSLib::UI::TreeList::GetNodePath
NodePath GetNodePath(IndexType) const
Definition: TreeView.cpp:217
ystdex::is_nothrow_swappable
Definition: type_traits.hpp:530
YSLib::UI::ImplDeDtor
ImplDeDtor(Thumb) void DecorateAsCloseButton(Thumb &tmb)
Definition: Button.cpp:125
YSLib::UI::Invalidate
YF_API void Invalidate(IWidget &, const Rect &)
无效化：使相对部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: YWidget.cpp:108
YSLib::size_t
name const ValueNode::Container const string &name ynothrow observer_ptr< ValueNode::Container > const string &name ynothrow observer_ptr< const ValueNode::Container > const string &name ynothrow size_t
Definition: ValueNode.h:639
YSLib::ynothrow
YB_PURE const _type size_t n ynothrow
Definition: YCoreUtilities.h:168
YSLib::UI::TreeList::Collapse
GEvent< void(IndexType)> Collapse
收缩节点后的回调。
Definition: TreeView.h:68
YSLib::UI::TreeList::NodeState
NodeState
节点状态。
Definition: TreeView.h:56
YSLib::UI::TreeList::UnitIndent
SDst UnitIndent
单元缩进：指定在界面上显示层次的水平距离和缩进值的比。
Definition: TreeView.h:87
YSLib::UI::AMUnitList::GetItemHeight
SDst GetItemHeight() const
取项目行高：调用 GetItemHeightCore 取结果。
Definition: Viewer.cpp:167
ystdex::exists
bool exists(const _tCon &con, const _tKey &key)
判断指定的容器中存在指定的键。
Definition: container.hpp:677
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:438
YSLib::UI::BackgroundPriority
yconstexpr const EventPriority BackgroundPriority(0xC0)
用户界面绘制优先级。
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:42
YSLib::Drawing::Vec
GBinaryGroup< SPos > Vec
屏幕二维向量（直角坐标表示）。
Definition: YGDIBase.h:285
YSLib::UI::TreeList::idxCursorOver
size_t idxCursorOver
最近响应 CursorOver 的项的索引。
Definition: TreeView.h:95
YSLib::UI::TreeList::TreeList
TreeList(const Rect &={}, const shared_ptr< ListType > &={}, const pair< Color, Color > &=FetchGUIConfiguration().Colors.GetPair(Styles::Highlight, Styles::HighlightText))
构造：使用指定边界、文本列表和高亮背景色/文本色对。
Definition: TreeView.cpp:67
YSLib::UI::TreeList::GetIndentBox
Rect GetIndentBox() const
取相对单元部件的基准缩进框边界。
Definition: TreeView.cpp:193
YSLib::UI::Widget::SDst
SDst
Definition: YWidget.h:454
YSLib::YAssert
YAssert(!(v< Deref(a)),"Value less than lower bound found.")
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:996
YSLib::UI::CursorEventArgs
指针设备输入事件参数类。
Definition: YWidgetEvent.h:210
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: YGDIBase.h:540
YSLib::UI::TreeList::GetNodeRef
const ValueNode & GetNodeRef(IndexType) const
Definition: TreeView.cpp:250
YSLib::Drawing::DrawCornerArrow
YF_API void DrawCornerArrow(const Graphics &, const Rect &, const Point &, SDst=4, Rotation=RDeg0, Color=ColorSpace::Black, bool={})
在指定图形接口上下文上描画腰和坐标轴共线的等腰直角三角形箭头。
Definition: YStyle.cpp:230
YSLib::UI::MTextList::IndexType
typename ListType::size_type IndexType
索引类型。
Definition: ListControl.h:143
YSLib::UI::TreeList::NodeState::Expanded
YSLib::ValueNode::empty
const container container empty
Definition: ValueNode.h:410
ystdex::insert_reversed
_tCon::const_iterator insert_reversed(_tCon &con, typename _tCon::const_iterator i, _tIn first, _tIn last)
逆向插入范围到容器的指定位置。
Definition: container.hpp:463
YSLib::Drawing::r
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect & r
Definition: YDraw.h:174
YSLib::UI::TreeList::expanded
set< NodePath > expanded
判断是否已经展开的索引。
Definition: TreeView.h:116
YSLib::UI::TreeList::Bind
void Bind(size_t=size_t(-1))
绑定数据源，展开不超过指定深度的节点。
Definition: TreeView.cpp:256
UI
YSLib::i
return i
Definition: YCoreUtilities.h:176
YSLib::UI::BorderArea::Left
ystdex::erase_n
_tCon::const_iterator erase_n(_tCon &con, typename _tCon::const_iterator i, typename _tCon::difference_type n)
删除指定容器中指定迭代器起始指定数量的元素。
Definition: container.hpp:795
YSLib::UI::Widget::SPos
Renderer AView SPos
Definition: YWidget.h:459
YSLib::UI::AMUnitList::idxShared
size_t idxShared
Definition: Viewer.h:203
YSLib::UI::e
void e
Definition: YWidget.h:352
YModules.h
YSLib::UI::MTextList::LabelBrush
MLabel LabelBrush
Definition: ListControl.h:150
YSLib::UI::TreeList::NodeState::None
YSLib::UI::TextList
文本列表。
Definition: ListControl.h:201
YSLib::UI::TreeView
带滚动条的树形视图。
Definition: TreeView.h:219
YSLib::Drawing::DrawArrow
YF_API void DrawArrow(const Graphics &, const Rect &, const Rect &, SDst=4, Rotation=RDeg0, Color=ColorSpace::Black, bool={})
在指定图形接口上下文上描画底边和坐标轴共线的等腰直角三角形箭头。
Definition: YStyle.cpp:202
YSLib::ValueNode
值类型节点。
Definition: ValueNode.h:57
YSLib::UI::TreeList::IndentMap
map< IndexType, IndentType > IndentMap
Definition: TreeView.h:63
YSLib::UI::TreeList::indent_map
IndentMap indent_map
列表项位置索引。
Definition: TreeView.h:106
YSLib::UI::TreeList::GetIndentBoxBounds
Rect GetIndentBoxBounds(IndexType) const
取相对部件的指定索引的缩进框边界。
Definition: TreeView.cpp:200
YSLib::UI::PaintEventArgs
部件绘制参数。
Definition: YWidgetEvent.h:323
YSLib::Drawing::RDeg0
Definition: YGDIBase.h:897
YSLib::IO::f
const string &path const String &path _func f
Definition: YSLib/Service/FileSystem.h:430
YSLib::Drawing::Padding::Left
SPos Left
空白距离：左、右、上、下。
Definition: YGDI.h:52
YSLib::UI::TreeList::ExtractNodeName
static String ExtractNodeName(const ValueNode &)
Definition: TreeView.cpp:187
YSLib::UI::KeyEventArgs
按键输入事件参数类。
Definition: YWidgetEvent.h:186
YSLib::UI::ListBox
带滚动条的文本列表框。
Definition: ComboList.h:49
ystdex::as_const
add_const_t< _type > & as_const(_type &t)
转换 const 引用。
Definition: utility.hpp:50
platform::n
size_t n
Definition: YCLib/FileSystem.cpp:321
ystdex::replace_value
auto replace_value(_tAssocCon &con, const _tKey &k, _func f) -> decltype(con.emplace_hint(con.erase(con.find(k)), f(*con.find(k))))
替换关联容器的值。
Definition: container.hpp:963
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:43
YSLib::UI::BorderArea::Right
YSLib::Drawing::GBinaryGroup< SPos >