OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/services/native_viewport/native_viewport.h" | 5 #include "mojo/services/native_viewport/native_viewport.h" |
6 | 6 |
7 #include "ui/events/event.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "ui/events/event_utils.h" | 8 #include "ui/gfx/rect.h" |
9 #include "ui/gfx/win/msg_util.h" | 9 #include "ui/platform_window/platform_window_delegate.h" |
10 #include "ui/gfx/win/window_impl.h" | 10 #include "ui/platform_window/win/win_window.h" |
11 | 11 |
12 namespace mojo { | 12 namespace mojo { |
13 namespace services { | 13 namespace services { |
14 namespace { | |
15 | 14 |
16 gfx::Rect GetWindowBoundsForClientBounds(DWORD style, DWORD ex_style, | 15 class NativeViewportWin : public NativeViewport, |
17 const gfx::Rect& bounds) { | 16 public ui::PlatformWindowDelegate { |
18 RECT wr; | |
19 wr.left = bounds.x(); | |
20 wr.top = bounds.y(); | |
21 wr.right = bounds.x() + bounds.width(); | |
22 wr.bottom = bounds.y() + bounds.height(); | |
23 AdjustWindowRectEx(&wr, style, FALSE, ex_style); | |
24 | |
25 // Make sure to keep the window onscreen, as AdjustWindowRectEx() may have | |
26 // moved part of it offscreen. | |
27 gfx::Rect window_bounds(wr.left, wr.top, | |
28 wr.right - wr.left, wr.bottom - wr.top); | |
29 window_bounds.set_x(std::max(0, window_bounds.x())); | |
30 window_bounds.set_y(std::max(0, window_bounds.y())); | |
31 return window_bounds; | |
32 } | |
33 | |
34 } | |
35 | |
36 class NativeViewportWin : public gfx::WindowImpl, | |
37 public NativeViewport { | |
38 public: | 17 public: |
39 explicit NativeViewportWin(NativeViewportDelegate* delegate) | 18 explicit NativeViewportWin(NativeViewportDelegate* delegate) |
40 : delegate_(delegate) { | 19 : delegate_(delegate) { |
41 } | 20 } |
| 21 |
42 virtual ~NativeViewportWin() { | 22 virtual ~NativeViewportWin() { |
43 if (IsWindow(hwnd())) | 23 // Destroy the platform-window while |this| is still alive. |
44 DestroyWindow(hwnd()); | 24 platform_window_.reset(); |
45 } | 25 } |
46 | 26 |
47 private: | 27 private: |
48 // Overridden from NativeViewport: | 28 // Overridden from NativeViewport: |
49 virtual void Init(const gfx::Rect& bounds) OVERRIDE { | 29 virtual void Init(const gfx::Rect& bounds) OVERRIDE { |
50 gfx::Rect window_bounds = GetWindowBoundsForClientBounds( | 30 platform_window_.reset(new ui::WinWindow(this, bounds)); |
51 WS_OVERLAPPEDWINDOW, window_ex_style(), bounds); | |
52 gfx::WindowImpl::Init(NULL, window_bounds); | |
53 SetWindowText(hwnd(), L"native_viewport::NativeViewportWin!"); | |
54 } | 31 } |
55 | 32 |
56 virtual void Show() OVERRIDE { | 33 virtual void Show() OVERRIDE { |
57 ShowWindow(hwnd(), SW_SHOWNORMAL); | 34 platform_window_->Show(); |
58 } | 35 } |
59 | 36 |
60 virtual void Hide() OVERRIDE { | 37 virtual void Hide() OVERRIDE { |
61 ShowWindow(hwnd(), SW_HIDE); | 38 platform_window_->Hide(); |
62 } | 39 } |
63 | 40 |
64 virtual void Close() OVERRIDE { | 41 virtual void Close() OVERRIDE { |
65 DestroyWindow(hwnd()); | 42 platform_window_->Close(); |
66 } | 43 } |
67 | 44 |
68 virtual gfx::Size GetSize() OVERRIDE { | 45 virtual gfx::Size GetSize() OVERRIDE { |
69 RECT cr; | 46 return platform_window_->GetBounds().size(); |
70 GetClientRect(hwnd(), &cr); | |
71 return gfx::Size(cr.right - cr.left, cr.bottom - cr.top); | |
72 } | 47 } |
73 | 48 |
74 virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE { | 49 virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE { |
75 gfx::Rect window_bounds = GetWindowBoundsForClientBounds( | 50 platform_window_->SetBounds(bounds); |
76 GetWindowLong(hwnd(), GWL_STYLE), | |
77 GetWindowLong(hwnd(), GWL_EXSTYLE), | |
78 bounds); | |
79 SetWindowPos(hwnd(), NULL, window_bounds.x(), window_bounds.y(), | |
80 window_bounds.width(), window_bounds.height(), | |
81 SWP_NOREPOSITION); | |
82 } | 51 } |
83 | 52 |
84 virtual void SetCapture() OVERRIDE { | 53 virtual void SetCapture() OVERRIDE { |
85 DCHECK(::GetCapture() != hwnd()); | 54 platform_window_->SetCapture(); |
86 ::SetCapture(hwnd()); | |
87 } | 55 } |
88 | 56 |
89 virtual void ReleaseCapture() OVERRIDE { | 57 virtual void ReleaseCapture() OVERRIDE { |
90 if (::GetCapture() == hwnd()) | 58 platform_window_->ReleaseCapture(); |
91 ::ReleaseCapture(); | |
92 } | 59 } |
93 | 60 |
94 CR_BEGIN_MSG_MAP_EX(NativeViewportWin) | 61 // ui::PlatformWindowDelegate: |
95 CR_MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange) | 62 virtual void OnBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE { |
| 63 delegate_->OnBoundsChanged(new_bounds); |
| 64 } |
96 | 65 |
97 CR_MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyEvent) | 66 virtual void OnDamageRect(const gfx::Rect& damaged_region) OVERRIDE { |
98 CR_MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyEvent) | 67 } |
99 CR_MESSAGE_HANDLER_EX(WM_SYSKEYDOWN, OnKeyEvent) | |
100 CR_MESSAGE_HANDLER_EX(WM_SYSKEYUP, OnKeyEvent) | |
101 CR_MESSAGE_HANDLER_EX(WM_CHAR, OnKeyEvent) | |
102 CR_MESSAGE_HANDLER_EX(WM_SYSCHAR, OnKeyEvent) | |
103 CR_MESSAGE_HANDLER_EX(WM_IME_CHAR, OnKeyEvent) | |
104 | 68 |
105 CR_MSG_WM_CREATE(OnCreate) | 69 virtual void DispatchEvent(ui::Event* event) OVERRIDE { |
106 CR_MSG_WM_DESTROY(OnDestroy) | 70 delegate_->OnEvent(event); |
107 CR_MSG_WM_PAINT(OnPaint) | 71 } |
108 CR_MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged) | |
109 CR_END_MSG_MAP() | |
110 | 72 |
111 LRESULT OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) { | 73 virtual void OnCloseRequest() OVERRIDE { |
112 MSG msg = { hwnd(), message, w_param, l_param, 0, | 74 platform_window_->Close(); |
113 { CR_GET_X_LPARAM(l_param), CR_GET_Y_LPARAM(l_param) } }; | |
114 ui::MouseEvent event(msg); | |
115 if (ui::IsMouseEventFromTouch(message)) | |
116 event.set_flags(event.flags() | ui::EF_FROM_TOUCH); | |
117 SetMsgHandled(delegate_->OnEvent(&event)); | |
118 return 0; | |
119 } | 75 } |
120 LRESULT OnKeyEvent(UINT message, WPARAM w_param, LPARAM l_param) { | 76 |
121 MSG msg = { hwnd(), message, w_param, l_param }; | 77 virtual void OnClosed() OVERRIDE { |
122 ui::KeyEvent event(msg, message == WM_CHAR); | |
123 SetMsgHandled(delegate_->OnEvent(&event)); | |
124 return 0; | |
125 } | |
126 LRESULT OnCreate(CREATESTRUCT* create_struct) { | |
127 delegate_->OnAcceleratedWidgetAvailable(hwnd()); | |
128 return 0; | |
129 } | |
130 void OnDestroy() { | |
131 delegate_->OnDestroyed(); | 78 delegate_->OnDestroyed(); |
132 } | 79 } |
133 void OnPaint(HDC) { | |
134 RECT cr; | |
135 GetClientRect(hwnd(), &cr); | |
136 | 80 |
137 PAINTSTRUCT ps; | 81 virtual void OnWindowStateChanged(ui::PlatformWindowState state) OVERRIDE { |
138 HDC dc = BeginPaint(hwnd(), &ps); | |
139 HBRUSH red_brush = CreateSolidBrush(RGB(255, 0, 0)); | |
140 HGDIOBJ old_object = SelectObject(dc, red_brush); | |
141 Rectangle(dc, cr.left, cr.top, cr.right, cr.bottom); | |
142 SelectObject(dc, old_object); | |
143 DeleteObject(red_brush); | |
144 EndPaint(hwnd(), &ps); | |
145 } | |
146 void OnWindowPosChanged(WINDOWPOS* window_pos) { | |
147 if (!(window_pos->flags & SWP_NOSIZE) || | |
148 !(window_pos->flags & SWP_NOMOVE)) { | |
149 RECT cr; | |
150 GetClientRect(hwnd(), &cr); | |
151 delegate_->OnBoundsChanged( | |
152 gfx::Rect(window_pos->x, window_pos->y, | |
153 cr.right - cr.left, cr.bottom - cr.top)); | |
154 } | |
155 } | 82 } |
156 | 83 |
| 84 virtual void OnLostCapture() OVERRIDE { |
| 85 } |
| 86 |
| 87 virtual void OnAcceleratedWidgetAvailable( |
| 88 gfx::AcceleratedWidget widget) OVERRIDE { |
| 89 delegate_->OnAcceleratedWidgetAvailable(widget); |
| 90 } |
| 91 |
| 92 scoped_ptr<ui::PlatformWindow> platform_window_; |
157 NativeViewportDelegate* delegate_; | 93 NativeViewportDelegate* delegate_; |
158 | 94 |
159 DISALLOW_COPY_AND_ASSIGN(NativeViewportWin); | 95 DISALLOW_COPY_AND_ASSIGN(NativeViewportWin); |
160 }; | 96 }; |
161 | 97 |
162 // static | 98 // static |
163 scoped_ptr<NativeViewport> NativeViewport::Create( | 99 scoped_ptr<NativeViewport> NativeViewport::Create( |
164 shell::Context* context, | 100 shell::Context* context, |
165 NativeViewportDelegate* delegate) { | 101 NativeViewportDelegate* delegate) { |
166 return scoped_ptr<NativeViewport>(new NativeViewportWin(delegate)).Pass(); | 102 return scoped_ptr<NativeViewport>(new NativeViewportWin(delegate)).Pass(); |
167 } | 103 } |
168 | 104 |
169 } // namespace services | 105 } // namespace services |
170 } // namespace mojo | 106 } // namespace mojo |
OLD | NEW |