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

📄 popupmenuchromium.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        gc->fillRect(rowRect, Color::white);    gc->fillRect(rowRect, backColor);        if (m_popupClient->itemIsSeparator(rowIndex)) {        IntRect separatorRect(            rowRect.x() + separatorPadding,            rowRect.y() + (rowRect.height() - separatorHeight) / 2,            rowRect.width() - 2 * separatorPadding, separatorHeight);        gc->fillRect(separatorRect, textColor);        return;    }        gc->setFillColor(textColor);    // Bunch of shit to deal with RTL text...    String itemText = m_popupClient->itemText(rowIndex);    unsigned length = itemText.length();    const UChar* str = itemText.characters();    TextRun textRun(str, length, false, 0, 0, itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft);    // FIXME: http://b/1210481 We should get the padding of individual option    // elements.  This probably implies changes to PopupMenuClient.    // Draw the item text    if (style.isVisible()) {        Font itemFont = getRowFont(rowIndex);        int textX = max(0, m_popupClient->clientPaddingLeft() - m_popupClient->clientInsetLeft());        int textY = rowRect.y() + itemFont.ascent() + (rowRect.height() - itemFont.height()) / 2;        gc->drawBidiText(itemFont, textRun, IntPoint(textX, textY));    }}Font PopupListBox::getRowFont(int rowIndex){    Font itemFont = m_popupClient->itemStyle(rowIndex).font();    if (m_popupClient->itemIsLabel(rowIndex)) {        // Bold-ify labels (ie, an <optgroup> heading).        FontDescription d = itemFont.fontDescription();        d.setWeight(FontWeightBold);        Font font(d, itemFont.letterSpacing(), itemFont.wordSpacing());        font.update(0);        return font;    }    return itemFont;}void PopupListBox::abandon(){    RefPtr<PopupListBox> keepAlive(this);    m_selectedIndex = m_originalIndex;    m_popupClient->hidePopup();    if (m_willAcceptOnAbandon)        m_popupClient->valueChanged(m_selectedIndex);}int PopupListBox::pointToRowIndex(const IntPoint& point){    int y = scrollY() + point.y();    // FIXME: binary search if perf matters.    for (int i = 0; i < numItems(); ++i) {        if (y < m_items[i]->y)            return i-1;    }    // Last item?    if (y < contentsHeight())        return m_items.size()-1;    return -1;}void PopupListBox::acceptIndex(int index){    ASSERT(index >= -1 && index < numItems());    if (index == -1 && m_popupClient) {      // Enter pressed with no selection, just close the popup.      m_popupClient->hidePopup();      return;    }    if (isSelectableItem(index)) {        RefPtr<PopupListBox> keepAlive(this);        // Hide ourselves first since valueChanged may have numerous side-effects.        m_popupClient->hidePopup();        // Tell the <select> PopupMenuClient what index was selected.        m_popupClient->valueChanged(index);    }}void PopupListBox::selectIndex(int index){    ASSERT(index >= 0 && index < numItems());    if (index != m_selectedIndex && isSelectableItem(index)) {        invalidateRow(m_selectedIndex);        m_selectedIndex = index;        invalidateRow(m_selectedIndex);        scrollToRevealSelection();    }}void PopupListBox::setOriginalIndex(int index){    m_originalIndex = m_selectedIndex = index;}int PopupListBox::getRowHeight(int index){    if (index < 0)        return 0;    return m_popupClient->itemStyle(index).font().height();}IntRect PopupListBox::getRowBounds(int index){    if (index < 0)        return IntRect(0, 0, visibleWidth(), getRowHeight(index));    return IntRect(0, m_items[index]->y, visibleWidth(), getRowHeight(index));}void PopupListBox::invalidateRow(int index){    if (index < 0)        return;    // Invalidate in the window contents, as FramelessScrollView::invalidateRect    // paints in the window coordinates.    invalidateRect(contentsToWindow(getRowBounds(index)));}void PopupListBox::scrollToRevealRow(int index){    if (index < 0)        return;    IntRect rowRect = getRowBounds(index);     if (rowRect.y() < scrollY()) {        // Row is above current scroll position, scroll up.        ScrollView::setScrollPosition(IntPoint(0, rowRect.y()));    } else if (rowRect.bottom() > scrollY() + visibleHeight()) {        // Row is below current scroll position, scroll down.        ScrollView::setScrollPosition(IntPoint(0, rowRect.bottom() - visibleHeight()));    }}bool PopupListBox::isSelectableItem(int index){    return m_items[index]->type == TypeOption && m_popupClient->itemIsEnabled(index);}void PopupListBox::clearSelection(){    if (m_selectedIndex != -1) {        invalidateRow(m_selectedIndex);        m_selectedIndex = -1;    }}void PopupListBox::selectNextRow(){    if (!m_settings.loopSelectionNavigation || m_selectedIndex != numItems() - 1) {        adjustSelectedIndex(1);        return;    }    // We are moving past the last item, no row should be selected.    clearSelection();}void PopupListBox::selectPreviousRow(){    if (!m_settings.loopSelectionNavigation || m_selectedIndex > 0) {        adjustSelectedIndex(-1);        return;    }    if (m_selectedIndex == 0) {        // We are moving past the first item, clear the selection.        clearSelection();        return;    }    // No row are selected, jump to the last item.    selectIndex(numItems() - 1);    scrollToRevealSelection();}void PopupListBox::adjustSelectedIndex(int delta){    int targetIndex = m_selectedIndex + delta;    targetIndex = min(max(targetIndex, 0), numItems() - 1);    if (!isSelectableItem(targetIndex)) {        // We didn't land on an option.  Try to find one.        // We try to select the closest index to target, prioritizing any in        // the range [current, target].        int dir = delta > 0 ? 1 : -1;        int testIndex = m_selectedIndex;        int bestIndex = m_selectedIndex;        bool passedTarget = false;        while (testIndex >= 0 && testIndex < numItems()) {            if (isSelectableItem(testIndex))                bestIndex = testIndex;            if (testIndex == targetIndex)                passedTarget = true;            if (passedTarget && bestIndex != m_selectedIndex)                break;            testIndex += dir;        }        // Pick the best index, which may mean we don't change.        targetIndex = bestIndex;    }    // Select the new index, and ensure its visible.  We do this regardless of    // whether the selection changed to ensure keyboard events always bring the    // selection into view.    selectIndex(targetIndex);    scrollToRevealSelection();}void PopupListBox::updateFromElement(){    // It happens when pressing a key to jump to an item, then use tab or    // mouse to get away from the select box. In that case, updateFromElement    // is called before abandon, which causes discarding of the select result.        if (m_willAcceptOnAbandon) {        m_popupClient->valueChanged(m_selectedIndex);        m_willAcceptOnAbandon = false;    }    clear();    int size = m_popupClient->listSize();    for (int i = 0; i < size; ++i) {        ListItemType type;        if (m_popupClient->itemIsSeparator(i))            type = PopupListBox::TypeSeparator;        else if (m_popupClient->itemIsLabel(i))            type = PopupListBox::TypeGroup;        else            type = PopupListBox::TypeOption;        m_items.append(new ListItem(m_popupClient->itemText(i), type));    }    m_selectedIndex = m_popupClient->selectedIndex();    setOriginalIndex(m_selectedIndex);    layout();}void PopupListBox::layout(){    // Size our child items.    int baseWidth = 0;    int paddingWidth = 0;    int y = 0;    for (int i = 0; i < numItems(); ++i) {        Font itemFont = getRowFont(i);        // Place the item vertically.        m_items[i]->y = y;        y += itemFont.height();        // Ensure the popup is wide enough to fit this item.        String text = m_popupClient->itemText(i);        if (!text.isEmpty()) {            int width = itemFont.width(TextRun(text));            baseWidth = max(baseWidth, width);        }        // FIXME: http://b/1210481 We should get the padding of individual option elements.        paddingWidth = max(paddingWidth,             m_popupClient->clientPaddingLeft() + m_popupClient->clientPaddingRight());    }    int windowHeight = 0;    m_visibleRows = min(numItems(), kMaxVisibleRows);    for (int i = 0; i < m_visibleRows; ++i) {        int rowHeight = getRowHeight(i);        if (windowHeight + rowHeight > kMaxHeight) {            m_visibleRows = i;            break;        }        windowHeight += rowHeight;    }    // Set our widget and scrollable contents sizes.    int scrollbarWidth = 0;    if (m_visibleRows < numItems())        scrollbarWidth = ScrollbarTheme::nativeTheme()->scrollbarThickness();    int windowWidth = baseWidth + scrollbarWidth + paddingWidth;    int contentWidth = baseWidth;    if (windowWidth < m_baseWidth) {        windowWidth = m_baseWidth;        contentWidth = m_baseWidth - scrollbarWidth - paddingWidth;    } else {        m_baseWidth = baseWidth;    }    resize(windowWidth, windowHeight);    setContentsSize(IntSize(contentWidth, getRowBounds(numItems() - 1).bottom()));    if (hostWindow())        scrollToRevealSelection();    invalidate();}void PopupListBox::clear(){    for (Vector<ListItem*>::iterator it = m_items.begin(); it != m_items.end(); ++it)        delete *it;    m_items.clear();}bool PopupListBox::isPointInBounds(const IntPoint& point){    return numItems() != 0 && IntRect(0, 0, width(), height()).contains(point);}///////////////////////////////////////////////////////////////////////////////// PopupMenu implementation// // Note: you cannot add methods to this class, since it is defined above the //       portability layer. To access methods and properties on the//       popup widgets, use |popupWindow| above. PopupMenu::PopupMenu(PopupMenuClient* client)     : m_popupClient(client){}PopupMenu::~PopupMenu(){    hide();}void PopupMenu::show(const IntRect& r, FrameView* v, int index) {    if (!p.popup)        p.popup = PopupContainer::create(client(), dropDownSettings);    p.popup->show(r, v, index);}void PopupMenu::hide(){    if (p.popup)        p.popup->hidePopup();}void PopupMenu::updateFromElement(){    p.popup->listBox()->updateFromElement();}bool PopupMenu::itemWritingDirectionIsNatural() {     return false; }} // namespace WebCore

⌨️ 快捷键说明

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