OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "webkit/glue/plugins/pepper_scrollbar.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/message_loop.h" | |
9 #include "ppapi/c/dev/ppp_scrollbar_dev.h" | |
10 #include "skia/ext/platform_canvas.h" | |
11 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" | |
12 #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" | |
13 #include "third_party/WebKit/WebKit/chromium/public/WebScrollbar.h" | |
14 #include "third_party/WebKit/WebKit/chromium/public/WebVector.h" | |
15 #include "webkit/glue/plugins/pepper_common.h" | |
16 #include "webkit/glue/plugins/pepper_event_conversion.h" | |
17 #include "webkit/glue/plugins/pepper_image_data.h" | |
18 #include "webkit/glue/plugins/pepper_plugin_instance.h" | |
19 #include "webkit/glue/plugins/pepper_plugin_module.h" | |
20 #include "webkit/glue/webkit_glue.h" | |
21 | |
22 #if defined(OS_WIN) | |
23 #include "base/win/windows_version.h" | |
24 #endif | |
25 | |
26 using WebKit::WebInputEvent; | |
27 using WebKit::WebRect; | |
28 using WebKit::WebScrollbar; | |
29 | |
30 namespace pepper { | |
31 | |
32 namespace { | |
33 | |
34 PP_Resource Create(PP_Instance instance_id, PP_Bool vertical) { | |
35 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); | |
36 if (!instance) | |
37 return 0; | |
38 | |
39 scoped_refptr<Scrollbar> scrollbar(new Scrollbar(instance, | |
40 PPBoolToBool(vertical))); | |
41 return scrollbar->GetReference(); | |
42 } | |
43 | |
44 PP_Bool IsScrollbar(PP_Resource resource) { | |
45 return BoolToPPBool(!!Resource::GetAs<Scrollbar>(resource)); | |
46 } | |
47 | |
48 uint32_t GetThickness() { | |
49 return WebScrollbar::defaultThickness(); | |
50 } | |
51 | |
52 uint32_t GetValue(PP_Resource resource) { | |
53 scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); | |
54 if (!scrollbar) | |
55 return 0; | |
56 return scrollbar->GetValue(); | |
57 } | |
58 | |
59 void SetValue(PP_Resource resource, uint32_t value) { | |
60 scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); | |
61 if (scrollbar) | |
62 scrollbar->SetValue(value); | |
63 } | |
64 | |
65 void SetDocumentSize(PP_Resource resource, uint32_t size) { | |
66 scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); | |
67 if (scrollbar) | |
68 scrollbar->SetDocumentSize(size); | |
69 } | |
70 | |
71 void SetTickMarks(PP_Resource resource, | |
72 const PP_Rect* tick_marks, | |
73 uint32_t count) { | |
74 scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); | |
75 if (scrollbar) | |
76 scrollbar->SetTickMarks(tick_marks, count); | |
77 } | |
78 | |
79 void ScrollBy(PP_Resource resource, PP_ScrollBy_Dev unit, int32_t multiplier) { | |
80 scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); | |
81 if (scrollbar) | |
82 scrollbar->ScrollBy(unit, multiplier); | |
83 } | |
84 | |
85 const PPB_Scrollbar_Dev ppb_scrollbar = { | |
86 &Create, | |
87 &IsScrollbar, | |
88 &GetThickness, | |
89 &GetValue, | |
90 &SetValue, | |
91 &SetDocumentSize, | |
92 &SetTickMarks, | |
93 &ScrollBy | |
94 }; | |
95 | |
96 } // namespace | |
97 | |
98 Scrollbar::Scrollbar(PluginInstance* instance, bool vertical) | |
99 : Widget(instance) { | |
100 scrollbar_.reset(WebScrollbar::create( | |
101 static_cast<WebKit::WebScrollbarClient*>(this), | |
102 vertical ? WebScrollbar::Vertical : WebScrollbar::Horizontal)); | |
103 } | |
104 | |
105 Scrollbar::~Scrollbar() { | |
106 } | |
107 | |
108 // static | |
109 const PPB_Scrollbar_Dev* Scrollbar::GetInterface() { | |
110 return &ppb_scrollbar; | |
111 } | |
112 | |
113 Scrollbar* Scrollbar::AsScrollbar() { | |
114 return this; | |
115 } | |
116 | |
117 uint32_t Scrollbar::GetValue() { | |
118 return scrollbar_->value(); | |
119 } | |
120 | |
121 void Scrollbar::SetValue(uint32_t value) { | |
122 scrollbar_->setValue(value); | |
123 } | |
124 | |
125 void Scrollbar::SetDocumentSize(uint32_t size) { | |
126 scrollbar_->setDocumentSize(size); | |
127 } | |
128 | |
129 void Scrollbar::SetTickMarks(const PP_Rect* tick_marks, uint32_t count) { | |
130 tickmarks_.resize(count); | |
131 for (uint32 i = 0; i < count; ++i) { | |
132 tickmarks_[i] = WebRect(tick_marks[i].point.x, | |
133 tick_marks[i].point.y, | |
134 tick_marks[i].size.width, | |
135 tick_marks[i].size.height);; | |
136 } | |
137 PP_Rect rect = location(); | |
138 Invalidate(&rect); | |
139 } | |
140 | |
141 void Scrollbar::ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier) { | |
142 WebScrollbar::ScrollDirection direction = multiplier >= 0 ? | |
143 WebScrollbar::ScrollForward : WebScrollbar::ScrollBackward; | |
144 float fmultiplier = 1.0; | |
145 | |
146 WebScrollbar::ScrollGranularity granularity; | |
147 if (unit == PP_SCROLLBY_LINE) { | |
148 granularity = WebScrollbar::ScrollByLine; | |
149 } else if (unit == PP_SCROLLBY_PAGE) { | |
150 granularity = WebScrollbar::ScrollByPage; | |
151 } else if (unit == PP_SCROLLBY_DOCUMENT) { | |
152 granularity = WebScrollbar::ScrollByDocument; | |
153 } else { | |
154 granularity = WebScrollbar::ScrollByPixel; | |
155 fmultiplier = static_cast<float>(multiplier); | |
156 if (fmultiplier < 0) | |
157 fmultiplier *= -1; | |
158 } | |
159 scrollbar_->scroll(direction, granularity, fmultiplier); | |
160 } | |
161 | |
162 bool Scrollbar::Paint(const PP_Rect* rect, ImageData* image) { | |
163 gfx::Rect gfx_rect(rect->point.x, | |
164 rect->point.y, | |
165 rect->size.width, | |
166 rect->size.height); | |
167 skia::PlatformCanvas* canvas = image->mapped_canvas(); | |
168 if (!canvas) | |
169 return false; | |
170 scrollbar_->paint(webkit_glue::ToWebCanvas(canvas), gfx_rect); | |
171 | |
172 #if defined(OS_WIN) | |
173 if (base::win::GetVersion() == base::win::VERSION_XP) { | |
174 canvas->getTopPlatformDevice().makeOpaque( | |
175 gfx_rect.x(), gfx_rect.y(), gfx_rect.width(), gfx_rect.height()); | |
176 } | |
177 #endif | |
178 | |
179 return true; | |
180 } | |
181 | |
182 bool Scrollbar::HandleEvent(const PP_InputEvent* event) { | |
183 scoped_ptr<WebInputEvent> web_input_event(CreateWebInputEvent(*event)); | |
184 if (!web_input_event.get()) | |
185 return false; | |
186 | |
187 return scrollbar_->handleInputEvent(*web_input_event.get()); | |
188 } | |
189 | |
190 void Scrollbar::SetLocationInternal(const PP_Rect* location) { | |
191 scrollbar_->setLocation(WebRect(location->point.x, | |
192 location->point.y, | |
193 location->size.width, | |
194 location->size.height)); | |
195 } | |
196 | |
197 void Scrollbar::valueChanged(WebKit::WebScrollbar* scrollbar) { | |
198 const PPP_Scrollbar_Dev* ppp_scrollbar = | |
199 static_cast<const PPP_Scrollbar_Dev*>( | |
200 module()->GetPluginInterface(PPP_SCROLLBAR_DEV_INTERFACE)); | |
201 if (!ppp_scrollbar) | |
202 return; | |
203 ScopedResourceId resource(this); | |
204 ppp_scrollbar->ValueChanged( | |
205 instance()->pp_instance(), resource.id, scrollbar_->value()); | |
206 } | |
207 | |
208 void Scrollbar::invalidateScrollbarRect(WebKit::WebScrollbar* scrollbar, | |
209 const WebKit::WebRect& rect) { | |
210 gfx::Rect gfx_rect(rect.x, | |
211 rect.y, | |
212 rect.width, | |
213 rect.height); | |
214 dirty_ = dirty_.Union(gfx_rect); | |
215 // Can't call into the client to tell them about the invalidate right away, | |
216 // since the Scrollbar code is still in the middle of updating its internal | |
217 // state. | |
218 MessageLoop::current()->PostTask( | |
219 FROM_HERE, | |
220 NewRunnableMethod(this, &Scrollbar::NotifyInvalidate)); | |
221 } | |
222 | |
223 void Scrollbar::getTickmarks( | |
224 WebKit::WebScrollbar* scrollbar, | |
225 WebKit::WebVector<WebKit::WebRect>* tick_marks) const { | |
226 if (tickmarks_.empty()) { | |
227 WebRect* rects = NULL; | |
228 tick_marks->assign(rects, 0); | |
229 } else { | |
230 tick_marks->assign(&tickmarks_[0], tickmarks_.size()); | |
231 } | |
232 } | |
233 | |
234 void Scrollbar::NotifyInvalidate() { | |
235 if (dirty_.IsEmpty()) | |
236 return; | |
237 PP_Rect pp_rect; | |
238 pp_rect.point.x = dirty_.x(); | |
239 pp_rect.point.y = dirty_.y(); | |
240 pp_rect.size.width = dirty_.width(); | |
241 pp_rect.size.height = dirty_.height(); | |
242 dirty_ = gfx::Rect(); | |
243 Invalidate(&pp_rect); | |
244 } | |
245 | |
246 } // namespace pepper | |
OLD | NEW |