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 |