YSTest: ComboList.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

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

- 文件列表
- 文件成员

ComboList.cpp
浏览该文件的文档.
1 /*
2 © 2011-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_ComboList
30 #include YFM_YSLib_UI_YStyle
31 #include YFM_YSLib_UI_YPanel
32 #include YFM_YSLib_Service_TextLayout // for FetchMaxTextWidth;
33
34 namespace YSLib
35 {
36
37 namespace UI
38 {
39
40 namespace
41 {
42
43 const SDst defMinScrollBarWidth(16);
44
45
50 void
51 Detach(observer_ptr<IWidget> p_con, IWidget& wgt)
52 {
53 if(const auto p = dynamic_cast<Panel*>(p_con.get()))
54 {
55 Invalidate(wgt);
56 *p -= wgt;
57 }
58 }
59
60 } // unnamed namespace;
61
62
63 ListBox::ListBox(const Rect& r, unique_ptr<TextList> p_textlist)
64 : ScrollableContainer(r),
65 pTextList(std::move(p_textlist))
66 {
67 Background = nullptr,
68 SetContainerPtrOf(GetTextListRef(), make_observer(this)),
69 vsbVertical.GetTrackRef().Scroll += [this](ScrollEventArgs&& e){
70 GetTextListRef().LocateViewPosition(SDst(round(e.GetValue())));
71 },
72 GetTextListRef().ViewChanged += [this](ViewArgs&& e){
73 if(!e.Value && GetWidth() > defMinScrollBarWidth)
74 {
75 const Size view_arena(GetWidth() - defMinScrollBarWidth,
76 GetTextListRef().GetFullViewHeight());
77
78 SetSizeOf(GetTextListRef(), FixLayout(view_arena));
79 if(view_arena.Height > GetTextListRef().GetHeight())
80 {
81 vsbVertical.SetSmallDelta(GetTextListRef().GetItemHeight());
82 vsbVertical.SetMaxValue(view_arena.Height
83 - GetTextListRef().GetHeight());
84 vsbVertical.SetLargeDelta(GetTextListRef().GetHeight());
85 vsbVertical.SetValue(GetTextListRef().GetViewPosition());
86 }
87 }
88 },
89 RequestFocus(GetTextListRef());
90 // NOTE: Text state refreshed for correctly showing scroll bars.
91 ResetView();
92 }
93 ListBox::ListBox(const Rect& r, const shared_ptr<ListType>& h)
94 : ListBox(r, make_unique<TextList>(Rect(r.GetSize()), h))
95 {}
96 ImplDeDtor(ListBox)
97
98 void
99 ListBox::ResizeForPreferred(const Size& sup, Size s)
100 {
101 if(s.Width == 0)
102 s.Width = FetchMaxTextWidth(GetTextListRef().LabelBrush.Font,
103 GetTextListRef().GetList().cbegin(),
104 GetTextListRef().GetList().cend())
105 + GetHorizontalOf(GetTextListRef().LabelBrush.Margin);
106 if(s.Height == 0)
107 s.Height = GetTextListRef().GetFullViewHeight();
108 if(sup.Width != 0 && s.Width > sup.Width)
109 s.Width = sup.Width;
110 if(sup.Height != 0 && s.Height > sup.Height)
111 {
112 yunseq(s.Width += defMinScrollBarWidth, s.Height = sup.Height);
113 if(sup.Width != 0 && sup.Width < s.Width)
114 s.Width = sup.Width;
115 }
116 SetSizeOf(*this, s);
117 SetSizeOf(GetTextListRef(), FixLayout(s));
118 UpdateView();
119 }
120
121
122 FileBox::FileBox(const Rect& r)
123 : ListBox(r), pthDirectory()
124 {
125 GetConfirmed() += [this](IndexEventArgs&& e){
126 if(Contains(e) && bool(*this = GetPath(e.Value)))
127 {
128 GetListRef() = ListItems();
129 ResetView();
130 }
131 };
132 ListItems();
133 UpdateView();
134 }
135 ImplDeDtor(FileBox)
136
137 IO::Path
138 FileBox::GetPath() const
139 {
140 return IsSelected() ? GetPath(GetSelectedIndex()) : pthDirectory;
141 }
142 IO::Path
143 FileBox::GetPath(typename ListType::size_type i) const
144 {
145 YAssert(i < GetList().size(), "Invalid index found.");
146 return pthDirectory / IO::Path(GetList()[i]);
147 }
148
149 bool
150 FileBox::operator=(const IO::Path& d)
151 {
152 if(VerifyDirectory(d))
153 {
154 pthDirectory = d;
155 return true;
156 }
157 return {};
158 }
159 bool
160 FileBox::operator/=(const String& d)
161 {
162 return *this = pthDirectory / d;
163 }
164 bool
165 FileBox::operator/=(const IO::Path& d)
166 {
167 return *this = pthDirectory / d;
168 }
169
170 bool
171 FileBox::SetPath(const IO::Path& pth)
172 {
173 if(operator=(pth))
174 {
175 GetListRef() = ListItems();
176 UpdateView();
177 return true;
178 }
179 return {};
180 }
181
182 FileBox::ListType
183 FileBox::ListItems() const
184 {
185 ListType lst;
186
187 TryExpr(ListFiles(pthDirectory, lst))
188 // TODO: Log errors?
189 CatchIgnore(IO::FileOperationFailure&)
190 // TODO: Platform-dependent name converting.
191 return lst;
192 }
193
194
195 DropDownList::DropDownList(const Rect& r, const shared_ptr<ListType>& h)
196 : Button(r),
197 lbContent({}, h)
198 {
199 const auto detacher([this](UIEventArgs&& e){
200 if(!dynamic_cast<RoutedEventArgs*>(&e))
201 DetachTopWidget();
202 });
203
204 yunseq(
205 Margin.Left = 4,
206 Margin.Right = 18,
207 HorizontalAlignment = TextAlignment::Left,
208 lbContent.GetView().DependencyPtr = make_observer(this),
209 FetchEvent<TouchDown>(*this) += [this](CursorEventArgs&& e){
210 if(!FetchContainerPtr(lbContent))
211 {
212 Point pt;
213
214 if(const auto p
215 = dynamic_cast<Panel*>(&FetchTopLevel(e.GetSender(), pt)))
216 {
217 // NOTE: Get height of top widget, top and bottom spaces.
218 const SDst h0(GetSizeOf(*p).Height);
219 // XXX: Conversion to 'SPos' might be implementation-defined.
220 const SDst h1(SDst(max<SPos>(0, pt.Y))), h2(SDst(max<SPos>(0,
221 SPos(h0) - pt.Y - SPos(GetHeight()))));
222
223 if(IsInOpenInterval(h1, h0) || IsInOpenInterval(h2, h0))
224 {
225 lbContent.ResizeForPreferred(Size(0, max(h1, h2)),
226 Size(GetWidth(), 0));
227
228 const SDst h3(lbContent.GetHeight());
229
230 // NOTE: Bottom space is preferred.
231 // XXX: Conversion to 'SPos' might be
232 // implementation-defined.
233 pt.Y += SPos(h2 < h3 ? -h3 : GetHeight());
234 SetLocationOf(lbContent, pt);
235 lbContent.AdjustViewLength();
236 {
237 const auto& lst(lbContent.GetList());
238 const auto i(std::find(lst.cbegin(), lst.cend(), Text));
239
240 if(i != lst.cend())
241 lbContent.SetSelected(size_t(i - lst.cbegin()));
242 else
243 lbContent.ClearSelected();
244 }
245 p->Add(lbContent, 224U); // TODO: Use non-magic number.
246 RequestFocusCascade(lbContent);
247 e.Handled = true;
248 }
249 }
250 }
251 },
252 FetchEvent<LostFocus>(*this) += detacher,
253 FetchEvent<LostFocus>(lbContent) += detacher,
254 lbContent.GetConfirmed() += [this](IndexEventArgs&& e){
255 YAssert(e.Value < lbContent.GetList().size(), "Invalid index found.");
256
257 Text = lbContent.GetList()[e.Value];
258 // XXX: This seems to be redundant if the detached top widget would be
259 // always invalidated, however there is no such guarantee.
260 Invalidate(e.GetSender()),
261 Invalidate(*this);
262 DetachTopWidget();
263 }
264 );
265 }
266 DropDownList::~DropDownList()
267 {
268 DetachTopWidget();
269 }
270
271 void
272 DropDownList::DetachTopWidget()
273 {
274 Detach(FetchContainerPtr(lbContent), lbContent);
275 }
276
277 void
278 DropDownList::Refresh(PaintEventArgs&& e)
279 {
280 const auto cs(GetCursorState());
281
282 if(FetchContainerPtr(lbContent))
283 csCurrent = CursorState::Pressed;
284 Button::Refresh(std::move(e));
285 csCurrent = cs;
286 // XXX: Conversion to 'SPos' might be implementation-defined.
287 DrawArrow(e.Target, e.ClipArea, Rect(e.Location.X + SPos(GetWidth()) - 16,
288 e.Location.Y, Size(16, GetHeight())), 4, RDeg270, ForeColor);
289 }
290
291 } // namespace UI;
292
293 } // namespace YSLib;
294
platform::p
while p p
Definition: YCLib/FileSystem.h:225
YSLib::UI::RequestFocusCascade
YF_API void RequestFocusCascade(IWidget &)
级联请求部件及上层容器焦点。
Definition: YFocus.cpp:137
YSLib::IsInOpenInterval
YB_STATELESS bool IsInOpenInterval(_type i, _type b) ynothrow
判断 i 是否在开区间 (_type(0), b) 内。
Definition: YCoreUtilities.h:136
YSLib::UI::ListBox::Contains
Contains
Definition: ComboList.h:87
YSLib::UI::CursorState::Pressed
ystdex::cpp2014::cend
auto cend(const _tRange &c) -> decltype(std::end(c))
Definition: range.hpp:87
YSLib::UI::FileBox::SetPath
bool SetPath(const IO::Path &)
设置路径，若成功则刷新列表。
Definition: ComboList.cpp:171
YSLib::UI::FileBox
文件列表框。
Definition: ComboList.h:169
YSLib::Drawing::FetchMaxTextWidth
SDst FetchMaxTextWidth(const Font &font, _tIn first, _tIn last)
取指定字体显示的迭代器范围中的文本的最大宽度。
Definition: TextLayout.h:330
YSLib::UI::FileBox::operator=
bool operator=(const IO::Path &)
导航至绝对路径。
YSLib::UI::UpdateView
void UpdateView(TextList &tl, bool is_active)
Definition: ListControl.cpp:425
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:45
YSLib::UI::ATrack::Scroll
GEvent< void(ScrollEventArgs &&)> Scroll
滚动事件。
Definition: Scroll.h:167
YSLib::UI::SPos
const IWidget &wgt SPos
Definition: YWidget.h:109
YSLib::UI::ListBox::ListType
TextList::ListType ListType
Definition: ComboList.h:52
YSLib::UI::ScrollEventArgs
滚动事件参数类。
Definition: Scroll.h:67
YSLib::UI::Button
按钮。
Definition: Button.h:127
YSLib::UI::DropDownList::lbContent
ListBox lbContent
Definition: ComboList.h:264
YSLib::Drawing::GBinaryGroup::Y
_type Y
分量。
Definition: YGDIBase.h:63
CHRLib::d
_tDst * d
Definition: CharacterProcessing.h:139
YSLib::UI::ListBox::ListBox
ListBox(const Rect &, unique_ptr< TextList >)
Definition: ComboList.cpp:63
platform_ex::Detach
_iCOM * Detach(COMPtr< _iCOM > &ptr) ynothrow
Definition: COM.h:398
YSLib::UI::Thumb::ForeColor
Color ForeColor
默认前景色。
Definition: Button.h:63
YSLib::UI::ScrollBar::GetTrackRef
ATrack GetTrackRef()) DefGetterMem(const ynothrow
YSLib::Text::String
YSLib 标准字符串（使用 UCS-2 作为内部编码）。
Definition: YString.h:46
YSLib::IO::VerifyDirectory
VerifyDirectory
Definition: YSLib/Service/FileSystem.h:394
YSLib::UI::UIEventArgs
用户界面事件参数基类。
Definition: YWidgetEvent.h:59
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
CatchIgnore
#define CatchIgnore(_ex)
指定异常处理器忽略指定异常。
Definition: YBaseMacro.h:133
YSLib::UI::Thumb::csCurrent
CursorState csCurrent
指针设备光标状态。
Definition: Button.h:70
YSLib::UI::TextAlignment::Left
YSLib::UI::SetSizeOf
YF_API void SetSizeOf(IWidget &, const Size &)
设置部件大小。
Definition: YWidget.cpp:83
YSLib::IO::ListFiles
void ListFiles(const Path &pth, vector< String > &lst)
Definition: YSLib/Service/FileSystem.cpp:222
YSLib::UI::ScrollableContainer::vsbVertical
ScrollBar vsbVertical
Definition: Scroll.h:419
std
Definition: memory.hpp:1100
YSLib::UI::DropDownList::Refresh
void Refresh(PaintEventArgs &&) override
分离顶层子部件。
Definition: ComboList.cpp:278
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:42
TryExpr
#define TryExpr(...)
指定表达式在 try 块中求值。
Definition: YBaseMacro.h:120
ystdex::cpp2014::make_unique
enable_if_t<!is_array< _type >::value, std::unique_ptr< _type > > make_unique(_tParams &&...args)
使用 new 和指定参数构造指定类型的 std::unique_ptr 对象。
Definition: memory.hpp:729
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
YSLib::UI::Widget::SDst
SDst
Definition: YWidget.h:454
YSLib::YAssert
YAssert(!(v< Deref(a)),"Value less than lower bound found.")
YSLib::UI::Widget::Background
HBrush Background
背景。
Definition: YWidget.h:391
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:996
YSLib::UI::wgt
IWidget & wgt
Definition: YControl.h:112
YSLib::UI::FileBox::FileBox
FileBox(const Rect &={})
Definition: ComboList.cpp:122
YSLib::UI::CursorEventArgs
指针设备输入事件参数类。
Definition: YWidgetEvent.h:210
IO
YSLib::UI::Widget::Refresh
virtual void Refresh(PaintEventArgs &&)
刷新：按指定参数绘制界面并更新状态。
Definition: YWidget.cpp:264
YSLib::Drawing::GetHeight
tr GetHeight())) inline PDefH(void
按字体高度和行距调整文本区域的底边距。
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: YGDIBase.h:540
YSLib::UI::ScrollableContainer
带滚动条的容器。
Definition: Scroll.h:407
ystdex::max
const _type & max(const _type &a, const _type &b, _fComp comp=less< _type >())
取较大的元素。
Definition: algorithm.hpp:543
YSLib::Drawing::Size
屏幕区域大小。
Definition: YGDIBase.h:293
YSLib::UI::SetLocationOf
YF_API void SetLocationOf(IWidget &, const Point &)
设置部件左上角所在位置（相对容器的偏移坐标）。
Definition: YWidget.cpp:76
YSLib::UI::FileBox::pthDirectory
IO::Path pthDirectory
目录的完整路径。
Definition: ComboList.h:176
YSLib::UI::Widget::Width
Renderer AView Width
Definition: YWidget.h:458
platform::FileOperationFailure
表示文件操作失败的异常。
Definition: FileIO.h:1142
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
UI
YSLib::UI::ListBox::ResetView
ListType::size_type i const ynothrow GEvent< void(IndexEventArgs)> const ListType ListType GEvent< void(IndexEventArgs)> TextList GEvent< void(ViewArgs)> const shared_ptr< ListType > ListType::size_type i ResetView
Definition: ComboList.h:148
YSLib::i
return i
Definition: YCoreUtilities.h:176
YSLib::UI::DropDownList::DropDownList
DropDownList(const Rect &={}, const shared_ptr< ListType > &={})
Definition: ComboList.cpp:195
YSLib::UI::e
void e
Definition: YWidget.h:352
YSLib::p_con
name const ValueNode::Container * p_con
Definition: ValueNode.h:627
YModules.h
YSLib::Drawing::Size::Height
SDst Height
宽和高。
Definition: YGDIBase.h:302
Text
YSLib::UI::FileBox::ListItems
ListType ListItems() const
遍历目录中的项目，更新至列表。
Definition: ComboList.cpp:183
YSLib::UI::TextList
文本列表。
Definition: ListControl.h:201
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::UI::GetSizeOf
pt pt Y const IWidget &wgt const IWidget &wgt GetSizeOf
无效化：使相对部件的子部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: YWidget.h:161
YSLib::UI::FileBox::GetPath
DefGetter(const ynothrow, const IO::Path &, Directory, pthDirectory) IO IO::Path GetPath(typename ListType::size_type i) const
取目录的完整路径。
Definition: ComboList.h:225
ystdex::make_observer
observer_ptr< _type > make_observer(_type *p)
Definition: memory.hpp:1042
YSLib::IO::Path
路径。
Definition: YSLib/Service/FileSystem.h:109
YSLib::UI::PaintEventArgs
部件绘制参数。
Definition: YWidgetEvent.h:323
YSLib::UI::FetchTopLevel
YF_API IWidget & FetchTopLevel(IWidget &)
取指定部件的顶层部件。
Definition: YUIContainer.cpp:41
YSLib::UI::ListBox::GetTextListRef
ListType::size_type i const ynothrow GetTextListRef()) DefGetter(
项目选中确定事件。
YSLib::UI::bool
IWidget bool b bool
Definition: YControl.h:121
ystdex::cpp2014::cbegin
auto cbegin(const _tRange &c) -> decltype(std::begin(c))
Definition: range.hpp:79
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:140
YSLib::UI::FileBox::operator/=
bool operator/=(const String &)
导航至子目录。
Definition: ComboList.cpp:160
YSLib::UI::ListBox
带滚动条的文本列表框。
Definition: ComboList.h:49
YSLib::Drawing::RDeg270
Definition: YGDIBase.h:900
YSLib::UI::IndexEventArgs
GValueEventArgs< size_t > IndexEventArgs
索引事件。
Definition: ListControl.h:47
YSLib::UI::GValueEventArgs
简单 UI 事件参数类。
Definition: YWidgetEvent.h:299
YSLib::UI::ListBox::ViewArgs
TextList::ViewArgs ViewArgs
Definition: ComboList.h:53
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:43
YSLib::Drawing::GBinaryGroup< SPos >