⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 popupmenuchromium.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2008, 2009, Google Inc. All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: *  *     * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. *     * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. *     * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "PopupMenuChromium.h"#include "CharacterNames.h"#include "ChromeClientChromium.h"#include "Font.h"#include "FontSelector.h"#include "FrameView.h"#include "Frame.h"#include "FramelessScrollView.h"#include "FramelessScrollViewClient.h"#include "GraphicsContext.h"#include "IntRect.h"#include "KeyboardCodes.h"#include "Page.h"#include "PlatformKeyboardEvent.h"#include "PlatformMouseEvent.h"#include "PlatformScreen.h"#include "PlatformWheelEvent.h"#include "PopupMenu.h"#include "RenderTheme.h"#include "ScrollbarTheme.h"#include "SystemTime.h"#include <wtf/CurrentTime.h>using namespace WTF;using namespace Unicode;using std::min;using std::max;namespace WebCore {typedef unsigned long long TimeStamp;static const int kMaxVisibleRows = 20;static const int kMaxHeight = 500;static const int kBorderSize = 1;static const TimeStamp kTypeAheadTimeoutMs = 1000;// The settings used for the drop down menu.// This is the delegate used if none is provided.static const PopupContainerSettings dropDownSettings = {    true, // focusOnShow    true, // setTextOnIndexChange    true, // acceptOnAbandon    false // loopSelectionNavigation};// This class uses WebCore code to paint and handle events for a drop-down list// box ("combobox" on Windows).class PopupListBox : public FramelessScrollView, public RefCounted<PopupListBox> {public:    static PassRefPtr<PopupListBox> create(PopupMenuClient* client, const PopupContainerSettings& settings)    {        return adoptRef(new PopupListBox(client, settings));    }    // FramelessScrollView    virtual void paint(GraphicsContext*, const IntRect&);    virtual bool handleMouseDownEvent(const PlatformMouseEvent&);    virtual bool handleMouseMoveEvent(const PlatformMouseEvent&);    virtual bool handleMouseReleaseEvent(const PlatformMouseEvent&);    virtual bool handleWheelEvent(const PlatformWheelEvent&);    virtual bool handleKeyEvent(const PlatformKeyboardEvent&);    // ScrollView    virtual HostWindow* hostWindow() const;    // PopupListBox methods    // Shows the popup    void showPopup();    // Hides the popup.  Do not call this directly: use client->hidePopup().    void hidePopup();    // Updates our internal list to match the client.    void updateFromElement();    // Frees any allocated resources used in a particular popup session.     void clear();    // Sets the index of the option that is displayed in the <select> widget in the page    void setOriginalIndex(int index);    // Gets the index of the item that the user is currently moused over or has selected with    // the keyboard. This is not the same as the original index, since the user has not yet    // accepted this input.    int selectedIndex() const { return m_selectedIndex; }    // Moves selection down/up the given number of items, scrolling if necessary.    // Positive is down.  The resulting index will be clamped to the range    // [0, numItems), and non-option items will be skipped.    void adjustSelectedIndex(int delta);    // Returns the number of items in the list.    int numItems() const { return static_cast<int>(m_items.size()); }    void setBaseWidth(int width) { m_baseWidth = width; }    // Computes the size of widget and children.    void layout();    // Returns whether the popup wants to process events for the passed key.    bool isInterestedInEventForKey(int keyCode);private:    friend class PopupContainer;    friend class RefCounted<PopupListBox>;    // A type of List Item    enum ListItemType {        TypeOption,        TypeGroup,        TypeSeparator    };    // A item (represented by <option> or <optgroup>) in the <select> widget.     struct ListItem {        ListItem(const String& label, ListItemType type)            : label(label.copy()), type(type), y(0) {}        String label;        ListItemType type;        int y;  // y offset of this item, relative to the top of the popup.    };    PopupListBox(PopupMenuClient* client, const PopupContainerSettings& settings)        : m_settings(settings)        , m_originalIndex(0)        , m_selectedIndex(0)        , m_willAcceptOnAbandon(false)        , m_visibleRows(0)        , m_popupClient(client)        , m_repeatingChar(0)        , m_lastCharTime(0)    {        setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);    }    ~PopupListBox()    {        clear();    }    void disconnectClient() { m_popupClient = 0; }    // Closes the popup    void abandon();    // Select an index in the list, scrolling if necessary.    void selectIndex(int index);    // Accepts the selected index as the value to be displayed in the <select> widget on    // the web page, and closes the popup.    void acceptIndex(int index);    // Returns true if the selection can be changed to index.    // Disabled items, or labels cannot be selected.    bool isSelectableItem(int index);    // Clears the selection (so no row appears selected).    void clearSelection();    // Scrolls to reveal the given index.    void scrollToRevealRow(int index);    void scrollToRevealSelection() { scrollToRevealRow(m_selectedIndex); }    // Invalidates the row at the given index.     void invalidateRow(int index);    // Gets the height of a row.    int getRowHeight(int index);    // Get the bounds of a row.     IntRect getRowBounds(int index);    // Converts a point to an index of the row the point is over    int pointToRowIndex(const IntPoint&);    // Paint an individual row    void paintRow(GraphicsContext*, const IntRect&, int rowIndex);    // Test if the given point is within the bounds of the popup window.    bool isPointInBounds(const IntPoint&);    // Called when the user presses a text key.  Does a prefix-search of the items.    void typeAheadFind(const PlatformKeyboardEvent&);    // Returns the font to use for the given row    Font getRowFont(int index);    // Moves the selection down/up one item, taking care of looping back to the    // first/last element if m_loopSelectionNavigation is true.    void selectPreviousRow();    void selectNextRow();    // The settings that specify the behavior for this Popup window.    PopupContainerSettings m_settings;    // This is the index of the item marked as "selected" - i.e. displayed in the widget on the    // page.     int m_originalIndex;    // This is the index of the item that the user is hovered over or has selected using the     // keyboard in the list. They have not confirmed this selection by clicking or pressing     // enter yet however.    int m_selectedIndex;    // True if we should accept the selectedIndex as chosen, even if the popup    // is "abandoned".  This is used for keyboard navigation, where we want the    // selection to change immediately, and is only used if the settings    // acceptOnAbandon field is true.    bool m_willAcceptOnAbandon;    // This is the number of rows visible in the popup. The maximum number visible at a time is    // defined as being kMaxVisibleRows. For a scrolled popup, this can be thought of as the    // page size in data units.     int m_visibleRows;    // Our suggested width, not including scrollbar.    int m_baseWidth;    // A list of the options contained within the <select>    Vector<ListItem*> m_items;    // The <select> PopupMenuClient that opened us.    PopupMenuClient* m_popupClient;    // The scrollbar which has mouse capture.  Mouse events go straight to this    // if non-NULL.    RefPtr<Scrollbar> m_capturingScrollbar;    // The last scrollbar that the mouse was over.  Used for mouseover highlights.    RefPtr<Scrollbar> m_lastScrollbarUnderMouse;    // The string the user has typed so far into the popup. Used for typeAheadFind.    String m_typedString;    // The char the user has hit repeatedly.  Used for typeAheadFind.    UChar m_repeatingChar;    // The last time the user hit a key.  Used for typeAheadFind.    TimeStamp m_lastCharTime;};static PlatformMouseEvent constructRelativeMouseEvent(const PlatformMouseEvent& e,                                                      FramelessScrollView* parent,                                                      FramelessScrollView* child){    IntPoint pos = parent->convertSelfToChild(child, e.pos());    // FIXME: This is a horrible hack since PlatformMouseEvent has no setters for x/y.    PlatformMouseEvent relativeEvent = e;    IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.pos());    relativePos.setX(pos.x());    relativePos.setY(pos.y());    return relativeEvent;}static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent& e,                                                      FramelessScrollView* parent,                                                      FramelessScrollView* child){    IntPoint pos = parent->convertSelfToChild(child, e.pos());    // FIXME: This is a horrible hack since PlatformWheelEvent has no setters for x/y.    PlatformWheelEvent relativeEvent = e;    IntPoint& relativePos = const_cast<IntPoint&>(relativeEvent.pos());    relativePos.setX(pos.x());    relativePos.setY(pos.y());    return relativeEvent;}///////////////////////////////////////////////////////////////////////////////// PopupContainer implementation// staticPassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client,                                                  const PopupContainerSettings& settings){    return adoptRef(new PopupContainer(client, settings));}PopupContainer::PopupContainer(PopupMenuClient* client, const PopupContainerSettings& settings)    : m_listBox(PopupListBox::create(client, settings))    , m_settings(settings){    setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);}PopupContainer::~PopupContainer(){    if (m_listBox)        removeChild(m_listBox.get());}void PopupContainer::showPopup(FrameView* view){    // Pre-layout, our size matches the <select> dropdown control.    int selectHeight = frameRect().height();    // Lay everything out to figure out our preferred size, then tell the view's    // WidgetClient about it.  It should assign us a client.    layout();    ChromeClientChromium* chromeClient = static_cast<ChromeClientChromium*>(        view->frame()->page()->chrome()->client());    if (chromeClient) {        // If the popup would extend past the bottom of the screen, open upwards        // instead.        FloatRect screen = screenAvailableRect(view);        IntRect widgetRect = chromeClient->windowToScreen(frameRect());        if (widgetRect.bottom() > static_cast<int>(screen.bottom()))            widgetRect.move(0, -(widgetRect.height() + selectHeight));        chromeClient->popupOpened(this, widgetRect, m_settings.focusOnShow);    }    if (!m_listBox->parent())        addChild(m_listBox.get());    // Enable scrollbars after the listbox is inserted into the hierarchy,    // so it has a proper WidgetClient.    m_listBox->setVerticalScrollbarMode(ScrollbarAuto);    m_listBox->scrollToRevealSelection();    invalidate();}void PopupContainer::hidePopup(){    if (client())        client()->popupClosed(this);}void PopupContainer::layout(){    m_listBox->layout();    // Place the listbox within our border.    m_listBox->move(kBorderSize, kBorderSize);    // Size ourselves to contain listbox + border.    resize(m_listBox->width() + kBorderSize * 2, m_listBox->height() + kBorderSize * 2);    invalidate();}bool PopupContainer::handleMouseDownEvent(const PlatformMouseEvent& event)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -