| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2010 Google Inc. All rights reserved. | 3 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 */ | 30 */ |
| 31 | 31 |
| 32 | |
| 33 #include "config.h" | 32 #include "config.h" |
| 34 #include "core/html/shadow/SliderThumbElement.h" | 33 #include "core/html/shadow/SliderThumbElement.h" |
| 35 | 34 |
| 36 #include "core/events/Event.h" | 35 #include "core/events/Event.h" |
| 37 #include "core/events/MouseEvent.h" | 36 #include "core/events/MouseEvent.h" |
| 38 #include "core/dom/shadow/ShadowRoot.h" | 37 #include "core/dom/shadow/ShadowRoot.h" |
| 39 #include "core/frame/LocalFrame.h" | 38 #include "core/frame/LocalFrame.h" |
| 40 #include "core/html/HTMLInputElement.h" | 39 #include "core/html/HTMLInputElement.h" |
| 41 #include "core/html/forms/StepRange.h" | 40 #include "core/html/forms/StepRange.h" |
| 42 #include "core/html/parser/HTMLParserIdioms.h" | 41 #include "core/html/parser/HTMLParserIdioms.h" |
| 43 #include "core/html/shadow/ShadowElementNames.h" | 42 #include "core/html/shadow/ShadowElementNames.h" |
| 44 #include "core/page/EventHandler.h" | 43 #include "core/page/EventHandler.h" |
| 45 #include "core/rendering/RenderFlexibleBox.h" | 44 #include "core/rendering/RenderFlexibleBox.h" |
| 46 #include "core/rendering/RenderSlider.h" | 45 #include "core/rendering/RenderSlider.h" |
| 46 #include "core/rendering/RenderSliderContainer.h" |
| 47 #include "core/rendering/RenderSliderThumb.h" |
| 47 #include "core/rendering/RenderTheme.h" | 48 #include "core/rendering/RenderTheme.h" |
| 48 | 49 |
| 49 namespace WebCore { | 50 namespace WebCore { |
| 50 | 51 |
| 51 using namespace HTMLNames; | 52 using namespace HTMLNames; |
| 52 | 53 |
| 53 inline static Decimal sliderPosition(HTMLInputElement* element) | |
| 54 { | |
| 55 const StepRange stepRange(element->createStepRange(RejectAny)); | |
| 56 const Decimal oldValue = parseToDecimalForNumberType(element->value(), stepR
ange.defaultValue()); | |
| 57 return stepRange.proportionFromValue(stepRange.clampValue(oldValue)); | |
| 58 } | |
| 59 | |
| 60 inline static bool hasVerticalAppearance(HTMLInputElement* input) | 54 inline static bool hasVerticalAppearance(HTMLInputElement* input) |
| 61 { | 55 { |
| 62 ASSERT(input->renderer()); | 56 ASSERT(input->renderer()); |
| 63 RenderStyle* sliderStyle = input->renderer()->style(); | 57 RenderStyle* sliderStyle = input->renderer()->style(); |
| 64 | 58 |
| 65 return sliderStyle->appearance() == SliderVerticalPart; | 59 return sliderStyle->appearance() == SliderVerticalPart; |
| 66 } | 60 } |
| 67 | 61 |
| 68 // -------------------------------- | |
| 69 | |
| 70 RenderSliderThumb::RenderSliderThumb(SliderThumbElement* element) | |
| 71 : RenderBlockFlow(element) | |
| 72 { | |
| 73 } | |
| 74 | |
| 75 void RenderSliderThumb::updateAppearance(RenderStyle* parentStyle) | |
| 76 { | |
| 77 if (parentStyle->appearance() == SliderVerticalPart) | |
| 78 style()->setAppearance(SliderThumbVerticalPart); | |
| 79 else if (parentStyle->appearance() == SliderHorizontalPart) | |
| 80 style()->setAppearance(SliderThumbHorizontalPart); | |
| 81 else if (parentStyle->appearance() == MediaSliderPart) | |
| 82 style()->setAppearance(MediaSliderThumbPart); | |
| 83 else if (parentStyle->appearance() == MediaVolumeSliderPart) | |
| 84 style()->setAppearance(MediaVolumeSliderThumbPart); | |
| 85 else if (parentStyle->appearance() == MediaFullScreenVolumeSliderPart) | |
| 86 style()->setAppearance(MediaFullScreenVolumeSliderThumbPart); | |
| 87 if (style()->hasAppearance()) | |
| 88 RenderTheme::theme().adjustSliderThumbSize(style(), toElement(node())); | |
| 89 } | |
| 90 | |
| 91 bool RenderSliderThumb::isSliderThumb() const | |
| 92 { | |
| 93 return true; | |
| 94 } | |
| 95 | |
| 96 // -------------------------------- | |
| 97 | |
| 98 // FIXME: Find a way to cascade appearance and adjust heights, and get rid of th
is class. | |
| 99 // http://webkit.org/b/62535 | |
| 100 class RenderSliderContainer : public RenderFlexibleBox { | |
| 101 public: | |
| 102 RenderSliderContainer(SliderContainerElement* element) | |
| 103 : RenderFlexibleBox(element) { } | |
| 104 public: | |
| 105 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logic
alTop, LogicalExtentComputedValues&) const OVERRIDE; | |
| 106 | |
| 107 private: | |
| 108 virtual void layout() OVERRIDE; | |
| 109 }; | |
| 110 | |
| 111 void RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, Layou
tUnit logicalTop, LogicalExtentComputedValues& computedValues) const | |
| 112 { | |
| 113 HTMLInputElement* input = toHTMLInputElement(node()->shadowHost()); | |
| 114 bool isVertical = hasVerticalAppearance(input); | |
| 115 | |
| 116 if (input->renderer()->isSlider() && !isVertical && input->list()) { | |
| 117 int offsetFromCenter = RenderTheme::theme().sliderTickOffsetFromTrackCen
ter(); | |
| 118 LayoutUnit trackHeight = 0; | |
| 119 if (offsetFromCenter < 0) | |
| 120 trackHeight = -2 * offsetFromCenter; | |
| 121 else { | |
| 122 int tickLength = RenderTheme::theme().sliderTickSize().height(); | |
| 123 trackHeight = 2 * (offsetFromCenter + tickLength); | |
| 124 } | |
| 125 float zoomFactor = style()->effectiveZoom(); | |
| 126 if (zoomFactor != 1.0) | |
| 127 trackHeight *= zoomFactor; | |
| 128 | |
| 129 // FIXME: The trackHeight should have been added before updateLogicalHei
ght was called to avoid this hack. | |
| 130 updateIntrinsicContentLogicalHeight(trackHeight); | |
| 131 | |
| 132 RenderBox::computeLogicalHeight(trackHeight, logicalTop, computedValues)
; | |
| 133 return; | |
| 134 } | |
| 135 if (isVertical) | |
| 136 logicalHeight = RenderSlider::defaultTrackLength; | |
| 137 | |
| 138 // FIXME: The trackHeight should have been added before updateLogicalHeight
was called to avoid this hack. | |
| 139 updateIntrinsicContentLogicalHeight(logicalHeight); | |
| 140 | |
| 141 RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues); | |
| 142 } | |
| 143 | |
| 144 void RenderSliderContainer::layout() | |
| 145 { | |
| 146 HTMLInputElement* input = toHTMLInputElement(node()->shadowHost()); | |
| 147 bool isVertical = hasVerticalAppearance(input); | |
| 148 style()->setFlexDirection(isVertical ? FlowColumn : FlowRow); | |
| 149 TextDirection oldTextDirection = style()->direction(); | |
| 150 if (isVertical) { | |
| 151 // FIXME: Work around rounding issues in RTL vertical sliders. We want t
hem to | |
| 152 // render identically to LTR vertical sliders. We can remove this work a
round when | |
| 153 // subpixel rendering is enabled on all ports. | |
| 154 style()->setDirection(LTR); | |
| 155 } | |
| 156 | |
| 157 Element* thumbElement = input->userAgentShadowRoot()->getElementById(ShadowE
lementNames::sliderThumb()); | |
| 158 Element* trackElement = input->userAgentShadowRoot()->getElementById(ShadowE
lementNames::sliderTrack()); | |
| 159 RenderBox* thumb = thumbElement ? thumbElement->renderBox() : 0; | |
| 160 RenderBox* track = trackElement ? trackElement->renderBox() : 0; | |
| 161 | |
| 162 SubtreeLayoutScope layoutScope(*this); | |
| 163 // Force a layout to reset the position of the thumb so the code below doesn
't move the thumb to the wrong place. | |
| 164 // FIXME: Make a custom Render class for the track and move the thumb positi
oning code there. | |
| 165 if (track) | |
| 166 layoutScope.setChildNeedsLayout(track); | |
| 167 | |
| 168 RenderFlexibleBox::layout(); | |
| 169 | |
| 170 style()->setDirection(oldTextDirection); | |
| 171 // These should always exist, unless someone mutates the shadow DOM (e.g., i
n the inspector). | |
| 172 if (!thumb || !track) | |
| 173 return; | |
| 174 | |
| 175 double percentageOffset = sliderPosition(input).toDouble(); | |
| 176 LayoutUnit availableExtent = isVertical ? track->contentHeight() : track->co
ntentWidth(); | |
| 177 availableExtent -= isVertical ? thumb->height() : thumb->width(); | |
| 178 LayoutUnit offset = percentageOffset * availableExtent; | |
| 179 LayoutPoint thumbLocation = thumb->location(); | |
| 180 if (isVertical) | |
| 181 thumbLocation.setY(thumbLocation.y() + track->contentHeight() - thumb->h
eight() - offset); | |
| 182 else if (style()->isLeftToRightDirection()) | |
| 183 thumbLocation.setX(thumbLocation.x() + offset); | |
| 184 else | |
| 185 thumbLocation.setX(thumbLocation.x() - offset); | |
| 186 thumb->setLocation(thumbLocation); | |
| 187 } | |
| 188 | |
| 189 // -------------------------------- | |
| 190 | |
| 191 inline SliderThumbElement::SliderThumbElement(Document& document) | 62 inline SliderThumbElement::SliderThumbElement(Document& document) |
| 192 : HTMLDivElement(document) | 63 : HTMLDivElement(document) |
| 193 , m_inDragMode(false) | 64 , m_inDragMode(false) |
| 194 { | 65 { |
| 195 } | 66 } |
| 196 | 67 |
| 197 PassRefPtrWillBeRawPtr<SliderThumbElement> SliderThumbElement::create(Document&
document) | 68 PassRefPtrWillBeRawPtr<SliderThumbElement> SliderThumbElement::create(Document&
document) |
| 198 { | 69 { |
| 199 RefPtrWillBeRawPtr<SliderThumbElement> element = adoptRefWillBeNoop(new Slid
erThumbElement(document)); | 70 RefPtrWillBeRawPtr<SliderThumbElement> element = adoptRefWillBeNoop(new Slid
erThumbElement(document)); |
| 200 element->setAttribute(idAttr, ShadowElementNames::sliderThumb()); | 71 element->setAttribute(idAttr, ShadowElementNames::sliderThumb()); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 case MediaVolumeSliderThumbPart: | 327 case MediaVolumeSliderThumbPart: |
| 457 case MediaFullScreenVolumeSliderPart: | 328 case MediaFullScreenVolumeSliderPart: |
| 458 case MediaFullScreenVolumeSliderThumbPart: | 329 case MediaFullScreenVolumeSliderThumbPart: |
| 459 return mediaSliderContainer; | 330 return mediaSliderContainer; |
| 460 default: | 331 default: |
| 461 return sliderContainer; | 332 return sliderContainer; |
| 462 } | 333 } |
| 463 } | 334 } |
| 464 | 335 |
| 465 } | 336 } |
| OLD | NEW |