18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
22fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *               2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     its contributors may be used to endorse or promote products derived
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     from this software without specific prior written permission.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderListBox.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "AXObjectCache.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSStyleSelector.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventHandler.h"
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "EventQueue.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FocusController.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HitTestResult.h"
44ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "NodeRenderStyle.h"
45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "OptionGroupElement.h"
46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "OptionElement.h"
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h"
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "PaintInfo.h"
492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "RenderLayer.h"
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderScrollbar.h"
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTheme.h"
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderView.h"
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Scrollbar.h"
54ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "ScrollbarTheme.h"
555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "SelectElement.h"
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SelectionController.h"
57ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "TextRun.h"
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h>
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int rowSpacing = 1;
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int optionsSpacingHorizontal = 2;
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int minSize = 4;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int maxDefaultSize = 10;
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: This hardcoded baselineAdjustment is what we used to do for the old
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// widget, but I'm not sure this is right for the new control.
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int baselineAdjustment = 7;
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
775f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRenderListBox::RenderListBox(Element* element)
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : RenderBlock(element)
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_optionsChanged(true)
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_scrollToRevealSelectionAfterLayout(false)
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_inAutoscroll(false)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_optionsWidth(0)
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_indexOffset(0)
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
852bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (Page* page = frame()->page()) {
862bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_page = page;
872bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_page->addScrollableArea(this);
882bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderListBox::~RenderListBox()
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setHasVerticalScrollbar(false);
942bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_page)
952bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_page->removeScrollableArea(this);
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::updateFromElement()
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_optionsChanged) {
1015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        const Vector<Element*>& listItems = toSelectElement(static_cast<Element*>(node()))->listItems();
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int size = numItems();
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        float width = 0;
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = 0; i < size; ++i) {
1065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            Element* element = listItems[i];
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            String text;
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Font itemFont = style()->font();
109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (OptionElement* optionElement = toOptionElement(element))
110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                text = optionElement->textIndentedToRespectGroupLabel();
111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            else if (OptionGroupElement* optionGroupElement = toOptionGroupElement(element)) {
112635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                text = optionGroupElement->groupLabelText();
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                FontDescription d = itemFont.fontDescription();
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                d.setWeight(d.bolderWeight());
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing());
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                itemFont.update(document()->styleSelector()->fontSelector());
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!text.isEmpty()) {
12081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                float textWidth = itemFont.width(TextRun(text.impl(), false, 0, 0, TextRun::AllowTrailingExpansion, false, false));
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                width = max(width, textWidth);
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_optionsWidth = static_cast<int>(ceilf(width));
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_optionsChanged = false;
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setHasVerticalScrollbar(true);
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setNeedsLayoutAndPrefWidthsRecalc();
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::selectionChanged()
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    repaint();
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_inAutoscroll) {
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_optionsChanged || needsLayout())
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_scrollToRevealSelectionAfterLayout = true;
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            scrollToRevealSelection();
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (AXObjectCache::accessibilityEnabled())
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        document()->axObjectCache()->selectedChildrenChanged(this);
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::layout()
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderBlock::layout();
1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_scrollToRevealSelectionAfterLayout) {
1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        view()->disableLayoutState();
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        scrollToRevealSelection();
1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        view()->enableLayoutState();
1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::scrollToRevealSelection()
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement* select = toSelectElement(static_cast<Element*>(node()));
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_scrollToRevealSelectionAfterLayout = false;
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int firstIndex = select->activeSelectionStartListIndex();
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (firstIndex >= 0 && !listIndexIsVisible(select->activeSelectionEndListIndex()))
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        scrollToRevealElementAtListIndex(firstIndex);
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
168bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderListBox::computePreferredLogicalWidths()
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_optionsChanged);
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
172bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_minPreferredLogicalWidth = 0;
173bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth = 0;
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->width().isFixed() && style()->width().value() > 0)
176bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->width().value());
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
178bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = m_optionsWidth + 2 * optionsSpacingHorizontal;
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_vBar)
180bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_maxPreferredLogicalWidth += m_vBar->width();
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
184bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
185bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent()))
187bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = 0;
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
189bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) {
192bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value()));
193bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value()));
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19621939df44de1705786c545cd1bf519d47250322dBen Murdoch    int toAdd = borderAndPaddingWidth();
197bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_minPreferredLogicalWidth += toAdd;
198bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth += toAdd;
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
200bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    setPreferredLogicalWidthsDirty(false);
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::size() const
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int specifiedSize = toSelectElement(static_cast<Element*>(node()))->size();
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (specifiedSize > 1)
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return max(minSize, specifiedSize);
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return min(max(minSize, numItems()), maxDefaultSize);
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::numVisibleItems() const
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Only count fully visible rows. But don't return 0 even if only part of a row shows.
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return max(1, (contentHeight() + rowSpacing) / itemHeight());
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::numItems() const
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return toSelectElement(static_cast<Element*>(node()))->listItems().size();
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::listHeight() const
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return itemHeight() * numItems() - rowSpacing;
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
227bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderListBox::computeLogicalHeight()
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22921939df44de1705786c545cd1bf519d47250322dBen Murdoch    int toAdd = borderAndPaddingHeight();
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int itemHeight = RenderListBox::itemHeight();
232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setHeight(itemHeight * size() - rowSpacing + toAdd);
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
234bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    RenderBlock::computeLogicalHeight();
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_vBar) {
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool enabled = numVisibleItems() < numItems();
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_vBar->setEnabled(enabled);
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_vBar->setSteps(1, min(1, numVisibleItems() - 1), itemHeight);
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_vBar->setProportion(numVisibleItems(), numItems());
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!enabled)
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_indexOffset = 0;
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerint RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    return RenderBox::baselinePosition(baselineType, firstLine, lineDirection, linePositionMode) - baselineAdjustment;
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIntRect RenderListBox::itemBoundingBoxRect(int tx, int ty, int index)
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return IntRect(tx + borderLeft() + paddingLeft(),
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                   ty + borderTop() + paddingTop() + itemHeight() * (index - m_indexOffset),
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                   contentWidth(), itemHeight());
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::paintObject(PaintInfo& paintInfo, int tx, int ty)
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() != VISIBLE)
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int listItemsSize = numItems();
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo.phase == PaintPhaseForeground) {
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int index = m_indexOffset;
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (index < listItemsSize && index <= m_indexOffset + numVisibleItems()) {
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            paintItemForeground(paintInfo, tx, ty, index);
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            index++;
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Paint the children.
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderBlock::paintObject(paintInfo, tx, ty);
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    switch (paintInfo.phase) {
2772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Depending on whether we have overlay scrollbars they
2782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // get rendered in the foreground or background phases
2792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    case PaintPhaseForeground:
2802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (m_vBar->isOverlayScrollbar())
2812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            paintScrollbar(paintInfo, tx, ty);
2822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        break;
2832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    case PaintPhaseBlockBackground:
2842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!m_vBar->isOverlayScrollbar())
2852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            paintScrollbar(paintInfo, tx, ty);
2862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        break;
2872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    case PaintPhaseChildBlockBackground:
2882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    case PaintPhaseChildBlockBackgrounds: {
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int index = m_indexOffset;
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (index < listItemsSize && index <= m_indexOffset + numVisibleItems()) {
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            paintItemBackground(paintInfo, tx, ty, index);
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            index++;
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        break;
2952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
2962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    default:
2972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        break;
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid RenderListBox::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
30281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
30381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!isSpatialNavigationEnabled(frame()))
30481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return RenderBlock::addFocusRingRects(rects, tx, ty);
30581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
30681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    SelectElement* select = toSelectElement(static_cast<Element*>(node()));
30781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
30881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Focus the last selected item.
30981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int selectedItem = select->activeSelectionEndListIndex();
31081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (selectedItem >= 0) {
31181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        rects.append(itemBoundingBoxRect(tx, ty, selectedItem));
31281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
31381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
31481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
31581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // No selected items, find the first non-disabled item.
31681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int size = numItems();
31781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const Vector<Element*>& listItems = select->listItems();
31881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (int i = 0; i < size; ++i) {
31981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        OptionElement* optionElement = toOptionElement(listItems[i]);
32081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (optionElement && !optionElement->disabled()) {
32181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            rects.append(itemBoundingBoxRect(tx, ty, i));
32281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
32381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
32481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
32581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
32681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::paintScrollbar(PaintInfo& paintInfo, int tx, int ty)
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_vBar) {
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect scrollRect(tx + width() - borderRight() - m_vBar->width(),
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                           ty + borderTop(),
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                           m_vBar->width(),
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                           height() - (borderTop() + borderBottom()));
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_vBar->setFrameRect(scrollRect);
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_vBar->paint(paintInfo.context, paintInfo.rect);
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3392bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic IntSize itemOffsetForAlignment(TextRun textRun, RenderStyle* itemStyle, Font itemFont, IntRect itemBoudingBox)
3402bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3412bde8e466a4451c7319e3a072d118917957d6554Steve Block    ETextAlign actualAlignment = itemStyle->textAlign();
3422bde8e466a4451c7319e3a072d118917957d6554Steve Block    // FIXME: Firefox doesn't respect JUSTIFY. Should we?
3432bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (actualAlignment == TAAUTO || actualAlignment == JUSTIFY)
3442bde8e466a4451c7319e3a072d118917957d6554Steve Block      actualAlignment = itemStyle->isLeftToRightDirection() ? LEFT : RIGHT;
3452bde8e466a4451c7319e3a072d118917957d6554Steve Block
3462bde8e466a4451c7319e3a072d118917957d6554Steve Block    IntSize offset = IntSize(0, itemFont.fontMetrics().ascent());
3472bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (actualAlignment == RIGHT || actualAlignment == WEBKIT_RIGHT) {
3482bde8e466a4451c7319e3a072d118917957d6554Steve Block        float textWidth = itemFont.width(textRun);
3492bde8e466a4451c7319e3a072d118917957d6554Steve Block        offset.setWidth(itemBoudingBox.width() - textWidth - optionsSpacingHorizontal);
3502bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else if (actualAlignment == CENTER || actualAlignment == WEBKIT_CENTER) {
3512bde8e466a4451c7319e3a072d118917957d6554Steve Block        float textWidth = itemFont.width(textRun);
3522bde8e466a4451c7319e3a072d118917957d6554Steve Block        offset.setWidth((itemBoudingBox.width() - textWidth) / 2);
3532bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else
3542bde8e466a4451c7319e3a072d118917957d6554Steve Block        offset.setWidth(optionsSpacingHorizontal);
3552bde8e466a4451c7319e3a072d118917957d6554Steve Block    return offset;
3562bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3572bde8e466a4451c7319e3a072d118917957d6554Steve Block
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, int listIndex)
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement* select = toSelectElement(static_cast<Element*>(node()));
3615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    const Vector<Element*>& listItems = select->listItems();
3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Element* element = listItems[listIndex];
363635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    OptionElement* optionElement = toOptionElement(element);
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3652bde8e466a4451c7319e3a072d118917957d6554Steve Block    RenderStyle* itemStyle = element->renderStyle();
3662bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!itemStyle)
3672bde8e466a4451c7319e3a072d118917957d6554Steve Block        itemStyle = style();
3682bde8e466a4451c7319e3a072d118917957d6554Steve Block
3692bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (itemStyle->visibility() == HIDDEN)
3702bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
3712bde8e466a4451c7319e3a072d118917957d6554Steve Block
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String itemText;
373635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (optionElement)
374635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        itemText = optionElement->textIndentedToRespectGroupLabel();
375635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    else if (OptionGroupElement* optionGroupElement = toOptionGroupElement(element))
3762bde8e466a4451c7319e3a072d118917957d6554Steve Block        itemText = optionGroupElement->groupLabelText();
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
378e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    Color textColor = element->renderStyle() ? element->renderStyle()->visitedDependentColor(CSSPropertyColor) : style()->visitedDependentColor(CSSPropertyColor);
379635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (optionElement && optionElement->selected()) {
380545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (frame()->selection()->isFocusedAndActive() && document()->focusedNode() == node())
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            textColor = theme()->activeListBoxSelectionForegroundColor();
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Honor the foreground color for disabled items
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (!element->disabled())
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            textColor = theme()->inactiveListBoxSelectionForegroundColor();
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
387643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ColorSpace colorSpace = itemStyle->colorSpace();
388643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    paintInfo.context->setFillColor(textColor, colorSpace);
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3902bde8e466a4451c7319e3a072d118917957d6554Steve Block    unsigned length = itemText.length();
3912bde8e466a4451c7319e3a072d118917957d6554Steve Block    const UChar* string = itemText.characters();
3922bde8e466a4451c7319e3a072d118917957d6554Steve Block    TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !itemStyle->isLeftToRightDirection(), itemStyle->unicodeBidi() == Override);
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Font itemFont = style()->font();
3942bde8e466a4451c7319e3a072d118917957d6554Steve Block    IntRect r = itemBoundingBoxRect(tx, ty, listIndex);
3952bde8e466a4451c7319e3a072d118917957d6554Steve Block    r.move(itemOffsetForAlignment(textRun, itemStyle, itemFont, r));
3962bde8e466a4451c7319e3a072d118917957d6554Steve Block
3975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (isOptionGroupElement(element)) {
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        FontDescription d = itemFont.fontDescription();
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        d.setWeight(d.bolderWeight());
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing());
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        itemFont.update(document()->styleSelector()->fontSelector());
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
403635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Draw the item text
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (itemStyle->visibility() != HIDDEN)
406635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        paintInfo.context->drawBidiText(itemFont, textRun, r.location());
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::paintItemBackground(PaintInfo& paintInfo, int tx, int ty, int listIndex)
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement* select = toSelectElement(static_cast<Element*>(node()));
4125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    const Vector<Element*>& listItems = select->listItems();
4135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Element* element = listItems[listIndex];
414635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    OptionElement* optionElement = toOptionElement(element);
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Color backColor;
417635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (optionElement && optionElement->selected()) {
418545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (frame()->selection()->isFocusedAndActive() && document()->focusedNode() == node())
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            backColor = theme()->activeListBoxSelectionBackgroundColor();
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            backColor = theme()->inactiveListBoxSelectionBackgroundColor();
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
423e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        backColor = element->renderStyle() ? element->renderStyle()->visitedDependentColor(CSSPropertyBackgroundColor) : style()->visitedDependentColor(CSSPropertyBackgroundColor);
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Draw the background for this list box item
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!element->renderStyle() || element->renderStyle()->visibility() != HIDDEN) {
427643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ColorSpace colorSpace = element->renderStyle() ? element->renderStyle()->colorSpace() : style()->colorSpace();
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect itemRect = itemBoundingBoxRect(tx, ty, listIndex);
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        itemRect.intersect(controlClipRect(tx, ty));
430643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo.context->fillRect(itemRect, backColor, colorSpace);
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderListBox::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty)
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_vBar)
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect vertRect(_tx + width() - borderRight() - m_vBar->width(),
4400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                     _ty + borderTop(),
441635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                     m_vBar->width(),
442635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                     height() - borderTop() - borderBottom());
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (vertRect.contains(_x, _y)) {
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result.setScrollbar(m_vBar.get());
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::listIndexAtOffset(int offsetX, int offsetY)
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!numItems())
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (offsetY < borderTop() + paddingTop() || offsetY > height() - paddingBottom() - borderBottom())
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int scrollbarWidth = m_vBar ? m_vBar->width() : 0;
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (offsetX < borderLeft() + paddingLeft() || offsetX > width() - borderRight() - paddingRight() - scrollbarWidth)
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int newOffset = (offsetY - borderTop() - paddingTop()) / itemHeight() + m_indexOffset;
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return newOffset < numItems() ? newOffset : -1;
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::panScroll(const IntPoint& panStartMousePosition)
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int maxSpeed = 20;
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int iconRadius = 7;
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int speedReducer = 4;
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
473635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: This doesn't work correctly with transforms.
474635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    FloatPoint absOffset = localToAbsolute();
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
476545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    IntPoint currentMousePosition = frame()->eventHandler()->currentMousePosition();
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need to check if the current mouse position is out of the window. When the mouse is out of the window, the position is incoherent
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static IntPoint previousMousePosition;
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (currentMousePosition.y() < 0)
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        currentMousePosition = previousMousePosition;
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        previousMousePosition = currentMousePosition;
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int yDelta = currentMousePosition.y() - panStartMousePosition.y();
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // If the point is too far from the center we limit the speed
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    yDelta = max(min(yDelta, maxSpeed), -maxSpeed);
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (abs(yDelta) < iconRadius) // at the center we let the space for the icon
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (yDelta > 0)
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        //offsetY = view()->viewHeight();
494635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        absOffset.move(0, listHeight());
4950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (yDelta < 0)
4960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        yDelta--;
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Let's attenuate the speed
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    yDelta /= speedReducer;
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    IntPoint scrollPoint(0, 0);
502635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    scrollPoint.setY(absOffset.y() + yDelta);
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int newOffset = scrollToward(scrollPoint);
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (newOffset < 0)
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_inAutoscroll = true;
5085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement* select = toSelectElement(static_cast<Element*>(node()));
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    select->updateListBoxSelection(!select->multiple());
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_inAutoscroll = false;
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::scrollToward(const IntPoint& destination)
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
515635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: This doesn't work correctly with transforms.
516635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    FloatPoint absPos = localToAbsolute();
517635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int offsetX = destination.x() - absPos.x();
518635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int offsetY = destination.y() - absPos.y();
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int rows = numVisibleItems();
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int offset = m_indexOffset;
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (offsetY < borderTop() + paddingTop() && scrollToRevealElementAtListIndex(offset - 1))
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return offset - 1;
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (offsetY > height() - paddingBottom() - borderBottom() && scrollToRevealElementAtListIndex(offset + rows))
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return offset + rows - 1;
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return listIndexAtOffset(offsetX, offsetY);
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::autoscroll()
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
534545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    IntPoint pos = frame()->view()->windowToContents(frame()->eventHandler()->currentMousePosition());
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int endIndex = scrollToward(pos);
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (endIndex >= 0) {
5385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        SelectElement* select = toSelectElement(static_cast<Element*>(node()));
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_inAutoscroll = true;
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!select->multiple())
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            select->setActiveSelectionAnchorIndex(endIndex);
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        select->setActiveSelectionEndIndex(endIndex);
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        select->updateListBoxSelection(!select->multiple());
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_inAutoscroll = false;
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::stopAutoscroll()
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    toSelectElement(static_cast<Element*>(node()))->listBoxOnChange();
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderListBox::scrollToRevealElementAtListIndex(int index)
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (index < 0 || index >= numItems() || listIndexIsVisible(index))
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int newOffset;
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (index < m_indexOffset)
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        newOffset = index;
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        newOffset = index - numVisibleItems() + 1;
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
566ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    ScrollableArea::scrollToYOffsetWithoutAnimation(newOffset);
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderListBox::listIndexIsVisible(int index)
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return index >= m_indexOffset && index < m_indexOffset + numVisibleItems();
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
576231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool RenderListBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier, Node**)
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
578ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    return ScrollableArea::scroll(direction, granularity, multiplier);
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
581f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool RenderListBox::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity, float multiplier, Node**)
582f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
583ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    return ScrollableArea::scroll(logicalToPhysical(direction, style()->isHorizontalWritingMode(), style()->isFlippedBlocksWritingMode()), granularity, multiplier);
584f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
585f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::valueChanged(unsigned listIndex)
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Element* element = static_cast<Element*>(node());
5895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement* select = toSelectElement(element);
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    select->setSelectedIndex(select->listToOptionIndex(listIndex));
5915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    element->dispatchFormControlChangeEvent();
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5945abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickint RenderListBox::scrollSize(ScrollbarOrientation orientation) const
5955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
5965abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return ((orientation == VerticalScrollbar) && m_vBar) ? (m_vBar->totalSize() - m_vBar->visibleSize()) : 0;
5975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
5985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
599ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochint RenderListBox::scrollPosition(Scrollbar*) const
6005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
601ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    return m_indexOffset;
6025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
6035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
604ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid RenderListBox::setScrollOffset(const IntPoint& offset)
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
606ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    scrollTo(offset.y());
607ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
608ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
609ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid RenderListBox::scrollTo(int newOffset)
610ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
611ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    if (newOffset == m_indexOffset)
612ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        return;
613ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
614ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    m_indexOffset = newOffset;
615ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    repaint();
6162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    node()->document()->eventQueue()->enqueueOrDispatchScrollEvent(node(), EventQueue::ScrollEventElementTarget);
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::itemHeight() const
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return style()->fontMetrics().height() + rowSpacing;
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::verticalScrollbarWidth() const
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
62681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_vBar && !m_vBar->isOverlayScrollbar() ? m_vBar->width() : 0;
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: We ignore padding in the vertical direction as far as these values are concerned, since that's
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// how the control currently paints.
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::scrollWidth() const
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // There is no horizontal scrolling allowed.
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return clientWidth();
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::scrollHeight() const
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return max(clientHeight(), listHeight());
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::scrollLeft() const
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::setScrollLeft(int)
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderListBox::scrollTop() const
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_indexOffset * itemHeight();
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::setScrollTop(int newTop)
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Determine an index and scroll to it.
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int index = newTop / itemHeight();
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (index < 0 || index >= numItems() || index == m_indexOffset)
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
662ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
663ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    ScrollableArea::scrollToYOffsetWithoutAnimation(index);
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
6678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
6688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!RenderBlock::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction))
6698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return false;
6705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    const Vector<Element*>& listItems = toSelectElement(static_cast<Element*>(node()))->listItems();
6718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int size = numItems();
6728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    tx += this->x();
6738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ty += this->y();
6748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (int i = 0; i < size; ++i) {
6758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (itemBoundingBoxRect(tx, ty, i).contains(x, y)) {
6765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (Element* node = listItems[i]) {
6778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                result.setInnerNode(node);
6788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (!result.innerNonSharedNode())
6798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    result.setInnerNonSharedNode(node);
6808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                result.setLocalPoint(IntPoint(x - tx, y - ty));
6818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
6828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
6838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
6848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
6858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return true;
6878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
6888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIntRect RenderListBox::controlClipRect(int tx, int ty) const
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
691635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect clipRect = contentBoxRect();
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    clipRect.move(tx, ty);
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return clipRect;
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderListBox::isActive() const
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
698545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    Page* page = frame()->page();
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return page && page->focusController()->isActive();
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect scrollRect = rect;
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    scrollRect.move(width() - borderRight() - scrollbar->width(), borderTop());
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    repaintRectangle(scrollRect);
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochIntRect RenderListBox::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
7100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
7110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RenderView* view = this->view();
7120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!view)
7130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return scrollbarRect;
7140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    IntRect rect = scrollbarRect;
7160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int scrollbarLeft = width() - borderRight() - scrollbar->width();
7180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int scrollbarTop = borderTop();
7190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    rect.move(scrollbarLeft, scrollbarTop);
7200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return view->frameView()->convertFromRenderer(this, rect);
7220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochIntRect RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
7250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
7260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RenderView* view = this->view();
7270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!view)
7280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return parentRect;
7290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    IntRect rect = view->frameView()->convertToRenderer(this, parentRect);
7310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int scrollbarLeft = width() - borderRight() - scrollbar->width();
7330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int scrollbarTop = borderTop();
7340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    rect.move(-scrollbarLeft, -scrollbarTop);
7350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return rect;
7360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochIntPoint RenderListBox::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
7390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
7400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RenderView* view = this->view();
7410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!view)
7420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return scrollbarPoint;
7430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    IntPoint point = scrollbarPoint;
7450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int scrollbarLeft = width() - borderRight() - scrollbar->width();
7470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int scrollbarTop = borderTop();
7480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    point.move(scrollbarLeft, scrollbarTop);
7490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return view->frameView()->convertFromRenderer(this, point);
7510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochIntPoint RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
7540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
7550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RenderView* view = this->view();
7560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!view)
7570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return parentPoint;
7580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    IntPoint point = view->frameView()->convertToRenderer(this, parentPoint);
7600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int scrollbarLeft = width() - borderRight() - scrollbar->width();
7620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int scrollbarTop = borderTop();
7630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    point.move(-scrollbarLeft, -scrollbarTop);
7640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return point;
7650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7672fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntSize RenderListBox::contentsSize() const
7682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
7692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IntSize(scrollWidth(), scrollHeight());
7702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
7712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7722fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderListBox::visibleHeight() const
7732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
7742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return height();
7752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
7762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7772fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint RenderListBox::visibleWidth() const
7782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
7792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return width();
7802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
7812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7822fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderListBox::currentMousePosition() const
7832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
7842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RenderView* view = this->view();
7852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!view)
7862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return IntPoint();
7872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return view->frameView()->currentMousePosition();
7882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
7892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7902bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool RenderListBox::shouldSuspendScrollAnimations() const
7912bde8e466a4451c7319e3a072d118917957d6554Steve Block{
7922bde8e466a4451c7319e3a072d118917957d6554Steve Block    RenderView* view = this->view();
7932bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!view)
7942bde8e466a4451c7319e3a072d118917957d6554Steve Block        return true;
7952bde8e466a4451c7319e3a072d118917957d6554Steve Block    return view->frameView()->shouldSuspendScrollAnimations();
7962bde8e466a4451c7319e3a072d118917957d6554Steve Block}
7972bde8e466a4451c7319e3a072d118917957d6554Steve Block
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Scrollbar> RenderListBox::createScrollbar()
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Scrollbar> widget;
8018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasCustomScrollbarStyle)
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        widget = RenderScrollbar::createCustomScrollbar(this, VerticalScrollbar, this);
80481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else {
8058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        widget = Scrollbar::createNativeScrollbar(this, VerticalScrollbar, theme()->scrollbarControlSizeForPart(ListboxPart));
80681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        didAddVerticalScrollbar(widget.get());
80781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    document()->view()->addChild(widget.get());
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return widget.release();
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::destroyScrollbar()
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_vBar)
8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
81681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
81781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_vBar->isCustomScrollbar())
81881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ScrollableArea::willRemoveVerticalScrollbar(m_vBar.get());
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_vBar->removeFromParent();
820ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    m_vBar->disconnectFromScrollableArea();
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_vBar = 0;
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderListBox::setHasVerticalScrollbar(bool hasScrollbar)
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasScrollbar == (m_vBar != 0))
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
82981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (hasScrollbar)
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_vBar = createScrollbar();
83181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        destroyScrollbar();
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_vBar)
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_vBar->styleChanged();
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(DASHBOARD_SUPPORT)
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Force an update since we know the scrollbars have changed things.
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (document()->hasDashboardRegions())
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        document()->setDashboardRegionsDirty(true);
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
845