PseudoId RenderMeter::valuePseudoId() const { HTMLMeterElement* element = static_cast<HTMLMeterElement*>(node()); if (isHorizontal()) { switch (element->gaugeRegion()) { case HTMLMeterElement::GaugeRegionOptimum: return METER_HORIZONTAL_OPTIMUM; case HTMLMeterElement::GaugeRegionSuboptimal: return METER_HORIZONTAL_SUBOPTIMAL; case HTMLMeterElement::GaugeRegionEvenLessGood: return METER_HORIZONTAL_EVEN_LESS_GOOD; } } else { switch (element->gaugeRegion()) { case HTMLMeterElement::GaugeRegionOptimum: return METER_VERTICAL_OPTIMUM; case HTMLMeterElement::GaugeRegionSuboptimal: return METER_VERTICAL_SUBOPTIMAL; case HTMLMeterElement::GaugeRegionEvenLessGood: return METER_VERTICAL_EVEN_LESS_GOOD; } } ASSERT_NOT_REACHED(); return NOPSEUDO; }
String AccessibilityProgressIndicator::valueDescription() const { // If the author has explicitly provided a value through aria-valuetext, use it. String description = AccessibilityRenderObject::valueDescription(); if (!description.isEmpty()) return description; #if ENABLE(METER_ELEMENT) if (!m_renderer->isMeter()) return String(); HTMLMeterElement* meter = meterElement(); if (!meter) return String(); // The HTML spec encourages authors to include a textual representation of the meter's state in // the element's contents. We'll fall back on that if there is not a more accessible alternative. AccessibilityObject* axMeter = axObjectCache()->getOrCreate(meter); if (is<AccessibilityNodeObject>(axMeter)) { description = downcast<AccessibilityNodeObject>(axMeter)->accessibilityDescriptionForChildren(); if (!description.isEmpty()) return description; } return meter->textContent(); #endif return String(); }
void setJSHTMLMeterElementOptimum(ExecState* exec, JSObject* thisObject, JSValue value) { JSHTMLMeterElement* castedThis = static_cast<JSHTMLMeterElement*>(thisObject); HTMLMeterElement* imp = static_cast<HTMLMeterElement*>(castedThis->impl()); ExceptionCode ec = 0; imp->setOptimum(value.toNumber(exec), ec); setDOMException(exec, ec); }
JSValue jsHTMLMeterElementLabels(ExecState* exec, JSValue slotBase, const Identifier&) { JSHTMLMeterElement* castedThis = static_cast<JSHTMLMeterElement*>(asObject(slotBase)); UNUSED_PARAM(exec); HTMLMeterElement* imp = static_cast<HTMLMeterElement*>(castedThis->impl()); JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->labels())); return result; }
JSValue jsHTMLMeterElementOptimum(ExecState* exec, JSValue slotBase, const Identifier&) { JSHTMLMeterElement* castedThis = static_cast<JSHTMLMeterElement*>(asObject(slotBase)); UNUSED_PARAM(exec); HTMLMeterElement* imp = static_cast<HTMLMeterElement*>(castedThis->impl()); JSValue result = jsNumber(imp->optimum()); return result; }
void nsMeterFrame::ReflowBarFrame(nsIFrame* aBarFrame, nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { bool vertical = ResolvedOrientationIsVertical(); WritingMode wm = aBarFrame->GetWritingMode(); LogicalSize availSize = aReflowState.ComputedSize(wm); availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; nsHTMLReflowState reflowState(aPresContext, aReflowState, aBarFrame, availSize); nscoord size = vertical ? aReflowState.ComputedHeight() : aReflowState.ComputedWidth(); nscoord xoffset = aReflowState.ComputedPhysicalBorderPadding().left; nscoord yoffset = aReflowState.ComputedPhysicalBorderPadding().top; // NOTE: Introduce a new function getPosition in the content part ? HTMLMeterElement* meterElement = static_cast<HTMLMeterElement*>(mContent); double max = meterElement->Max(); double min = meterElement->Min(); double value = meterElement->Value(); double position = max - min; position = position != 0 ? (value - min) / position : 1; size = NSToCoordRound(size * position); if (!vertical && (wm.IsVertical() ? wm.IsVerticalRL() : !wm.IsBidiLTR())) { xoffset += aReflowState.ComputedWidth() - size; } // The bar position is *always* constrained. if (vertical) { // We want the bar to begin at the bottom. yoffset += aReflowState.ComputedHeight() - size; size -= reflowState.ComputedPhysicalMargin().TopBottom() + reflowState.ComputedPhysicalBorderPadding().TopBottom(); size = std::max(size, 0); reflowState.SetComputedHeight(size); } else { size -= reflowState.ComputedPhysicalMargin().LeftRight() + reflowState.ComputedPhysicalBorderPadding().LeftRight(); size = std::max(size, 0); reflowState.SetComputedWidth(size); } xoffset += reflowState.ComputedPhysicalMargin().left; yoffset += reflowState.ComputedPhysicalMargin().top; nsHTMLReflowMetrics barDesiredSize(reflowState); ReflowChild(aBarFrame, aPresContext, barDesiredSize, reflowState, xoffset, yoffset, 0, aStatus); FinishReflowChild(aBarFrame, aPresContext, barDesiredSize, &reflowState, xoffset, yoffset, 0); }
void nsMeterFrame::ReflowBarFrame(nsIFrame* aBarFrame, nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { bool vertical = StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL; nsHTMLReflowState reflowState(aPresContext, aReflowState, aBarFrame, nsSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE)); nscoord size = vertical ? aReflowState.ComputedHeight() : aReflowState.ComputedWidth(); nscoord xoffset = aReflowState.mComputedBorderPadding.left; nscoord yoffset = aReflowState.mComputedBorderPadding.top; // NOTE: Introduce a new function getPosition in the content part ? HTMLMeterElement* meterElement = static_cast<HTMLMeterElement*>(mContent); double max = meterElement->Max(); double min = meterElement->Min(); double value = meterElement->Value(); double position = max - min; position = position != 0 ? (value - min) / position : 1; size = NSToCoordRound(size * position); if (!vertical && StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { xoffset += aReflowState.ComputedWidth() - size; } // The bar position is *always* constrained. if (vertical) { // We want the bar to begin at the bottom. yoffset += aReflowState.ComputedHeight() - size; size -= reflowState.mComputedMargin.TopBottom() + reflowState.mComputedBorderPadding.TopBottom(); size = std::max(size, 0); reflowState.SetComputedHeight(size); } else { size -= reflowState.mComputedMargin.LeftRight() + reflowState.mComputedBorderPadding.LeftRight(); size = std::max(size, 0); reflowState.SetComputedWidth(size); } xoffset += reflowState.mComputedMargin.left; yoffset += reflowState.mComputedMargin.top; nsHTMLReflowMetrics barDesiredSize; ReflowChild(aBarFrame, aPresContext, barDesiredSize, reflowState, xoffset, yoffset, 0, aStatus); FinishReflowChild(aBarFrame, aPresContext, &reflowState, barDesiredSize, xoffset, yoffset, 0); }
double RenderMeter::valueRatio() const { HTMLMeterElement* element = static_cast<HTMLMeterElement*>(node()); double min = element->min(); double max = element->max(); double value = element->value(); if (max <= min) return 0; return (value - min) / (max - min); }
bool RenderTheme::paintMeter(RenderObject* renderObject, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { // Some platforms do not have a native gauge widget, so we draw here a default implementation. RenderMeter* renderMeter = toRenderMeter(renderObject); RenderStyle* style = renderObject->style(); int left = style->borderLeft().width() + style->paddingLeft().value(); int top = style->borderTop().width() + style->paddingTop().value(); int right = style->borderRight().width() + style->paddingRight().value(); int bottom = style->borderBottom().width() + style->paddingBottom().value(); FloatRect innerRect(rect.x() + left, rect.y() + top, rect.width() - left - right, rect.height() - top - bottom); HTMLMeterElement* element = static_cast<HTMLMeterElement*>(renderMeter->node()); double min = element->min(); double max = element->max(); double value = element->value(); if (min >= max) { paintInfo.context->fillRect(innerRect, Color::black, style->colorSpace()); return false; } // Paint the background first paintInfo.context->fillRect(innerRect, Color::lightGray, style->colorSpace()); FloatRect valueRect; if (rect.width() < rect.height()) { // Vertical gauge double scale = innerRect.height() / (max - min); valueRect.setLocation(FloatPoint(innerRect.x(), innerRect.y() + narrowPrecisionToFloat((max - value) * scale))); valueRect.setSize(FloatSize(innerRect.width(), narrowPrecisionToFloat((value - min) * scale))); } else if (renderMeter->style()->direction() == RTL) { // right to left horizontal gauge double scale = innerRect.width() / (max - min); valueRect.setLocation(FloatPoint(innerRect.x() + narrowPrecisionToFloat((max - value) * scale), innerRect.y())); valueRect.setSize(FloatSize(narrowPrecisionToFloat((value - min) * scale), innerRect.height())); } else { // left to right horizontal gauge double scale = innerRect.width() / (max - min); valueRect.setLocation(innerRect.location()); valueRect.setSize(FloatSize(narrowPrecisionToFloat((value - min)) * scale, innerRect.height())); } if (!valueRect.isEmpty()) paintInfo.context->fillRect(valueRect, Color::black, style->colorSpace()); return false; }
bool RenderThemeSafari::paintMeter(const RenderObject& renderObject, const PaintInfo& paintInfo, const IntRect& rect) { // NOTE: This routine is for testing only. It should be fleshed out with a real CG-based implementation. // Right now it uses a slider, with the thumb positioned at the meter point. if (!renderObject.isMeter()) return true; HTMLMeterElement* element = toRenderMeter(&renderObject)->meterElement(); int remaining = static_cast<int>((1.0 - element->valueRatio()) * static_cast<double>(rect.size().width())); // Draw the background paintSliderTrack(renderObject, paintInfo, rect); // Draw the progress portion IntRect completedRect(rect); completedRect.contract(remaining, 0); paintSliderThumb(renderObject, paintInfo, completedRect); return true; }
const AtomicString& MeterValueElement::valuePseudoId() const { DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, optimumPseudoId, ("-webkit-meter-optimum-value", AtomicString::ConstructFromLiteral)); DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, suboptimumPseudoId, ("-webkit-meter-suboptimum-value", AtomicString::ConstructFromLiteral)); DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, evenLessGoodPseudoId, ("-webkit-meter-even-less-good-value", AtomicString::ConstructFromLiteral)); HTMLMeterElement* meter = meterElement(); if (!meter) return optimumPseudoId; switch (meter->gaugeRegion()) { case HTMLMeterElement::GaugeRegionOptimum: return optimumPseudoId; case HTMLMeterElement::GaugeRegionSuboptimal: return suboptimumPseudoId; case HTMLMeterElement::GaugeRegionEvenLessGood: return evenLessGoodPseudoId; default: ASSERT_NOT_REACHED(); return optimumPseudoId; } }
bool RenderThemeNix::paintMeter(RenderObject* o, const PaintInfo& i, const IntRect& rect) { if (!o->isMeter()) return true; RenderMeter* renderMeter = toRenderMeter(o); HTMLMeterElement* e = renderMeter->meterElement(); WebKit::WebThemeEngine::MeterExtraParams extraParams; extraParams.min = e->min(); extraParams.max = e->max(); extraParams.value = e->value(); extraParams.low = e->low(); extraParams.high = e->high(); extraParams.optimum = e->optimum(); themeEngine()->paintMeter(webCanvas(i), getWebThemeState(this, o), rect, extraParams); return false; }