YSTest: TabControl.cpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

TabControl.cpp
浏览该文件的文档.
1 /*
2 © 2014-2016, 2019 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_TabControl // for ystdex::max;
30 #include YFM_YSLib_UI_YGUI
31 #include YFM_YSLib_Service_YGDI // for Drawing::Clip;
32 #include <ystdex/iterator.hpp>
33
34 namespace YSLib
35 {
36
37 using namespace Drawing;
38
39 namespace UI
40 {
41
42 TabBar::TabBar(const Rect& r)
43 : Control(r), MLinearUIContainer()
44 {
45 FetchEvent<Resize>(*this) += [this]{
46 PerformLayout();
47 };
48 }
49
50 void
51 TabBar::operator+=(IWidget& tab)
52 {
53 MLinearUIContainer::operator+=(tab);
54 SetContainerPtrOf(tab, make_observer(this));
55 }
56
57 bool
58 TabBar::operator-=(IWidget& tab)
59 {
60 return RemoveFrom(tab, *this) ? MLinearUIContainer::operator-=(tab) : false;
61 }
62
63 void
64 TabBar::DefaultPaintTabBorder(PaintEventArgs&& e)
65 {
66 auto& sender(e.GetSender());
67
68 DrawRect(e.Target, e.ClipArea, Rect(e.Location, GetSizeOf(sender)),
69 FetchGUIConfiguration().Colors[IsFocused(sender)
70 ? Styles::ActiveBorder : Styles::InactiveBorder]);
71 }
72
73 SPos
74 TabBar::PerformLayout()
75 {
76 const SDst h(GetHeight());
77 SPos x(Offset);
78
79 for(const auto& wgt_ref : vWidgets)
80 {
81 Size s(GetSizeOf(wgt_ref));
82
83 if(s.Width < MinWidth)
84 s.Width = MinWidth;
85 if(h < s.Height)
86 s.Height = h;
87 SetBoundsOf(wgt_ref, Rect(x, 0, s));
88 // XXX: Conversion to 'SPos' might be implementation-defined.
89 x += SPos(s.Width);
90 }
91 return x;
92 }
93
94 void
95 TabBar::Refresh(PaintEventArgs&& e)
96 {
97 if(!e.ClipArea.IsUnstrictlyEmpty())
98 for(auto pr(GetChildren()); pr.first != pr.second; ++pr.first)
99 {
100 auto& wgt(*pr.first);
101
102 if(IsVisible(wgt))
103 {
104 PaintContext& pc(e);
105 PaintEventArgs e_new(wgt, pc);
106
107 if(Clip(e_new.ClipArea,
108 Rect(e_new.Location += GetLocationOf(wgt), GetSizeOf(wgt))))
109 {
110 if(PaintTabBackground)
111 PaintTabBackground(std::move(e_new));
112 wgt.GetRenderer().Paint(wgt, std::move(e_new));
113 if(PaintTabForeground)
114 PaintTabForeground(std::move(e_new));
115 }
116 pc.ClipArea |= e_new.ClipArea;
117 }
118 }
119 }
120
121 bool
122 TabBar::SwitchPage(Control& ctl)
123 {
124 return IsEnabled(ctl);
125 }
126
127
128 TabControl::TabControl(const Rect& r)
129 : Control(r),
130 p_bar(new TabBar(Size(r.Width, BarHeight)))
131 {}
132 ImplDeDtor(TabControl)
133
134 void
135 TabControl::operator+=(IWidget& wgt)
136 {
137 tab_pages.push_back(make_observer(&dynamic_cast< Panel&>(wgt)));
138 SetContainerPtrOf(wgt, make_observer(this));
139 SetVisibleOf(wgt, {});
140 }
141
142 void
143 TabControl::Attach(Control& ctl)
144 {
145 FetchEvent<TouchDown>(ctl) += [&]{
146 if(SwitchTab(ctl))
147 Invalidate(*this);
148 };
149 }
150
151 Rect
152 TabControl::GetPageBounds() const ynothrow
153 {
154 const SDst h(GetHeight());
155 const SDst h_tb(ystdex::max(GetTabBarRef().GetHeight(), BarHeight));
156
157 // XXX: Conversion to 'SPos' might be implementation-defined.
158 return Rect(0, SPos(h_tb), GetWidth(), h < h_tb ? 0 : h - h_tb);
159 }
160
161 size_t
162 TabControl::Find(IWidget& wgt) const
163 {
164 return size_t(std::find(tab_pages.cbegin(), tab_pages.cend(),
165 make_observer(&wgt)) - tab_pages.cbegin());
166 }
167
168 bool
169 TabControl::SwitchTab(Control& ctl)
170 {
171 const auto idx(GetTabBarRef().Find(ctl));
172
173 return idx < GetTabCount() ? SwitchPage(idx) : false;
174 }
175
176 bool
177 TabControl::SwitchPage(size_t idx)
178 {
179 if(idx < tab_pages.size())
180 {
181 if(const auto p = tab_pages[idx])
182 return SwitchPage(*p);
183 }
184 return {};
185 }
186 bool
187 TabControl::SwitchPage(Control& ctl)
188 {
189 YAssert(Find(ctl) != tab_pages.size(), "Invalid page found.");
190 if(Deref(p_bar).SwitchPage(ctl))
191 {
192 if(p_page)
193 SetVisibleOf(*p_page, {});
194
195 const auto i(Find(ctl));
196
197 p_page = tab_pages[i];
198 SetBoundsOf(*p_page, GetPageBounds()),
199 SetVisibleOf(*p_page, true);
200 return true;
201 }
202 return {};
203 }
204
205 void
206 TabControl::UpdateTabPages()
207 {
208 auto& tb(GetTabBarRef());
209
210 tb.PerformLayout();
211
212 const auto tp_count(tab_pages.size());
213 size_t i(0);
214
215 for(auto pr(tb.GetChildren()); !p_page && i < tp_count
216 && pr.first != pr.second; yunseq(++pr.first, ++i))
217 if(tab_pages[i])
218 {
219 p_page = tab_pages[i];
220 SetVisibleOf(*p_page, true),
221 SetBoundsOf(*p_page, GetPageBounds());
222 }
223 Invalidate(*this);
224 }
225
226 } // namespace UI;
227
228 } // namespace YSLib;
229
YSLib::UI::TabControl::SwitchTab
bool SwitchTab(Control &)
按标签切换页面。
Definition: TabControl.cpp:169
YSLib::UI::TabControl::tab_pages
vector< observer_ptr< Panel > > tab_pages
Definition: TabControl.h:128
YSLib::UI::Styles::ActiveBorder
@ ActiveBorder
活动边框背景。
Definition: YStyle.h:321
YSLib::UI::TabControl::BarHeight
SDst BarHeight
标签栏初始高。
Definition: TabControl.h:117
YSLib::UI::IsFocused
YF_API bool IsFocused(const IWidget &)
判断部件是否取得焦点。
Definition: YFocus.cpp:38
YSLib::UI::ynothrow
AView &y ynothrow
Definition: YWidgetView.cpp:47
YSLib::Drawing::Size
屏幕区域大小。
Definition: YGDIBase.h:536
YSLib::UI::Panel
面板。
Definition: YPanel.h:46
YSLib::UI::TabBar::operator-=
virtual bool operator-=(IWidget &)
Definition: TabControl.cpp:58
YSLib::UI::MLinearUIContainer
线性部件容器模块。
Definition: YUIContainer.h:205
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::TabBar::Refresh
void Refresh(PaintEventArgs &&) override
刷新：按指定参数绘制界面并更新状态。
Definition: TabControl.cpp:95
YSLib::UI::TabBar
标签栏控件。
Definition: TabControl.h:46
YSLib::UI::Control
控件。
Definition: YControl.h:271
YSLib::UI::MLinearUIContainer::operator-=
bool operator-=(IWidget &)
从部件组移除部件。
Definition: YUIContainer.cpp:185
YSLib::UI::TabControl::UpdateTabPages
void UpdateTabPages()
更新标签页状态。
Definition: TabControl.cpp:206
YSLib::UI::SetBoundsOf
void SetBoundsOf(IWidget &wgt, const Rect &r)
Definition: YWidget.cpp:56
YSLib::UI::TabControl::GetTabBarRef
GetTabBarRef().GetCount()) DefGetter(const ynothrow
YSLib::UI::TabBar::operator+=
virtual void operator+=(IWidget &)
Definition: TabControl.cpp:51
YSLib::UI::GetSizeOf
YB_ATTR_nodiscard YB_PURE pt pt Y YB_ATTR_nodiscard YB_PURE const IWidget &wgt const IWidget &wgt GetSizeOf
无效化：使相对部件的子部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: YWidget.h:165
ystdex::cpp2014::max
const _type & max(const _type &a, const _type &b, _fComp comp=less< _type >())
取较大的元素。
Definition: algorithm.hpp:635
YSLib::UI::Widget::SPos
Renderer AView SPos
Definition: YWidget.h:463
YSLib::UI::RemoveFrom
YF_API bool RemoveFrom(IWidget &, IWidget &)
从容器中移除部件。
Definition: YUIContainer.cpp:164
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::UI::TabBar::Offset
SPos Offset
第一个标签所在的起始偏移位置。
Definition: TabControl.h:51
YSLib::YAssert
YAssert(!(v< Deref(a)), "Value less than lower bound found.")
ystdex::make_observer
observer_ptr< _type > make_observer(_type *p)
Definition: pointer.hpp:405
YSLib::UI::TabBar::SwitchPage
bool SwitchPage(Control &)
切换页面。
Definition: TabControl.cpp:122
YSLib::UI::TabBar::PerformLayout
SPos PerformLayout()
布局。
Definition: TabControl.cpp:74
YSLib::UI::TabBar::DefaultPaintTabBorder
static void DefaultPaintTabBorder(PaintEventArgs &&)
绘制默认标签页边框。
Definition: TabControl.cpp:64
iterator.hpp
通用迭代器。
YSLib::UI::FetchGUIConfiguration
GUIConfiguration & FetchGUIConfiguration()
Definition: YGUI.cpp:517
YSLib::i
return i
Definition: YCoreUtilities.h:177
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:1535
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:44
YSLib::UI::e
void e
Definition: YWidget.h:356
YSLib::UI::MLinearUIContainer::vWidgets
WidgetVector vWidgets
部件组：存储部件引用。
Definition: YUIContainer.h:218
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: YGDIBase.h:788
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:46
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:143
YModules.h
YSLib 用户界面模块配置文件。
YSLib::UI::TabControl
标签容器控件。
Definition: TabControl.h:112
YSLib::UI::TabControl::p_page
observer_ptr< Panel > p_page
Definition: TabControl.h:126
YSLib::UI::wgt
IWidget & wgt
Definition: YControl.h:113
YSLib::UI::PaintEventArgs
部件绘制参数。
Definition: YWidgetEvent.h:330
YSLib::UI::TabBar::PaintTabForeground
function< void(PaintEventArgs &&)> PaintTabForeground
标签前景附加绘制操作。
Definition: TabControl.h:62
YSLib::UI::TabControl::size_t
size_t
Definition: TabControl.h:164
YSLib::UI::x
SPos x
Definition: YWidget.cpp:43
YSLib::UI::Widget::Deref
Renderer Deref(renderer_ptr)) DefGetter(const ImplI(IWidget)
YSLib::UI::TabBar::PaintTabBackground
function< void(PaintEventArgs &&)> PaintTabBackground
标签背景附加绘制操作。
Definition: TabControl.h:60
YSLib::UI::Styles::InactiveBorder
@ InactiveBorder
不活动边框背景。
Definition: YStyle.h:322
YSLib::UI::TabControl::p_bar
unique_ptr< TabBar > p_bar
标签栏。
Definition: TabControl.h:124
YSLib::UI::TabBar::MinWidth
SDst MinWidth
每个标签最小的位置。
Definition: TabControl.h:53
platform::p
return p p
Definition: YCLib/FileSystem.h:209
YSLib::UI::GetLocationOf
YB_ATTR_nodiscard YB_PURE pt pt Y YB_ATTR_nodiscard YB_PURE const IWidget &wgt GetLocationOf
Definition: YWidget.h:157
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:43
YSLib::UI::TabControl::SwitchPage
bool SwitchPage(size_t)
切换页面。
Definition: TabControl.cpp:177
YSLib::Drawing::GetHeight
YB_ATTR_nodiscard YB_PURE tr GetHeight())) inline PDefH(void
按字体高度和行距调整文本区域的底边距。
YSLib::UI::IsVisible
IsVisible
Definition: YWidget.h:101
YSLib::UI::TabControl::Find
YB_ATTR_nodiscard YB_PURE size_t Find(IWidget &) const
查找页面部件。
Definition: TabControl.cpp:162
YSLib::Drawing::DrawRect
void DrawRect(const Graphics &g, const Rect &bounds, const Rect &r, Color c)
Definition: YDraw.cpp:136
YSLib::UI::TabControl::Attach
const vector< observer_ptr< Panel > > tab_pages void Attach(Control &)
附加：添加 TouchDown 事件处理器。
Definition: TabControl.cpp:143
YSLib::UI::TabBar::TabBar
TabBar(const Rect &={})
Definition: TabControl.cpp:42
YSLib::UI::TabControl::TabControl
TabControl(const Rect &={})
Definition: TabControl.cpp:128