OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "HTMLNames.h" | 28 #include "HTMLNames.h" |
29 #include "RenderTheme.h" | 29 #include "RenderTheme.h" |
30 #include "ShadowElement.h" | 30 #include "ShadowElement.h" |
31 | 31 |
32 using namespace std; | 32 using namespace std; |
33 | 33 |
34 namespace WebCore { | 34 namespace WebCore { |
35 | 35 |
36 using namespace HTMLNames; | 36 using namespace HTMLNames; |
37 | 37 |
| 38 class MeterPartElement : public ShadowBlockElement { |
| 39 public: |
| 40 static PassRefPtr<MeterPartElement> createForPart(HTMLElement*, PseudoId); |
| 41 |
| 42 void hide(); |
| 43 void restoreVisibility(); |
| 44 |
| 45 virtual void updateStyleForPart(PseudoId); |
| 46 |
| 47 private: |
| 48 MeterPartElement(HTMLElement*); |
| 49 void saveVisibility(); |
| 50 |
| 51 EVisibility m_originalVisibility; |
| 52 }; |
| 53 |
| 54 MeterPartElement::MeterPartElement(HTMLElement* shadowParent) |
| 55 : ShadowBlockElement(shadowParent) |
| 56 { |
| 57 } |
| 58 |
| 59 PassRefPtr<MeterPartElement> MeterPartElement::createForPart(HTMLElement* shadow
Parent, PseudoId pseudoId) |
| 60 { |
| 61 RefPtr<MeterPartElement> ret = adoptRef(new MeterPartElement(shadowParent)); |
| 62 ret->initAsPart(pseudoId); |
| 63 ret->saveVisibility(); |
| 64 return ret; |
| 65 } |
| 66 |
| 67 void MeterPartElement::hide() |
| 68 { |
| 69 if (renderer()) |
| 70 renderer()->style()->setVisibility(HIDDEN); |
| 71 } |
| 72 |
| 73 void MeterPartElement::restoreVisibility() |
| 74 { |
| 75 if (renderer()) |
| 76 renderer()->style()->setVisibility(m_originalVisibility); |
| 77 } |
| 78 |
| 79 void MeterPartElement::updateStyleForPart(PseudoId pseudoId) |
| 80 { |
| 81 if (renderer()->style()->styleType() == pseudoId) |
| 82 return; |
| 83 |
| 84 ShadowBlockElement::updateStyleForPart(pseudoId); |
| 85 saveVisibility(); |
| 86 } |
| 87 |
| 88 void MeterPartElement::saveVisibility() |
| 89 { |
| 90 m_originalVisibility = renderer()->style()->visibility(); |
| 91 } |
| 92 |
38 RenderMeter::RenderMeter(HTMLMeterElement* element) | 93 RenderMeter::RenderMeter(HTMLMeterElement* element) |
39 : RenderIndicator(element) | 94 : RenderIndicator(element) |
40 { | 95 { |
41 } | 96 } |
42 | 97 |
43 RenderMeter::~RenderMeter() | 98 RenderMeter::~RenderMeter() |
44 { | 99 { |
45 if (m_valuePart) | 100 if (shadowAttached()) { |
46 m_valuePart->detach(); | 101 m_verticalValuePart->detach(); |
47 if (m_barPart) | 102 m_verticalBarPart->detach(); |
48 m_barPart->detach(); | 103 m_horizontalValuePart->detach(); |
| 104 m_horizontalBarPart->detach(); |
| 105 } |
| 106 } |
| 107 |
| 108 PassRefPtr<MeterPartElement> RenderMeter::createPart(PseudoId pseudoId) |
| 109 { |
| 110 RefPtr<MeterPartElement> element = MeterPartElement::createForPart(static_ca
st<HTMLElement*>(node()), pseudoId); |
| 111 if (element->renderer()) |
| 112 addChild(element->renderer()); |
| 113 return element; |
| 114 } |
| 115 |
| 116 void RenderMeter::updateFromElement() |
| 117 { |
| 118 if (!shadowAttached()) { |
| 119 m_horizontalBarPart = createPart(barPseudoId(HORIZONTAL)); |
| 120 m_horizontalValuePart = createPart(valuePseudoId(HORIZONTAL)); |
| 121 m_verticalBarPart = createPart(barPseudoId(VERTICAL)); |
| 122 m_verticalValuePart = createPart(valuePseudoId(VERTICAL)); |
| 123 } |
| 124 |
| 125 m_horizontalBarPart->updateStyleForPart(barPseudoId(HORIZONTAL)); |
| 126 m_horizontalValuePart->updateStyleForPart(valuePseudoId(HORIZONTAL)); |
| 127 m_verticalBarPart->updateStyleForPart(barPseudoId(VERTICAL)); |
| 128 m_verticalValuePart->updateStyleForPart(valuePseudoId(VERTICAL)); |
| 129 RenderIndicator::updateFromElement(); |
49 } | 130 } |
50 | 131 |
51 void RenderMeter::computeLogicalWidth() | 132 void RenderMeter::computeLogicalWidth() |
52 { | 133 { |
53 RenderBox::computeLogicalWidth(); | 134 RenderBox::computeLogicalWidth(); |
54 setWidth(theme()->meterSizeForBounds(this, frameRect()).width()); | 135 setWidth(theme()->meterSizeForBounds(this, frameRect()).width()); |
55 } | 136 } |
56 | 137 |
57 void RenderMeter::computeLogicalHeight() | 138 void RenderMeter::computeLogicalHeight() |
58 { | 139 { |
59 RenderBox::computeLogicalHeight(); | 140 RenderBox::computeLogicalHeight(); |
60 setHeight(theme()->meterSizeForBounds(this, frameRect()).height()); | 141 setHeight(theme()->meterSizeForBounds(this, frameRect()).height()); |
61 } | 142 } |
62 | 143 |
63 void RenderMeter::layoutParts() | 144 void RenderMeter::layoutParts() |
64 { | 145 { |
65 // We refresh shadow node here because the state can depend | 146 m_horizontalBarPart->layoutAsPart(barPartRect()); |
66 // on the frame size of this render object. | 147 m_horizontalValuePart->layoutAsPart(valuePartRect(HORIZONTAL)); |
67 updatePartsState(); | 148 m_verticalBarPart->layoutAsPart(barPartRect()); |
68 if (m_valuePart) | 149 m_verticalValuePart->layoutAsPart(valuePartRect(VERTICAL)); |
69 m_valuePart->layoutAsPart(valuePartRect()); | 150 |
70 if (m_barPart) | 151 if (shouldHaveParts()) { |
71 m_barPart->layoutAsPart(barPartRect()); | 152 if (HORIZONTAL == orientation()) { |
| 153 m_verticalBarPart->hide(); |
| 154 m_verticalValuePart->hide(); |
| 155 m_horizontalBarPart->restoreVisibility(); |
| 156 m_horizontalValuePart->restoreVisibility(); |
| 157 } else { |
| 158 m_verticalBarPart->restoreVisibility(); |
| 159 m_verticalValuePart->restoreVisibility(); |
| 160 m_horizontalBarPart->hide(); |
| 161 m_horizontalValuePart->hide(); |
| 162 } |
| 163 } else { |
| 164 m_verticalBarPart->hide(); |
| 165 m_verticalValuePart->hide(); |
| 166 m_horizontalBarPart->hide(); |
| 167 m_horizontalValuePart->hide(); |
| 168 } |
72 } | 169 } |
73 | 170 |
74 bool RenderMeter::shouldHaveParts() const | 171 bool RenderMeter::shouldHaveParts() const |
75 { | 172 { |
76 bool hasTheme = theme()->supportsMeter(style()->appearance(), isHorizontal()
); | 173 EBoxOrient currentOrientation = orientation(); |
| 174 bool hasTheme = theme()->supportsMeter(style()->appearance(), HORIZONTAL ==
currentOrientation); |
77 if (!hasTheme) | 175 if (!hasTheme) |
78 return true; | 176 return true; |
79 bool shadowsHaveStyle = ShadowBlockElement::partShouldHaveStyle(this, barPse
udoId()) || ShadowBlockElement::partShouldHaveStyle(this, valuePseudoId()); | 177 bool shadowsHaveStyle = ShadowBlockElement::partShouldHaveStyle(this, barPse
udoId(currentOrientation)) || ShadowBlockElement::partShouldHaveStyle(this, valu
ePseudoId(currentOrientation)); |
80 if (shadowsHaveStyle) | 178 if (shadowsHaveStyle) |
81 return true; | 179 return true; |
82 return false; | 180 return false; |
83 } | 181 } |
84 | 182 |
85 double RenderMeter::valueRatio() const | 183 double RenderMeter::valueRatio() const |
86 { | 184 { |
87 HTMLMeterElement* element = static_cast<HTMLMeterElement*>(node()); | 185 HTMLMeterElement* element = static_cast<HTMLMeterElement*>(node()); |
88 double min = element->min(); | 186 double min = element->min(); |
89 double max = element->max(); | 187 double max = element->max(); |
90 double value = element->value(); | 188 double value = element->value(); |
91 | 189 |
92 if (max <= min) | 190 if (max <= min) |
93 return 0; | 191 return 0; |
94 return (value - min) / (max - min); | 192 return (value - min) / (max - min); |
95 } | 193 } |
96 | 194 |
97 IntRect RenderMeter::barPartRect() const | 195 IntRect RenderMeter::barPartRect() const |
98 { | 196 { |
99 return IntRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), lro
und(width() - borderLeft() - paddingLeft() - borderRight() - paddingRight()), he
ight() - borderTop() - paddingTop() - borderBottom() - paddingBottom()); | 197 return IntRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), lro
und(width() - borderLeft() - paddingLeft() - borderRight() - paddingRight()), he
ight() - borderTop() - paddingTop() - borderBottom() - paddingBottom()); |
100 } | 198 } |
101 | 199 |
102 IntRect RenderMeter::valuePartRect() const | 200 IntRect RenderMeter::valuePartRect(EBoxOrient asOrientation) const |
103 { | 201 { |
104 IntRect rect = barPartRect(); | 202 IntRect rect = barPartRect(); |
105 | 203 |
106 if (rect.height() <= rect.width()) { | 204 if (HORIZONTAL == asOrientation) { |
107 int width = static_cast<int>(rect.width()*valueRatio()); | 205 int width = static_cast<int>(rect.width()*valueRatio()); |
108 if (!style()->isLeftToRightDirection()) { | 206 if (!style()->isLeftToRightDirection()) { |
109 rect.setX(rect.x() + (rect.width() - width)); | 207 rect.setX(rect.x() + (rect.width() - width)); |
110 rect.setWidth(width); | 208 rect.setWidth(width); |
111 } else | 209 } else |
112 rect.setWidth(width); | 210 rect.setWidth(width); |
113 } else { | 211 } else { |
114 int height = static_cast<int>(rect.height()*valueRatio()); | 212 int height = static_cast<int>(rect.height()*valueRatio()); |
115 rect.setY(rect.y() + (rect.height() - height)); | 213 rect.setY(rect.y() + (rect.height() - height)); |
116 rect.setHeight(height); | 214 rect.setHeight(height); |
117 } | 215 } |
118 | 216 |
119 return rect; | 217 return rect; |
120 } | 218 } |
121 | 219 |
122 bool RenderMeter::isHorizontal() const | 220 EBoxOrient RenderMeter::orientation() const |
123 { | 221 { |
124 IntRect rect = barPartRect(); | 222 IntRect rect = barPartRect(); |
125 return rect.height() <= rect.width(); | 223 return rect.height() <= rect.width() ? HORIZONTAL : VERTICAL; |
126 } | 224 } |
127 | 225 |
128 PseudoId RenderMeter::valuePseudoId() const | 226 PseudoId RenderMeter::valuePseudoId(EBoxOrient asOrientation) const |
129 { | 227 { |
130 HTMLMeterElement* element = static_cast<HTMLMeterElement*>(node()); | 228 HTMLMeterElement* element = static_cast<HTMLMeterElement*>(node()); |
131 | 229 |
132 if (isHorizontal()) { | 230 if (HORIZONTAL == asOrientation) { |
133 switch (element->gaugeRegion()) { | 231 switch (element->gaugeRegion()) { |
134 case HTMLMeterElement::GaugeRegionOptimum: | 232 case HTMLMeterElement::GaugeRegionOptimum: |
135 return METER_HORIZONTAL_OPTIMUM; | 233 return METER_HORIZONTAL_OPTIMUM; |
136 case HTMLMeterElement::GaugeRegionSuboptimal: | 234 case HTMLMeterElement::GaugeRegionSuboptimal: |
137 return METER_HORIZONTAL_SUBOPTIMAL; | 235 return METER_HORIZONTAL_SUBOPTIMAL; |
138 case HTMLMeterElement::GaugeRegionEvenLessGood: | 236 case HTMLMeterElement::GaugeRegionEvenLessGood: |
139 return METER_HORIZONTAL_EVEN_LESS_GOOD; | 237 return METER_HORIZONTAL_EVEN_LESS_GOOD; |
140 } | 238 } |
141 } else { | 239 } else { |
142 switch (element->gaugeRegion()) { | 240 switch (element->gaugeRegion()) { |
143 case HTMLMeterElement::GaugeRegionOptimum: | 241 case HTMLMeterElement::GaugeRegionOptimum: |
144 return METER_VERTICAL_OPTIMUM; | 242 return METER_VERTICAL_OPTIMUM; |
145 case HTMLMeterElement::GaugeRegionSuboptimal: | 243 case HTMLMeterElement::GaugeRegionSuboptimal: |
146 return METER_VERTICAL_SUBOPTIMAL; | 244 return METER_VERTICAL_SUBOPTIMAL; |
147 case HTMLMeterElement::GaugeRegionEvenLessGood: | 245 case HTMLMeterElement::GaugeRegionEvenLessGood: |
148 return METER_VERTICAL_EVEN_LESS_GOOD; | 246 return METER_VERTICAL_EVEN_LESS_GOOD; |
149 } | 247 } |
150 } | 248 } |
151 | 249 |
152 ASSERT_NOT_REACHED(); | 250 ASSERT_NOT_REACHED(); |
153 return NOPSEUDO; | 251 return NOPSEUDO; |
154 } | 252 } |
155 | 253 |
156 PseudoId RenderMeter::barPseudoId() const | 254 PseudoId RenderMeter::barPseudoId(EBoxOrient asOrientation) const |
157 { | 255 { |
158 return isHorizontal() ? METER_HORIZONTAL_BAR : METER_VERTICAL_BAR; | 256 return HORIZONTAL == asOrientation ? METER_HORIZONTAL_BAR : METER_VERTICAL_B
AR; |
159 } | |
160 | |
161 void RenderMeter::updatePartsState() | |
162 { | |
163 if (shouldHaveParts() && !m_barPart) { | |
164 ASSERT(!m_valuePart); | |
165 m_barPart = ShadowBlockElement::createForPart(static_cast<HTMLElement*>(
node()), barPseudoId()); | |
166 addChild(m_barPart->renderer()); | |
167 m_valuePart = ShadowBlockElement::createForPart(static_cast<HTMLElement*
>(node()), valuePseudoId()); | |
168 addChild(m_valuePart->renderer()); | |
169 } else if (!shouldHaveParts() && m_barPart) { | |
170 ASSERT(m_valuePart); | |
171 m_barPart->detach(); | |
172 m_barPart = 0; | |
173 m_valuePart->detach(); | |
174 m_valuePart = 0; | |
175 } | |
176 | |
177 if (m_barPart) { | |
178 ASSERT(m_valuePart); | |
179 m_barPart->updateStyleForPart(barPseudoId()); | |
180 m_valuePart->updateStyleForPart(valuePseudoId()); | |
181 } | |
182 } | 257 } |
183 | 258 |
184 } // namespace WebCore | 259 } // namespace WebCore |
185 | 260 |
186 #endif | 261 #endif |
OLD | NEW |