Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Side by Side Diff: webkit/port/platform/chromium/PopupMenuChromium.cpp

Issue 8885: Implementation of the UI part of the autofill (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/port/platform/chromium/PopupMenuChromium.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008, Google Inc. 1 // Copyright (c) 2008, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 18 matching lines...) Expand all
29 29
30 #include "config.h" 30 #include "config.h"
31 31
32 #pragma warning(push, 0) 32 #pragma warning(push, 0)
33 #include "PopupMenu.h" 33 #include "PopupMenu.h"
34 34
35 #include "CharacterNames.h" 35 #include "CharacterNames.h"
36 #include "ChromeClientChromium.h" 36 #include "ChromeClientChromium.h"
37 #include "Document.h" 37 #include "Document.h"
38 #include "Font.h" 38 #include "Font.h"
39 #include "Frame.h"
40 #include "FrameView.h" 39 #include "FrameView.h"
41 #include "FontSelector.h" 40 #include "FontSelector.h"
41 #include "Frame.h"
42 #include "FramelessScrollView.h" 42 #include "FramelessScrollView.h"
43 #include "FramelessScrollViewClient.h" 43 #include "FramelessScrollViewClient.h"
44 #include "GraphicsContext.h" 44 #include "GraphicsContext.h"
45 #include "IntRect.h" 45 #include "IntRect.h"
46 #include "KeyboardCodes.h" 46 #include "KeyboardCodes.h"
47 #include "NotImplemented.h" 47 #include "NotImplemented.h"
48 #include "Page.h" 48 #include "Page.h"
49 #include "PlatformKeyboardEvent.h" 49 #include "PlatformKeyboardEvent.h"
50 #include "PlatformMouseEvent.h" 50 #include "PlatformMouseEvent.h"
51 #include "PlatformScreen.h" 51 #include "PlatformScreen.h"
52 #include "PlatformWheelEvent.h" 52 #include "PlatformWheelEvent.h"
53 #include "RenderBlock.h" 53 #include "RenderBlock.h"
54 #include "RenderTheme.h" 54 #include "RenderTheme.h"
55 #include "ScrollbarTheme.h" 55 #include "ScrollbarTheme.h"
56 #include "SystemTime.h" 56 #include "SystemTime.h"
57 #include "Widget.h" 57 #include "Widget.h"
58 #pragma warning(pop) 58 #pragma warning(pop)
59 59
60 #include "webkit/port/platform/chromium/PopupMenuChromium.h"
61
60 using namespace WTF; 62 using namespace WTF;
61 using namespace Unicode; 63 using namespace Unicode;
62 64
63 using std::min; 65 using std::min;
64 using std::max; 66 using std::max;
65 67
66 namespace WebCore { 68 namespace WebCore {
67 69
68 typedef unsigned long long TimeStamp; 70 typedef unsigned long long TimeStamp;
69 71
70 static const int kMaxVisibleRows = 20; 72 static const int kMaxVisibleRows = 20;
71 static const int kMaxHeight = 500; 73 static const int kMaxHeight = 500;
72 static const int kBorderSize = 1; 74 static const int kBorderSize = 1;
73 static const TimeStamp kTypeAheadTimeoutMs = 1000; 75 static const TimeStamp kTypeAheadTimeoutMs = 1000;
74 76
75 class PopupListBox;
76
77 // TODO(darin): Our FramelessScrollView classes need to implement HostWindow!
78
79 // This class holds a PopupListBox. Its sole purpose is to be able to draw
80 // a border around its child. All its paint/event handling is just forwarded
81 // to the child listBox (with the appropriate transforms).
82 class PopupContainer : public FramelessScrollView, public RefCounted<PopupContai ner> {
83 public:
84 static PassRefPtr<PopupContainer> create(PopupMenuClient* client);
85
86 // FramelessScrollView
87 virtual void paint(GraphicsContext* gc, const IntRect& rect);
88 virtual void hide();
89 virtual bool handleMouseDownEvent(const PlatformMouseEvent& event);
90 virtual bool handleMouseMoveEvent(const PlatformMouseEvent& event);
91 virtual bool handleMouseReleaseEvent(const PlatformMouseEvent& event);
92 virtual bool handleWheelEvent(const PlatformWheelEvent& event);
93 virtual bool handleKeyEvent(const PlatformKeyboardEvent& event);
94
95 // PopupContainer methods
96
97 // Show the popup
98 void showPopup(FrameView* view);
99
100 // Hide the popup. Do not call this directly: use client->hidePopup().
101 void hidePopup();
102
103 // Compute size of widget and children.
104 void layout();
105
106 PopupListBox* listBox() const { return m_listBox.get(); }
107
108 private:
109 friend class RefCounted<PopupContainer>;
110
111 PopupContainer(PopupMenuClient* client);
112 ~PopupContainer();
113
114 // Paint the border.
115 void paintBorder(GraphicsContext* gc, const IntRect& rect);
116
117 RefPtr<PopupListBox> m_listBox;
118 };
119
120 // This class uses WebCore code to paint and handle events for a drop-down list 77 // This class uses WebCore code to paint and handle events for a drop-down list
121 // box ("combobox" on Windows). 78 // box ("combobox" on Windows).
122 class PopupListBox : public FramelessScrollView, public RefCounted<PopupListBox> { 79 class PopupListBox : public FramelessScrollView, public RefCounted<PopupListBox> {
123 public: 80 public:
124 // FramelessScrollView 81 // FramelessScrollView
125 virtual void paint(GraphicsContext* gc, const IntRect& rect); 82 virtual void paint(GraphicsContext* gc, const IntRect& rect);
126 virtual bool handleMouseDownEvent(const PlatformMouseEvent& event); 83 virtual bool handleMouseDownEvent(const PlatformMouseEvent& event);
127 virtual bool handleMouseMoveEvent(const PlatformMouseEvent& event); 84 virtual bool handleMouseMoveEvent(const PlatformMouseEvent& event);
128 virtual bool handleMouseReleaseEvent(const PlatformMouseEvent& event); 85 virtual bool handleMouseReleaseEvent(const PlatformMouseEvent& event);
129 virtual bool handleWheelEvent(const PlatformWheelEvent& event); 86 virtual bool handleWheelEvent(const PlatformWheelEvent& event);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 int numItems() const { return static_cast<int>(m_items.size()); } 120 int numItems() const { return static_cast<int>(m_items.size()); }
164 121
165 void setBaseWidth(int width) 122 void setBaseWidth(int width)
166 { 123 {
167 m_baseWidth = width; 124 m_baseWidth = width;
168 } 125 }
169 126
170 // Compute size of widget and children. 127 // Compute size of widget and children.
171 void layout(); 128 void layout();
172 129
130 // Returns whether the popup wants to process events for the passed key.
131 bool isInterestedInEventForKey(int key_code);
132
173 private: 133 private:
174 friend class PopupContainer; 134 friend class PopupContainer;
175 friend class RefCounted<PopupListBox>; 135 friend class RefCounted<PopupListBox>;
176 136
177 // A type of List Item 137 // A type of List Item
178 enum ListItemType { 138 enum ListItemType {
179 TYPE_OPTION, 139 TYPE_OPTION,
180 TYPE_GROUP, 140 TYPE_GROUP,
181 TYPE_SEPARATOR 141 TYPE_SEPARATOR
182 }; 142 };
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.pos()); 280 IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.pos());
321 relativePos.setX(pos.x()); 281 relativePos.setX(pos.x());
322 relativePos.setY(pos.y()); 282 relativePos.setY(pos.y());
323 return relativeEvent; 283 return relativeEvent;
324 } 284 }
325 285
326 /////////////////////////////////////////////////////////////////////////////// 286 ///////////////////////////////////////////////////////////////////////////////
327 // PopupContainer implementation 287 // PopupContainer implementation
328 288
329 // static 289 // static
330 PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client) 290 PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client,
291 bool focusOnShow)
331 { 292 {
332 return adoptRef(new PopupContainer(client)); 293 return adoptRef(new PopupContainer(client, focusOnShow));
333 } 294 }
334 295
335 PopupContainer::PopupContainer(PopupMenuClient* client) 296 PopupContainer::PopupContainer(PopupMenuClient* client, bool focusOnShow)
336 : m_listBox(new PopupListBox(client)) 297 : m_listBox(new PopupListBox(client)),
298 m_focusOnShow(focusOnShow)
337 { 299 {
338 // FrameViews are created with a refcount of 1 so it needs releasing after w e 300 // FrameViews are created with a refcount of 1 so it needs releasing after w e
339 // assign it to a RefPtr. 301 // assign it to a RefPtr.
340 m_listBox->deref(); 302 m_listBox->deref();
341 303
342 setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); 304 setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
343 } 305 }
344 306
345 PopupContainer::~PopupContainer() 307 PopupContainer::~PopupContainer()
346 { 308 {
(...skipping 13 matching lines...) Expand all
360 ChromeClientChromium* chromeClient = static_cast<ChromeClientChromium*>( 322 ChromeClientChromium* chromeClient = static_cast<ChromeClientChromium*>(
361 view->frame()->page()->chrome()->client()); 323 view->frame()->page()->chrome()->client());
362 if (chromeClient) { 324 if (chromeClient) {
363 // If the popup would extend past the bottom of the screen, open upwards 325 // If the popup would extend past the bottom of the screen, open upwards
364 // instead. 326 // instead.
365 FloatRect screen = screenRect(view); 327 FloatRect screen = screenRect(view);
366 IntRect widgetRect = chromeClient->windowToScreen(frameRect()); 328 IntRect widgetRect = chromeClient->windowToScreen(frameRect());
367 if (widgetRect.bottom() > static_cast<int>(screen.bottom())) 329 if (widgetRect.bottom() > static_cast<int>(screen.bottom()))
368 widgetRect.move(0, -(widgetRect.height() + selectHeight)); 330 widgetRect.move(0, -(widgetRect.height() + selectHeight));
369 331
370 chromeClient->popupOpened(this, widgetRect); 332 chromeClient->popupOpened(this, widgetRect, m_focusOnShow);
371 } 333 }
372 334
373 // Must get called after we have a client and containingWindow. 335 // Must get called after we have a client and containingWindow.
374 addChild(m_listBox.get()); 336 addChild(m_listBox.get());
375 337
376 // Enable scrollbars after the listbox is inserted into the hierarchy, so 338 // Enable scrollbars after the listbox is inserted into the hierarchy, so
377 // it has a proper WidgetClient. 339 // it has a proper WidgetClient.
378 m_listBox->setVerticalScrollbarMode(ScrollbarAuto); 340 m_listBox->setVerticalScrollbarMode(ScrollbarAuto);
379 341
380 m_listBox->scrollToRevealSelection(); 342 m_listBox->scrollToRevealSelection();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 int tx = x(); 429 int tx = x();
468 int ty = y(); 430 int ty = y();
469 431
470 // top, left, bottom, right 432 // top, left, bottom, right
471 gc->drawRect(IntRect(tx, ty, width(), kBorderSize)); 433 gc->drawRect(IntRect(tx, ty, width(), kBorderSize));
472 gc->drawRect(IntRect(tx, ty, kBorderSize, height())); 434 gc->drawRect(IntRect(tx, ty, kBorderSize, height()));
473 gc->drawRect(IntRect(tx, ty + height() - kBorderSize, width(), kBorderSize)) ; 435 gc->drawRect(IntRect(tx, ty + height() - kBorderSize, width(), kBorderSize)) ;
474 gc->drawRect(IntRect(tx + width() - kBorderSize, ty, kBorderSize, height())) ; 436 gc->drawRect(IntRect(tx + width() - kBorderSize, ty, kBorderSize, height())) ;
475 } 437 }
476 438
439 bool PopupContainer::isInterestedInEventForKey(int key_code) {
440 return m_listBox->isInterestedInEventForKey(key_code);
441 }
442
443 void PopupContainer::show(const IntRect& r, FrameView* v, int index) {
444 // The rect is the size of the select box. It's usually larger than we need.
445 // subtract border size so that usually the container will be displayed
446 // exactly the same width as the select box.
447 listBox()->setBaseWidth(max(r.width() - kBorderSize * 2, 0));
448
449 listBox()->updateFromElement();
450
451 // We set the selected item in updateFromElement(), and disregard the
452 // index passed into this function (same as Webkit's PopupMenuWin.cpp)
453 // TODO(ericroman): make sure this is correct, and add an assertion.
454 // DCHECK(popupWindow(popup)->listBox()->selectedIndex() == index);
455
456 // Convert point to main window coords.
457 IntPoint location = v->contentsToWindow(r.location());
458
459 // Move it below the select widget.
460 location.move(0, r.height());
461
462 IntRect popupRect(location, r.size());
463 setFrameRect(popupRect);
464 showPopup(v);
465 }
477 466
478 /////////////////////////////////////////////////////////////////////////////// 467 ///////////////////////////////////////////////////////////////////////////////
479 // PopupListBox implementation 468 // PopupListBox implementation
480 469
481 bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event) 470 bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event)
482 { 471 {
483 Scrollbar* scrollbar = scrollbarUnderMouse(event); 472 Scrollbar* scrollbar = scrollbarUnderMouse(event);
484 if (scrollbar) { 473 if (scrollbar) {
485 m_capturingScrollbar = scrollbar; 474 m_capturingScrollbar = scrollbar;
486 m_capturingScrollbar->mouseDown(event); 475 m_capturingScrollbar->mouseDown(event);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 abandon(); 530 abandon();
542 return true; 531 return true;
543 } 532 }
544 533
545 // Pass it off to the scroll view. 534 // Pass it off to the scroll view.
546 // Sadly, WebCore devs don't understand the whole "const" thing. 535 // Sadly, WebCore devs don't understand the whole "const" thing.
547 wheelEvent(const_cast<PlatformWheelEvent&>(event)); 536 wheelEvent(const_cast<PlatformWheelEvent&>(event));
548 return true; 537 return true;
549 } 538 }
550 539
540 // Should be kept in sync with handleKeyEvent().
541 bool PopupListBox::isInterestedInEventForKey(int key_code) {
542 switch (key_code) {
543 case VKEY_ESCAPE:
544 case VKEY_RETURN:
545 case VKEY_UP:
546 case VKEY_DOWN:
547 case VKEY_PRIOR:
548 case VKEY_NEXT:
549 case VKEY_HOME:
550 case VKEY_END:
551 return true;
552 default:
553 return false;
554 }
555 }
556
551 bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event) 557 bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
552 { 558 {
553 if (event.type() == PlatformKeyboardEvent::KeyUp) 559 if (event.type() == PlatformKeyboardEvent::KeyUp)
554 return true; 560 return true;
555 561
556 if (numItems() == 0 && event.windowsVirtualKeyCode() != VKEY_ESCAPE) 562 if (numItems() == 0 && event.windowsVirtualKeyCode() != VKEY_ESCAPE)
557 return true; 563 return true;
558 564
559 switch (event.windowsVirtualKeyCode()) { 565 switch (event.windowsVirtualKeyCode()) {
560 case VKEY_ESCAPE: 566 case VKEY_ESCAPE:
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 { 1035 {
1030 } 1036 }
1031 1037
1032 PopupMenu::~PopupMenu() 1038 PopupMenu::~PopupMenu()
1033 { 1039 {
1034 hide(); 1040 hide();
1035 } 1041 }
1036 1042
1037 void PopupMenu::show(const IntRect& r, FrameView* v, int index) 1043 void PopupMenu::show(const IntRect& r, FrameView* v, int index)
1038 { 1044 {
1039 p.m_popup = PopupContainer::create(client()); 1045 p.m_popup = PopupContainer::create(client(), true);
1040 1046 p.m_popup->show(r, v, index);
1041 // The rect is the size of the select box. It's usually larger than we need.
1042 // subtract border size so that usually the container will be displayed
1043 // exactly the same width as the select box.
1044 p.m_popup->listBox()->setBaseWidth(max(r.width() - kBorderSize * 2, 0));
1045
1046 updateFromElement();
1047
1048 // We set the selected item in updateFromElement(), and disregard the
1049 // index passed into this function (same as Webkit's PopupMenuWin.cpp)
1050 // TODO(ericroman): make sure this is correct, and add an assertion.
1051 // DCHECK(popupWindow(m_popup)->listBox()->selectedIndex() == index);
1052
1053 // Convert point to main window coords.
1054 IntPoint location = v->contentsToWindow(r.location());
1055
1056 // Move it below the select widget.
1057 location.move(0, r.height());
1058
1059 IntRect popupRect(location, r.size());
1060 p.m_popup->setFrameRect(popupRect);
1061 p.m_popup->showPopup(v);
1062 } 1047 }
1063 1048
1064 void PopupMenu::hide() 1049 void PopupMenu::hide()
1065 { 1050 {
1066 if (p.m_popup) { 1051 if (p.m_popup) {
1067 p.m_popup->hidePopup(); 1052 p.m_popup->hidePopup();
1068 p.m_popup = 0; 1053 p.m_popup = 0;
1069 } 1054 }
1070 } 1055 }
1071 1056
1072 void PopupMenu::updateFromElement() 1057 void PopupMenu::updateFromElement()
1073 { 1058 {
1074 p.m_popup->listBox()->updateFromElement(); 1059 p.m_popup->listBox()->updateFromElement();
1075 } 1060 }
1076 1061
1077 bool PopupMenu::itemWritingDirectionIsNatural() 1062 bool PopupMenu::itemWritingDirectionIsNatural()
1078 { 1063 {
1079 return false; 1064 return false;
1080 } 1065 }
1081 1066
1082 } // namespace WebCore 1067 } // namespace WebCore
OLDNEW
« no previous file with comments | « webkit/port/platform/chromium/PopupMenuChromium.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698