summaryrefslogtreecommitdiffstats
path: root/webkit/tools/test_shell/mac/webwidget_host.mm
diff options
context:
space:
mode:
authoramanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-15 19:54:42 +0000
committeramanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-15 19:54:42 +0000
commitfaf19bbf27a42842d4d2bc9a1e689dfcac3bd675 (patch)
treeffd7eb58cac407e6f66595f5201fb4b394260d17 /webkit/tools/test_shell/mac/webwidget_host.mm
parent8dd3dddd1cd80d28cc8237a5dbcf9f60e3c24566 (diff)
downloadchromium_src-faf19bbf27a42842d4d2bc9a1e689dfcac3bd675.zip
chromium_src-faf19bbf27a42842d4d2bc9a1e689dfcac3bd675.tar.gz
chromium_src-faf19bbf27a42842d4d2bc9a1e689dfcac3bd675.tar.bz2
Add test shell WebView and WebWidget host classes. This are stopgaps and
are subject to change as the rest of the rendering and event handling paths come together. Review URL: http://codereview.chromium.org/3062 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2230 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/tools/test_shell/mac/webwidget_host.mm')
-rw-r--r--webkit/tools/test_shell/mac/webwidget_host.mm260
1 files changed, 260 insertions, 0 deletions
diff --git a/webkit/tools/test_shell/mac/webwidget_host.mm b/webkit/tools/test_shell/mac/webwidget_host.mm
new file mode 100644
index 0000000..bf38fc4
--- /dev/null
+++ b/webkit/tools/test_shell/mac/webwidget_host.mm
@@ -0,0 +1,260 @@
+// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+#include "webkit/tools/test_shell/webwidget_host.h"
+
+#include "base/gfx/platform_canvas_mac.h"
+#include "base/gfx/rect.h"
+#include "base/gfx/size.h"
+#include "base/logging.h"
+#include "webkit/glue/webinputevent.h"
+#include "webkit/glue/webwidget.h"
+
+/*static*/
+WebWidgetHost* WebWidgetHost::Create(NSWindow* parent_window,
+ WebWidgetDelegate* delegate) {
+ WebWidgetHost* host = new WebWidgetHost();
+
+ NSRect content_rect = [parent_window frame];
+ content_rect.origin.y += 64;
+ content_rect.size.height -= 64;
+ host->view_ = [[NSView alloc] initWithFrame:content_rect];
+ [[parent_window contentView] addSubview:host->view_];
+
+ // win_util::SetWindowUserData(host->hwnd_, host);
+
+ host->webwidget_ = WebWidget::Create(delegate);
+ host->webwidget_->Resize(gfx::Size(content_rect.size.width,
+ content_rect.size.height));
+ return host;
+}
+
+/*static*/
+WebWidgetHost* WebWidgetHost::FromWindow(NSWindow* hwnd) {
+ return NULL;
+}
+
+/*static*/
+void WebWidgetHost::HandleEvent(NSWindow *window, NSEvent *event) {
+ WebWidgetHost* host = FromWindow(window);
+ if (host) {
+ switch ([event type]) {
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
+ case NSMouseEntered:
+ case NSMouseExited:
+ host->MouseEvent(event);
+ break;
+
+ case NSScrollWheel:
+ host->WheelEvent(event);
+ break;
+
+ case NSKeyDown:
+ case NSKeyUp:
+ host->KeyEvent(event);
+ break;
+
+ case NSAppKitDefined:
+ switch ([event subtype]) {
+ case NSApplicationActivatedEventType:
+ host->SetFocus(true);
+ break;
+ case NSApplicationDeactivatedEventType:
+ host->SetFocus(false);
+ break;
+ }
+ break;
+ }
+ }
+}
+
+void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
+ DLOG_IF(WARNING, painting_) << "unexpected invalidation while painting";
+
+ // If this invalidate overlaps with a pending scroll, then we have to
+ // downgrade to invalidating the scroll rect.
+ if (damaged_rect.Intersects(scroll_rect_)) {
+ paint_rect_ = paint_rect_.Union(scroll_rect_);
+ ResetScrollRect();
+ }
+ paint_rect_ = paint_rect_.Union(damaged_rect);
+
+ NSRect r = NSRectFromCGRect(damaged_rect.ToCGRect());
+ [view_ setNeedsDisplayInRect:r];
+}
+
+void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
+ DCHECK(dx || dy);
+
+ // If we already have a pending scroll operation or if this scroll operation
+ // intersects the existing paint region, then just failover to invalidating.
+ if (!scroll_rect_.IsEmpty() || paint_rect_.Intersects(clip_rect)) {
+ paint_rect_ = paint_rect_.Union(scroll_rect_);
+ ResetScrollRect();
+ paint_rect_ = paint_rect_.Union(clip_rect);
+ }
+
+ // We will perform scrolling lazily, when requested to actually paint.
+ scroll_rect_ = clip_rect;
+ scroll_dx_ = dx;
+ scroll_dy_ = dy;
+
+ NSRect r = NSRectFromCGRect(clip_rect.ToCGRect());
+ [view_ setNeedsDisplayInRect:r];
+}
+
+// void WebWidgetHost::SetCursor(HCURSOR cursor) {
+// }
+
+void WebWidgetHost::DiscardBackingStore() {
+ canvas_.reset();
+}
+
+WebWidgetHost::WebWidgetHost()
+ : view_(NULL),
+ webwidget_(NULL),
+ scroll_dx_(0),
+ scroll_dy_(0),
+ track_mouse_leave_(false)
+{
+ set_painting(false);
+}
+
+WebWidgetHost::~WebWidgetHost() {
+ // win_util::SetWindowUserData(hwnd_, 0);
+
+ TrackMouseLeave(false);
+
+ webwidget_->Close();
+ webwidget_->Release();
+}
+
+void WebWidgetHost::Paint() {
+ NSRect r = [view_ frame];
+ gfx::Rect client_rect(NSRectToCGRect(r));
+ NSGraphicsContext* view_context = [NSGraphicsContext currentContext];
+ CGContextRef context = static_cast<CGContextRef>([view_context graphicsPort]);
+
+ // Allocate a canvas if necessary
+ if (!canvas_.get()) {
+ ResetScrollRect();
+ paint_rect_ = client_rect;
+ canvas_.reset(new gfx::PlatformCanvas(
+ paint_rect_.width(), paint_rect_.height(), true));
+ }
+
+ // make sure webkit draws into our bitmap, not the window
+ CGContextRef bitmap_context =
+ canvas_->getTopPlatformDevice().GetBitmapContext();
+ [NSGraphicsContext setCurrentContext:
+ [NSGraphicsContext graphicsContextWithGraphicsPort:bitmap_context
+ flipped:NO]];
+
+ // This may result in more invalidation
+ webwidget_->Layout();
+
+ // Scroll the canvas if necessary
+ scroll_rect_ = client_rect.Intersect(scroll_rect_);
+ if (!scroll_rect_.IsEmpty()) {
+ // add to invalidate rect, since there's no equivalent of ScrollDC.
+ paint_rect_.Union(scroll_rect_);
+ }
+ ResetScrollRect();
+
+ // Paint the canvas if necessary. Allow painting to generate extra rects the
+ // first time we call it. This is necessary because some WebCore rendering
+ // objects update their layout only when painted.
+ for (int i = 0; i < 2; ++i) {
+ paint_rect_ = client_rect;//.Intersect(paint_rect_);
+ if (!paint_rect_.IsEmpty()) {
+ gfx::Rect rect(paint_rect_);
+ paint_rect_ = gfx::Rect();
+
+// DLOG_IF(WARNING, i == 1) << "painting caused additional invalidations";
+ PaintRect(rect);
+ }
+ }
+ DCHECK(paint_rect_.IsEmpty());
+
+ // set the context back to our window
+ [NSGraphicsContext setCurrentContext: view_context];
+
+ // Paint to the screen
+ if ([view_ lockFocusIfCanDraw]) {
+ CGRect paint_rect = NSRectToCGRect(r);
+ int bitmap_height = CGBitmapContextGetHeight(bitmap_context);
+ int bitmap_width = CGBitmapContextGetWidth(bitmap_context);
+ CGRect bitmap_rect = { { 0, 0 },
+ { bitmap_width, bitmap_height } };
+ canvas_->getTopPlatformDevice().DrawToContext(
+ context, 0, client_rect.height() - bitmap_height, &bitmap_rect);
+
+ [view_ unlockFocus];
+ }
+
+ // Draw children
+ // UpdateWindow(hwnd_);
+}
+
+void WebWidgetHost::Resize(const gfx::Rect& rect) {
+ // Force an entire re-paint. TODO(darin): Maybe reuse this memory buffer.
+ DiscardBackingStore();
+ webwidget_->Resize(gfx::Size(rect.width(), rect.height()));
+}
+
+void WebWidgetHost::MouseEvent(NSEvent *event) {
+ WebMouseEvent web_event(event);
+ switch (event.type) {
+ case WebInputEvent::MOUSE_MOVE:
+ TrackMouseLeave(true);
+ break;
+ case WebInputEvent::MOUSE_LEAVE:
+ TrackMouseLeave(false);
+ break;
+ case WebInputEvent::MOUSE_DOWN:
+ break;
+ case WebInputEvent::MOUSE_UP:
+ break;
+ }
+ webwidget_->HandleInputEvent(&web_event);
+}
+
+void WebWidgetHost::WheelEvent(NSEvent *event) {
+ WebMouseWheelEvent web_event(event);
+ webwidget_->HandleInputEvent(&web_event);
+}
+
+void WebWidgetHost::KeyEvent(NSEvent *event) {
+ WebKeyboardEvent web_event(event);
+ webwidget_->HandleInputEvent(&web_event);
+}
+
+void WebWidgetHost::SetFocus(bool enable) {
+ webwidget_->SetFocus(enable);
+}
+
+void WebWidgetHost::TrackMouseLeave(bool track) {
+}
+
+void WebWidgetHost::ResetScrollRect() {
+ scroll_rect_ = gfx::Rect();
+ scroll_dx_ = 0;
+ scroll_dy_ = 0;
+}
+
+void WebWidgetHost::PaintRect(const gfx::Rect& rect) {
+ DCHECK(!painting_);
+ DCHECK(canvas_.get());
+
+ set_painting(true);
+ webwidget_->Paint(canvas_.get(), rect);
+ set_painting(false);
+}