YSTest: ComboList.cpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
ComboList.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 "YSLib/UI/YModules.h"
29 #include YFM_YSLib_UI_ComboList
30 #include YFM_YSLib_UI_YStyle
31 #include YFM_YSLib_UI_YPanel
32
33 namespace YSLib
34 {
35
36 namespace UI
37 {
38
39 namespace
40 {
41 const SDst defMinScrollBarWidth(16);
42 // const SDst defMinScrollBarHeight(16); //!< 默认最小滚动条高。
43
44
49 void
50 Detach(IWidget* pCon, IWidget& wgt)
51 {
52 if(const auto p = dynamic_cast<Panel*>(pCon))
53 {
54 Invalidate(wgt);
55 *p -= wgt;
56 }
57 }
58 }
59
60
61 ListBox::ListBox(const Rect& r, const shared_ptr<ListType>& h)
62 : ScrollableContainer(r),
63 tlContent(Rect(r.GetSize()), h)
64 {
65 Background = nullptr,
66 SetContainerPtrOf(tlContent, this),
67 vsbVertical.GetTrackRef().GetScroll() += [this](ScrollEventArgs&& e){
68 tlContent.LocateViewPosition(SDst(round(e.GetValue())));
69 },
70 tlContent.ViewChanged += [this](ViewArgs&& e){
71 if(!e.Value && GetWidth() > defMinScrollBarWidth)
72 {
73 const Size view_arena(GetWidth() - defMinScrollBarWidth,
74 tlContent.GetFullViewHeight());
75
76 SetSizeOf(tlContent, FixLayout(view_arena));
77 if(view_arena.Height > tlContent.GetHeight())
78 {
79 vsbVertical.SetSmallDelta(tlContent.GetItemHeight());
80 vsbVertical.SetMaxValue(view_arena.Height
81 - tlContent.GetHeight());
82 vsbVertical.SetLargeDelta(tlContent.GetHeight());
83 vsbVertical.SetValue(tlContent.GetViewPosition());
84 }
85 }
86 },
87 RequestFocus(tlContent);
88 //刷新文本状态，防止第一次绘制时无法正确决定是否需要滚动条。
89 tlContent.RefreshTextState();
90 }
91
92 void
93 ListBox::ResizeForPreferred(const Size& sup, Size s)
94 {
95 if(s.Width == 0)
96 s.Width = tlContent.GetMaxTextWidth()
97 + GetHorizontalOf(tlContent.Margin);
98 if(s.Height == 0)
99 s.Height = tlContent.GetFullViewHeight();
100 if(sup.Width != 0 && s.Width > sup.Width)
101 s.Width = sup.Width;
102 if(sup.Height != 0 && s.Height > sup.Height)
103 {
104 yunseq(s.Width = s.Width + defMinScrollBarWidth, s.Height = sup.Height);
105 if(sup.Width != 0 && sup.Width < s.Width)
106 s.Width = sup.Width;
107 }
108 SetSizeOf(*this, s);
109 SetSizeOf(tlContent, FixLayout(s));
110 UpdateView();
111 }
112
113
114 FileBox::FileBox(const Rect& r)
115 : ListBox(r), pthDirectory()
116 {
117 GetConfirmed() += [this](IndexEventArgs&& e){
118 if(Contains(e) && bool(*this /= GetList()[e.Value]))
119 {
120 GetListRef() = ListItems();
121 ResetView();
122 }
123 };
124 ListItems();
125 UpdateView();
126 }
127
128 IO::Path
129 FileBox::GetPath() const
130 {
131 return IsSelected() ? pthDirectory / (GetList()[GetSelectedIndex()])
132 : pthDirectory;
133 }
134
135 bool
136 FileBox::operator=(const IO::Path& d)
137 {
138 if(VerifyDirectory(d))
139 {
140 pthDirectory = d;
141 return true;
142 }
143 return false;
144 }
145 bool
146 FileBox::operator/=(const String& d)
147 {
148 return *this = pthDirectory / d;
149 }
150 bool
151 FileBox::operator/=(const IO::Path& d)
152 {
153 return *this = pthDirectory / d;
154 }
155
156 bool
157 FileBox::SetPath(const IO::Path& pth)
158 {
159 if(operator=(pth))
160 {
161 GetListRef() = ListItems();
162 UpdateView();
163 return true;
164 }
165 return false;
166 }
167
168 FileBox::ListType
169 FileBox::ListItems() const
170 {
171 ListType lst;
172
173 ListFiles(pthDirectory, lst);
174 // TODO: Platform-dependent name converting.
175 return lst;
176 }
177
178
179 DropDownList::DropDownList(const Rect& r, const shared_ptr<ListType>& h)
180 : Button(r),
181 lbContent({}, h)
182 {
183 const auto detacher([this](UIEventArgs&& e){
184 if(!dynamic_cast<RoutedEventArgs*>(&e))
185 DetachTopWidget();
186 });
187
188 yunseq(
189 Margin.Left = 4,
190 Margin.Right = 18,
191 HorizontalAlignment = TextAlignment::Left,
192 lbContent.GetView().DependencyPtr = this,
193 FetchEvent<TouchDown>(*this) += [this](CursorEventArgs&& e){
194 if(!FetchContainerPtr(lbContent))
195 {
196 Point pt;
197
198 if(const auto p
199 = dynamic_cast<Panel*>(&FetchTopLevel(e.GetSender(), pt)))
200 {
201 // NOTE: Get height of top widget, top and bottom spaces.
202 const SDst h0(GetSizeOf(*p).Height);
203 const SDst h1(max<SPos>(0, pt.Y)), h2(max<SPos>(0, h0 - pt.Y
204 - GetHeight()));
205
206 if(IsInOpenInterval(h1, h0) || IsInOpenInterval(h2, h0))
207 {
208 lbContent.ResizeForPreferred(Size(0, max(h1, h2)),
209 Size(GetWidth(), 0));
210
211 const SDst h(lbContent.GetHeight());
212
213 // NOTE: Bottom space is preferred.
214 pt.Y += h2 < h ? -h : GetHeight();
215 SetLocationOf(lbContent, pt);
216 lbContent.AdjustViewLength();
217 {
218 const auto idx(lbContent.Find(Text));
219
220 if(idx + 1 != 0)
221 lbContent.SetSelected(idx);
222 else
223 lbContent.ClearSelected();
224 }
225 p->Add(lbContent, 224U); // TODO: Use non-magic number.
226 RequestFocus(lbContent);
227 e.Handled = true;
228 }
229 }
230 }
231 },
232 FetchEvent<LostFocus>(*this) += detacher,
233 FetchEvent<LostFocus>(lbContent) += detacher,
234 lbContent.GetConfirmed() += [this](IndexEventArgs&& e){
235 YAssert(e.Value < lbContent.GetList().size(), "Invalid index found.");
236
237 Text = lbContent.GetList()[e.Value];
238 Invalidate(e.GetSender()),
239 DetachTopWidget();
240 }
241 );
242 }
243 DropDownList::~DropDownList()
244 {
245 DetachTopWidget();
246 }
247
248 void
249 DropDownList::DetachTopWidget()
250 {
251 Detach(FetchContainerPtr(lbContent), lbContent);
252 }
253
254 void
255 DropDownList::Refresh(PaintEventArgs&& e)
256 {
257 const auto cs(GetCursorState());
258
259 if(FetchContainerPtr(lbContent))
260 csCurrent = CursorState::Pressed;
261 Button::Refresh(std::move(e));
262 csCurrent = cs;
263 DrawArrow(e.Target, Rect(e.Location + Vec(GetWidth() - 16, 0),
264 Size(16, GetHeight())) & e.ClipArea, 4, RDeg270, ForeColor);
265 }
266
267 } // namespace UI;
268
269 } // namespace YSLib;
270
YSLib::UI::ListBox::tlContent
TextList tlContent
Definition: ComboList.h:66
YSLib::UI::GetSizeOf
pt pt Y const IWidget &wgt const IWidget &wgt GetSizeOf
无效化：使相对于部件的子部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: ywidget.h:156
YSLib::UI::IndexEventArgs
GValueEventArgs< MTextList::IndexType > IndexEventArgs
索引事件。
Definition: textlist.h:47
YModules.h
YSLib::UI::FileBox::ListItems
ListType ListItems() const
遍历目录中的项目，更新至列表。
Definition: ComboList.cpp:169
YSLib::UI::SetLocationOf
YF_API void SetLocationOf(IWidget &, const Point &)
设置部件左上角所在位置（相对于容器的偏移坐标）。
Definition: ywidget.cpp:73
YSLib::UI::ListBox
带滚动条的文本列表框。
Definition: ComboList.h:48
YSLib::IO::ListFiles
void ListFiles(const Path &pth, vector< String > &lst)
Definition: YSLib/Service/FileSystem.cpp:153
YSLib::UI::ScrollEventArgs
滚动事件参数类。
Definition: scroll.h:67
YSLib::UI::ListBox::ResetView
tlContent ListType::size_type i tlContent const ListType tlContent tlContent ViewChanged tlContent Confirmed ListType::size_type i const ItemType &text ResetView
Definition: ComboList.h:141
YSLib::UI::Invalidate
YF_API void Invalidate(IWidget &, const Rect &)
无效化：使相对于部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: ywidget.cpp:111
platform_ex::Detach
_iCOM * Detach(COMPtr< _iCOM > &ptr) ynothrow
Definition: include/YCLib/COM.h:396
YSLib::UI::PaintEventArgs
部件绘制参数。
Definition: ywgtevt.h:276
YSLib::UI::UpdateView
void UpdateView(TextList &tl, bool is_active)
Definition: textlist.cpp:431
YSLib::UI::ListBox::ViewArgs
TextList::ViewArgs ViewArgs
Definition: ComboList.h:52
YSLib::UI::ListBox::Contains
tlContent Contains
Definition: ComboList.h:78
YSLib::UI::FileBox::pthDirectory
IO::Path pthDirectory
目录的完整路径。
Definition: ComboList.h:169
YSLib::Drawing::Size::Height
SDst Height
宽和高。
Definition: ygdibase.h:258
YSLib::IsInOpenInterval
bool IsInOpenInterval(_type i, _type b) ynothrow
判断 i 是否在开区间 (FetchZero<_type>(), b) 内。
Definition: ycutil.h:192
YSLib::UI::SetSizeOf
YF_API void SetSizeOf(IWidget &, const Size &)
设置部件大小。
Definition: ywidget.cpp:83
YSLib::UI::ScrollableContainer::FixLayout
Size FixLayout(const Size &)
固定布局。
Definition: scroll.cpp:467
YSLib::UI::Button
按钮。
Definition: button.h:116
YSLib::UI::UIEventArgs
用户界面事件参数基类。
Definition: ywgtevt.h:59
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:39
YSLib::UI::DropDownList::lbContent
ListBox lbContent
Definition: ComboList.h:251
YSLib::Drawing::operator=
CompactPixmapEx & operator=(const CompactPixmapEx &buf)
Definition: ygdi.h:328
YSLib::Drawing::RDeg270
Definition: ygdibase.h:873
YSLib::UI::ScrollableContainer::vsbVertical
VerticalScrollBar vsbVertical
控制竖直可视区域的竖直滚动条。
Definition: scroll.h:431
YSLib::Text::String
YSLib 标准字符串（使用 UCS-2 作为内部编码）。
Definition: ystring.h:47
YSLib::UI::Widget::Background
HBrush Background
背景。
Definition: ywidget.h:374
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
YSLib::UI::ScrollableContainer
带滚动条的容器。
Definition: scroll.h:414
YSLib::UI::CursorState::Pressed
YSLib::UI::Thumb::csCurrent
CursorState csCurrent
指针设备光标状态。
Definition: button.h:64
YSLib::UI::TextAlignment::Left
YSLib::UI::wgt
_tWidget & wgt
Definition: ywgtevt.h:596
YSLib::IO::Path
路径。
Definition: YSLib/Service/FileSystem.h:75
YSLib::UI::AScrollBar::GetTrackRef
ATrack *pTrack GetTrackRef()) DefGetterMem(const ynothrow
YSLib::Drawing::GBinaryGroup::Y
_type Y
分量。
Definition: ygdibase.h:59
YSLib::UI::ListBox::ListBox
ListBox(const Rect &={}, const shared_ptr< ListType > &={})
Definition: ComboList.cpp:61
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: ygdibase.h:416
YSLib::UI::FetchTopLevel
YF_API IWidget & FetchTopLevel(IWidget &)
取指定部件的顶层部件。
Definition: yuicont.cpp:40
YSLib::Drawing::GBinaryGroup< SPos >
YSLib::UI::FileBox::operator/=
bool operator/=(const String &)
导航至子目录。
Definition: ComboList.cpp:146
YSLib::UI::FileBox::FileBox
FileBox(const Rect &={})
Definition: ComboList.cpp:114
YSLib::UI::GValueEventArgs
简单 UI 事件参数类。
Definition: ywgtevt.h:252
YSLib::UI::FileBox::SetPath
DefGetter(const ynothrow, const IO::Path &, Directory, pthDirectory) IO bool SetPath(const IO::Path &)
取目录的完整路径。
Definition: ComboList.h:214
platform_ex::Windows::s
return s
Definition: MinGW32.cpp:49
YSLib::Drawing::DrawArrow
YF_API void DrawArrow(const Graphics &, const Rect &, SDst=4, Rotation=RDeg0, Color=ColorSpace::Black)
在指定图形接口上下文上描画箭头。
Definition: ystyle.cpp:100
YSLib::UI::DropDownList::DropDownList
DropDownList(const Rect &={}, const shared_ptr< ListType > &={})
Definition: ComboList.cpp:179
YSLib::UI::DropDownList::Refresh
void Refresh(PaintEventArgs &&) override
分离顶层子部件。
Definition: ComboList.cpp:255
YSLib::Drawing::r
bounds & r
Definition: ydraw.h:220
YSLib::UI::Widget::ForeColor
Color ForeColor
默认前景色。
Definition: ywidget.h:375
YSLib::UI::Widget::Refresh
virtual void Refresh(PaintEventArgs &&)
刷新：按指定参数绘制界面并更新状态。
Definition: ywidget.cpp:264
YSLib::IO::VerifyDirectory
VerifyDirectory
Definition: YSLib/Service/FileSystem.h:312
YSLib::Drawing::Size
屏幕区域大小。
Definition: ygdibase.h:249
YSLib::UI::CursorEventArgs
指针设备输入事件参数类。
Definition: ywgtevt.h:183
YSLib::Drawing::Size::Width
SDst Width
Definition: ygdibase.h:258
YSLib::UI::ListBox::ListType
TextList::ListType ListType
Definition: ComboList.h:51
YAssert
#define YAssert(_expr, _msg)
Definition: cassert.h:73