YSTest: HostedUI.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

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

- 文件列表
- 文件成员

HostedUI.cpp
浏览该文件的文档.
1 /*
2 © 2013-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 "Helper/YModules.h"
29 #include YFM_Helper_HostedUI // for UI::WrapRenderer;
30 #include YFM_Helper_HostRenderer
31 #include YFM_YSLib_UI_YControl // for UI::FetchEvent;
32 #include YFM_YSLib_UI_YGUI // for UI::FetchGUIState;
33 #include YFM_YSLib_UI_Border
34 #include YFM_YSLib_UI_YPanel
35 #include YFM_Helper_Environment
36 #if YCL_Win32
37 # include YFM_YSLib_Core_Task // for ystdex::pvoid, PostTask;
38 # include YFM_Helper_GUIApplication // for Host::FetchGUIHost;
39 #endif
40
41 namespace YSLib
42 {
43
44 using namespace Drawing;
45 using namespace UI;
46
47 #if YF_Hosted
48 namespace Host
49 {
50
51 Window&
52 WaitForHostWindow(IWidget& wgt)
53 {
54 return dynamic_cast<HostRenderer&>(wgt.GetRenderer()).Wait();
55 }
56
57 # if !YCL_Android
58 void
59 AttachToHost(Widget& wgt, Window& wnd, Messaging::Priority prior)
60 {
61 # if YCL_Win32
62 using ystdex::pvoid;
63
64 wnd.MessageMap[WM_DESTROY] += [&]{
65 PostTask([&, prior]{
66 wgt.SetRenderer({});
67 }, prior);
68 };
69 # else
70 yunused(wgt), yunused(wnd), yunused(prior);
71 # endif
72 }
73
74 void
75 DragWindow(Window& wnd, CursorEventArgs&& e, bool root)
76 {
77 if(e.Strategy == RoutedEventArgs::Direct && !e.Handled)
78 {
79 auto& st(FetchGUIState());
80
81 if(st.CheckDraggingOffset())
82 {
83 const auto offset(st.CursorLocation + st.DraggingOffset);
84
85 if(root)
86 {
87 # if YCL_Win32
88 wnd.MoveClient(wnd.GetClientLocation() + offset);
89 # else
90 wnd.Move(wnd.GetLocation() + offset);
91 # endif
92 st.CursorLocation -= offset - GetLocationOf(e.GetSender());
93 }
94 else
95 # if YCL_Win32
96 wnd.MoveClient(offset);
97 # else
98 wnd.Move(offset);
99 # endif
100 }
101 }
102 }
103
104 Point
105 FetchDefaultTopLevelPosition() ynothrow
106 {
107 # if YCL_Win32
108 return {SPos(::GetSystemMetrics(SM_CXSCREEN) / 4),
109 SPos(::GetSystemMetrics(SM_CYSCREEN) / 4)};
110 # else
111 return {};
112 # endif
113 }
114 # endif
115
116 # if YCL_Win32
117
118 HostRenderer&
119 ShowTopLevel(Widget& wgt, WindowStyle wstyle, WindowStyle wstyle_ex,
120 int n_cmd_show, const wchar_t* title)
121 {
122 return ShowTopLevel(wgt, WindowThread::DefaultGenerateGuard, wstyle,
123 wstyle_ex, n_cmd_show, title);
124 }
125 HostRenderer&
126 ShowTopLevel(Widget& wgt, WindowThread::GuardGenerator guard_gen,
127 WindowStyle wstyle, WindowStyle wstyle_ex, int n_cmd_show,
128 const wchar_t* title)
129 {
130 if(!bool(wstyle & WS_POPUP) && bool(wstyle_ex & WS_EX_LAYERED))
131 {
132 wstyle_ex &= ~static_cast<WindowStyle>(WS_EX_LAYERED);
133 YTraceDe(Informative, "Layered style ignored for non-popup window.");
134 }
135
136 auto& res(WrapRenderer<HostRenderer>(wgt, wgt, guard_gen, [=, &wgt]{
137 WindowReference wnd_ref(CreateNativeWindow(WindowClassName,
138 GetSizeOf(wgt), title, wstyle, wstyle_ex));
139
140 const auto& pt(GetLocationOf(wgt));
141
142 if(pt != Point::Invalid)
143 wnd_ref.MoveClient(pt);
144 else if(!
145 (wstyle & static_cast<WindowStyle>(WS_OVERLAPPED | WS_CHILD)))
146 wnd_ref.MoveClient(FetchDefaultTopLevelPosition());
147 wnd_ref.Show(n_cmd_show);
148 return wnd_ref;
149 }));
150
151 res.Wait().UseOpacity = bool(wstyle_ex & WS_EX_LAYERED);
152 return res;
153 }
154 # endif
155 # if !YCL_Android
156
157 void
158 ShowTopLevelDraggable(Widget& wgt)
159 {
160 # if YCL_Win32
161 ShowTopLevel(wgt, WS_POPUP);
162 # endif
163 FetchEvent<TouchHeld>(wgt) += std::bind(Host::DragWindow,
164 std::ref(WaitForHostWindow(wgt)), std::placeholders::_1,
165 std::ref(Deref(GetHostRendererPtrOf(wgt)).RootMode));
166 }
167 # endif
168
169
170 array<GEvent<HCursorEvent::FuncType>::iterator, 2>
171 BindTimedTips(TimedHoverState& st, IWidget& wgt, Widget& target)
172 {
173 auto& cursor_over(FetchEvent<CursorOver>(wgt));
174 auto& leave(FetchEvent<Leave>(wgt));
175
176 return {{cursor_over.Insert([&](CursorEventArgs&& e){
177 if(st.CheckShow(e))
178 ActOnHover_ShowTopLevelAt(e.GetSender(), target,
179 std::bind(st.Locate, std::ref(e)));
180 }), leave.Insert([&](CursorEventArgs&& e){
181 if(st.CheckHide(e))
182 target.SetRenderer({});
183 })}};
184 }
185
186 void
187 PrepareTopLevelPopupMenu(Menu& mnu, Panel& root)
188 {
189 root.Add(mnu, DefaultMenuZOrder);
190 # if YCL_Win32
191 ShowTopLevel(mnu, WindowThread::GuardGenerator(), WS_POPUP,
192 WS_EX_NOACTIVATE | WS_EX_LAYERED | WS_EX_TOPMOST, SW_HIDE);
193 # endif
194 }
195
196 void
197 SetupTopLevelTimedTips(IWidget& wgt, TimedHoverState& st, Label& lbl,
198 const String& text, const Rect& r, const Font& fnt, const Padding& m)
199 {
200 SetupContentsOf(lbl, text, r, fnt, m);
201 // TODO: Border style setting, font, background, allowing host shadow,
202 // etc.
203 FetchEvent<Paint>(lbl) += BorderBrush();
204 # if YCL_Win32
205 BindTimedTips(st, wgt, lbl);
206 # else
207 yunused(wgt), yunused(st);
208 # endif
209 }
210
211 void
212 SetupTopLevelContextMenu(IWidget& wgt, MenuHost& mh, Menu& mnu)
213 {
214 mh += mnu;
215 # if YCL_Win32
216 PrepareTopLevelPopupMenu(mnu, FetchGUIHost().Desktop);
217 BindTopLevelPopupMenu(mh, mnu, wgt);
218 # else
219 yunused(wgt), yunused(mh), yunused(mnu);
220 # endif
221 }
222
223 } // namespace Host;
224 #endif
225
226 } // namespace YSLib;
227
YSLib::UI::DefaultMenuZOrder
yconstexpr const ZOrder DefaultMenuZOrder(224)
默认菜单 Z 顺序值。
YSLib::UI::BindTopLevelPopupMenu
YF_API void BindTopLevelPopupMenu(MenuHost &, Menu &, IWidget &, KeyIndex k=KeyCodes::Secondary)
绑定顶层部件的按键事件弹出菜单。
Definition: Menu.cpp:374
platform::Descriptions::Informative
Definition: YCommon.h:159
YSLib::UI::FetchGUIState
GUIState & FetchGUIState() ynothrow
Definition: YGUI.cpp:508
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:45
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:109
YSLib::UI::Styles::Window
窗口背景。
Definition: YStyle.h:311
YSLib::FetchGUIHost
FetchGUIHost
Definition: GUIApplication.h:300
YSLib::UI::SetupContentsOf
void SetupContentsOf(Label &lbl, const String &text, const Rect &r, const Font &fnt, const Padding &m)
Definition: Label.cpp:153
yunused
#define yunused(...)
标记未使用的表达式。
Definition: ydef.h:942
YSLib::UI::RoutedEventArgs::Direct
直接事件：仅当遍历至目标控件时触发。
Definition: YWidgetEvent.h:109
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:305
YSLib::ynothrow
YB_PURE const _type size_t n ynothrow
Definition: YCoreUtilities.h:168
platform::Deref
yconstfn auto Deref(_type &&p) -> decltype(*p)
断言并解引用非空指针。
Definition: Debug.h:440
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:42
YSLib::UI::Styles::Desktop
桌面背景。
Definition: YStyle.h:310
YSLib::UI::wgt
IWidget & wgt
Definition: YControl.h:112
ystdex::pvoid
enable_if_t< or_< is_object< _type >, is_void< _type > >::value, void * > pvoid(_type *p)
取 void* 类型的指针。
Definition: addressof.hpp:101
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
Drawing
UI
YSLib::Drawing::GBinaryGroup< SPos >::Invalid
static const GBinaryGroup Invalid
无效（不在屏幕坐标系中）对象。
Definition: YGDIBase.h:58
YSLib::Messaging::Priority
std::uint8_t Priority
消息优先级。
Definition: YMessage.h:51
YModules.h
YSLib::Drawing::Point
GBinaryGroup< SPos > Point
屏幕二维点（直角坐标表示）。
Definition: YGDIBase.h:278
YSLib::UI::GetSizeOf
pt pt Y const IWidget &wgt const IWidget &wgt GetSizeOf
无效化：使相对部件的子部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: YWidget.h:161
YSLib::UI::GetLocationOf
pt pt Y const IWidget &wgt GetLocationOf
Definition: YWidget.h:153
YSLib::PostTask
void PostTask(_fCallable &&f, Messaging::Priority prior=Messaging::NormalPriority)
通过消息队列部署后任务。
Definition: Task.h:43
platform::KeyCategory::Menu
表示菜单键（如 Menu 和 Win ）。
Definition: Keys.h:131
platform::bool
std::FILE *fp bool
Definition: FileIO.h:1187
YSLib::UI::Styles::Panel
面板背景。
Definition: YStyle.h:312
ystdex::ref
lref< _type > ref(_type &t)
构造引用包装。
Definition: ref.hpp:120