18f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/* 2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderSlider.h" 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSPropertyNames.h" 2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "CSSStyleSelector.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Event.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventHandler.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLInputElement.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 3368513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "HTMLParserIdioms.h" 34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "MediaControlElements.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MouseEvent.h" 362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "Node.h" 378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderLayer.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTheme.h" 398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderView.h" 40545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "ShadowElement.h" 41f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "SliderThumbElement.h" 42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "StepRange.h" 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h> 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing std::min; 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic const int defaultTrackLength = 129; 508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// Returns a value between 0 and 1. 528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic double sliderPosition(HTMLInputElement* element) 538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StepRange range(element); 558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return range.proportionFromValue(range.valueFromElement(element)); 568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderSlider::RenderSlider(HTMLInputElement* element) 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : RenderBlock(element) 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderSlider::~RenderSlider() 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerint RenderSlider::baselinePosition(FontBaseline, bool /*firstLine*/, LineDirectionMode, LinePositionMode) const 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // FIXME: Patch this function for writing-mode. 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return height() + marginTop(); 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 73bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderSlider::computePreferredLogicalWidths() 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 75bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = 0; 76bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = 0; 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->width().isFixed() && style()->width().value() > 0) 79bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->width().value()); 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 81bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = defaultTrackLength * style()->effectiveZoom(); 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) { 84bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value())); 85bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value())); 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent())) 87bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = 0; 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 89bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth; 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) { 92bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value())); 93bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value())); 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9621939df44de1705786c545cd1bf519d47250322dBen Murdoch int toAdd = borderAndPaddingWidth(); 97bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_minPreferredLogicalWidth += toAdd; 98bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_maxPreferredLogicalWidth += toAdd; 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 100bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen setPreferredLogicalWidthsDirty(false); 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochIntRect RenderSlider::thumbRect() 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch SliderThumbElement* thumbElement = shadowSliderThumb(); 10665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!thumbElement) 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return IntRect(); 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IntRect thumbRect; 11065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch RenderBox* thumb = toRenderBox(thumbElement->renderer()); 1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch thumbRect.setWidth(thumb->style()->width().calcMinValue(contentWidth())); 1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch thumbRect.setHeight(thumb->style()->height().calcMinValue(contentHeight())); 1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch double fraction = sliderPosition(static_cast<HTMLInputElement*>(node())); 1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IntRect contentRect = contentBoxRect(); 117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart) { 1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch thumbRect.setX(contentRect.x() + (contentRect.width() - thumbRect.width()) / 2); 1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch thumbRect.setY(contentRect.y() + static_cast<int>(nextafter((contentRect.height() - thumbRect.height()) + 1, 0) * (1 - fraction))); 1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } else { 1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch thumbRect.setX(contentRect.x() + static_cast<int>(nextafter((contentRect.width() - thumbRect.width()) + 1, 0) * fraction)); 1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch thumbRect.setY(contentRect.y() + (contentRect.height() - thumbRect.height()) / 2); 1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return thumbRect; 1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderSlider::layout() 1298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(needsLayout()); 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch SliderThumbElement* thumbElement = shadowSliderThumb(); 13365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch RenderBox* thumb = thumbElement ? toRenderBox(thumbElement->renderer()) : 0; 1348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 13521939df44de1705786c545cd1bf519d47250322dBen Murdoch IntSize baseSize(borderAndPaddingWidth(), borderAndPaddingHeight()); 1368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (thumb) { 1388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Allow the theme to set the size of the thumb. 1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (thumb->style()->hasAppearance()) { 1408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // FIXME: This should pass the style, not the renderer, to the theme. 1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian theme()->adjustSliderThumbSize(thumb); 1428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian baseSize.expand(thumb->style()->width().calcMinValue(0), thumb->style()->height().calcMinValue(0)); 1458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); 1488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian IntSize oldSize = size(); 1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setSize(baseSize); 152bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen computeLogicalWidth(); 153bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen computeLogicalHeight(); 154f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch updateLayerTransform(); 1558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (thumb) { 1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (oldSize != size()) 1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian thumb->setChildNeedsLayout(true, false); 1598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1602bde8e466a4451c7319e3a072d118917957d6554Steve Block LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode()); 1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian IntRect oldThumbRect = thumb->frameRect(); 1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian thumb->layoutIfNeeded(); 1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IntRect rect = thumbRect(); 1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch thumb->setFrameRect(rect); 1688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (thumb->checkForRepaintDuringLayout()) 1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian thumb->repaintDuringLayoutIfMoved(oldThumbRect); 1708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian statePusher.pop(); 172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block addOverflowFromChild(thumb); 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian repainter.repaintAfterLayout(); 1768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setNeedsLayout(false); 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochSliderThumbElement* RenderSlider::shadowSliderThumb() const 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Node* shadow = static_cast<Element*>(node())->shadowRoot(); 1832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return shadow ? toSliderThumbElement(shadow->firstChild()) : 0; 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderSlider::inDragMode() const 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch SliderThumbElement* thumbElement = shadowSliderThumb(); 18965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return thumbElement && thumbElement->inDragMode(); 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 193