YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
ycontrol.cpp
浏览该文件的文档.
1 /*
2  © 2010-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_YControl
30 #include YFM_YSLib_UI_YGUI
31 #include YFM_YSLib_UI_YUIContainer
32 #include YFM_YSLib_Core_YStorage
33 #include <ystdex/algorithm.hpp>
34 #include YFM_YSLib_UI_YBrush
35 
36 namespace YSLib
37 {
38 
39 namespace UI
40 {
41 
42 namespace
43 {
44 
45 IWidget*
46 FetchEnabledBoundControlPtr(KeyEventArgs&& e)
47 {
48  try
49  {
50  auto p_ctl(
51  dynamic_cast<Control&>(e.GetSender()).BoundControlPtr(e.GetKeys()));
52 
53  return p_ctl && IsEnabled(*p_ctl) ? p_ctl : nullptr;
54  }
55  catch(std::bad_function_call&)
56  {}
57  catch(std::bad_cast&)
58  {}
59  return nullptr;
60 }
61 
63 void
64 TouchHeld_DragWidget(IWidget* p = {})
65 {
66  auto& st(FetchGUIState());
67 
68  if(!p)
69  p = st.GetIndependentFocusPtr();
70  if(st.CheckDraggingOffset(p))
71  {
72  // TODO: Compare subsequent states to make a more efficient implementation.
73  // TODO: Merge state to make a more efficient implementation.
74  InvalidateParent(*p);
75  SetLocationOf(*p, st.CursorLocation + st.DraggingOffset);
76  }
77 }
78 
79 } // unnamed namespace;
80 
81 
83 Controller::GetItemRef(const VisualEvent& id, EventMapping::MappedType(&f)())
84 {
85  return GetEvent(EventMap, id, f);
86 }
87 
88 
89 bool
90 Enable(IWidget& wgt, bool b)
91 {
92  const auto enability_changed(IsEnabled(wgt) != b);
93 
94  SetEnabledOf(wgt, b);
95  if(enability_changed)
96  Invalidate(wgt);
97  return enability_changed;
98 }
99 
100 
101 void
103 {
104  Invalidate(e.GetSender());
105 }
106 
107 void
109 {
110  auto& st(FetchGUIState());
111 
112  if(st.HeldTimer.RefreshHeld(st.KeyHeldState, Timers::TimeSpan(240),
113  Timers::TimeSpan(60)))
114  CallEvent<KeyDown>(e.GetSender(), e);
115 }
116 
117 void
119 {
120  IWidget& wgt(e.GetSender());
121 
122  if(e.Strategy != RoutedEventArgs::Bubble)
124  if(e.Strategy == RoutedEventArgs::Direct)
126  if(e.Strategy != RoutedEventArgs::Tunnel)
127  RequestFocus(wgt);
128 }
129 
130 void
132 {
133  if(e.Strategy == RoutedEventArgs::Direct)
134  {
135  auto& st(FetchGUIState());
136 
137  if(st.GetIndependentFocusPtr() && st.HeldTimer.RefreshHeld(
138  st.TouchHeldState, Timers::TimeSpan(240), Timers::TimeSpan(80)))
139  CallEvent<TouchDown>(*st.GetIndependentFocusPtr(), e);
140  }
141 }
142 
143 void
145 {
146  if(e.Strategy == RoutedEventArgs::Direct && !e.Handled)
147  TouchHeld_DragWidget();
148 }
149 
150 void
152 {
153  if(e.Strategy == RoutedEventArgs::Direct && !e.Handled)
154  TouchHeld_DragWidget(&wgt);
155 }
156 
157 
158 void
160 {
161  if(const auto p_ctl = FetchEnabledBoundControlPtr(std::move(e)))
162  {
163  CursorEventArgs et(*p_ctl, e.Keys, Point::Invalid);
164 
165  CallEvent<TouchUp>(*p_ctl, et);
166  e.Handled = true;
167  }
168 }
169 
170 void
172 {
173  if(const auto p_ctl = FetchEnabledBoundControlPtr(std::move(e)))
174  {
175  CursorEventArgs et(*p_ctl, e.Keys, Point::Invalid);
176 
177  CallEvent<TouchDown>(*p_ctl, et);
178  e.Handled = true;
179  }
180 }
181 
182 void
184 {
185  if(const auto p_ctl = FetchEnabledBoundControlPtr(std::move(e)))
186  {
187  CursorEventArgs et(*p_ctl, e.Keys, Point::Invalid);
188 
189  CallEvent<Click>(*p_ctl, et);
190  e.Handled = true;
191  }
192 }
193 
194 
195 Control::ControlEventMap::ControlEventMap()
196 {
197  FetchEvent<TouchDown>(*this) += OnTouchDown_RequestToFrontFocused;
198 }
199 
200 Control::Control(const Rect& r)
201  : Widget(new View(r), new Renderer(),
202  new Controller(true, FetchPrototype<ControlEventMap>())),
203  BoundControlPtr(std::bind(&Control::GetBoundControlPtr, this,
204  std::placeholders::_1))
205 {
206  FetchGUIState().Wrap(*this),
207  yunseq(
208  FetchEvent<Move>(*this) += [](UIEventArgs&& e){
209  InvalidateParent(e.GetSender());
210  },
211  FetchEvent<Resize>(*this) += OnUIEvent_Invalidate
212  );
213 }
215  : Control(r)
216 {
217  yunseq(Background = b, ForeColor = f);
218 }
220  : Widget(ctl), BoundControlPtr(ctl.BoundControlPtr)
221 {}
222 
223 void
224 Control::OnTouch_Close(CursorEventArgs&&)
225 {
226  Close(*this);
227 }
228 
229 } // namespace UI;
230 
231 } // namespace YSLib;
232 
void InvalidateParent(IWidget &wgt)
Definition: ywidget.cpp:144
const _type & FetchPrototype()
取指定类型的静态原型对象。
Definition: ystorage.hpp:69
YF_API void OnKeyHeld(KeyEventArgs &&)
处理键接触保持事件。
Definition: ycontrol.cpp:108
YF_API void OnKey_Bound_TouchDown(KeyEventArgs &&)
处理按键事件:按键-指针设备接触开始。
Definition: ycontrol.cpp:171
YF_API void SetLocationOf(IWidget &, const Point &)
设置部件左上角所在位置(相对于容器的偏移坐标)。
Definition: ywidget.cpp:73
bool return true
Definition: DSMain.cpp:177
YF_API GUIState & FetchGUIState()
取默认图形用户界面公共状态。
Definition: ygui.cpp:442
GEventPointerWrapper< UIEventArgs && > MappedType
映射项类型。
Definition: ywgtevt.h:423
按键输入事件参数类。
Definition: ywgtevt.h:167
YF_API void Invalidate(IWidget &, const Rect &)
无效化:使相对于部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: ywidget.cpp:111
GIHEvent< UIEventArgs && > ItemType
Definition: ywgtevt.h:424
YF_API EventMapping::ItemType & GetEvent(EventMapping::MapType &, const VisualEvent &, EventMapping::MappedType(&)())
在事件映射表中取指定 id 对应的事件。
YF_API void OnTouchHeld_DraggingRaw(CursorEventArgs &&, IWidget &)
处理屏幕接触移动事件:拖放指定部件。
Definition: ycontrol.cpp:151
static const GBinaryGroup Invalid
无效(不在屏幕坐标系中)对象。
Definition: ygdibase.h:57
YF_API bool Enable(IWidget &, bool=true)
设置部件可用性,且当可用性改变时无效化部件区域。
Definition: ycontrol.cpp:90
YF_API void OnTouchHeld_Dragging(CursorEventArgs &&)
处理屏幕接触移动事件:拖放按下部件。
Definition: ycontrol.cpp:144
用户界面事件参数基类。
Definition: ywgtevt.h:59
控件。
Definition: ycontrol.h:275
void SetEnabledOf(IWidget &wgt, bool b)
设置部件可用性。
Definition: ycontrol.h:101
YF_API void OnTouchHeld(CursorEventArgs &&)
处理屏幕接触保持事件。
Definition: ycontrol.cpp:131
HBrush Background
背景。
Definition: ywidget.h:374
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
_tWidget & wgt
Definition: ywgtevt.h:596
YF_API void OnTouchDown_RequestToFrontFocused(CursorEventArgs &&)
处理屏幕接触开始事件:使用一般接触策略。
Definition: ycontrol.cpp:118
屏幕标准矩形:表示屏幕矩形区域。
Definition: ygdibase.h:416
直接事件:仅当遍历至目标控件时触发。
Definition: ywgtevt.h:104
std::function< void(PaintEventArgs &&)> HBrush
画刷回调函数。
Definition: YComponent.h:104
_tWidget _fCallable && f
Definition: ywgtevt.h:597
wgt wgt YF_API void ClearFocusingOf(IWidget &)
清除焦点指针并以此部件作为事件源调用被清除焦点部件的 LostFocus 事件。
Definition: yfocus.cpp:112
bool IsEnabled(const IWidget &wgt)
判断部件是否为可用的控件。
Definition: ycontrol.h:86
EventMapping::MapType EventMap
事件映射表。
Definition: ycontrol.h:56
void Wrap(IWidget &)
包装部件响应 Enter/Leave 事件。
Definition: ygui.cpp:356
泛型算法。
YF_API void OnKey_Bound_TouchUp(KeyEventArgs &&)
处理按键事件:按键-指针设备接触结束。
Definition: ycontrol.cpp:159
YF_API void RequestToFront(IWidget &)
请求提升至容器前端。
Definition: ywidget.cpp:199
YF_API void OnKey_Bound_Click(KeyEventArgs &&)
处理按键事件:按键-指针设备按下。
Definition: ycontrol.cpp:183
气泡事件:向上遍历视图树时触发。
Definition: ywgtevt.h:102
bounds & r
Definition: ydraw.h:220
Color ForeColor
默认前景色。
Definition: ywidget.h:375
std::chrono::milliseconds TimeSpan
低精度时间间隔。
Definition: ytimer.h:85
隧道事件:向下遍历视图树时触发。
Definition: ywgtevt.h:103
颜色。
Definition: Video.h:339
部件。
Definition: ywidget.h:356
指针设备输入事件参数类。
Definition: ywgtevt.h:183
void Close(IWidget &wgt)
Definition: ywidget.cpp:95
YF_API void OnUIEvent_Invalidate(UIEventArgs &&)
处理用户界面事件:无效化发送者。
Definition: ycontrol.cpp:102
Control(const Rect &, HBrush, Drawing::Color=Drawing::ColorSpace::Black)
构造:使用指定边界、背景画刷和前景色。
Definition: ycontrol.cpp:214