void PaintedSlider::updateState() { bool rtl = WApplication::instance()->layoutDirection() == LayoutDirection::RightToLeft; Orientation o = slider_->orientation(); if (o == Orientation::Horizontal) { handle_->resize(slider_->handleWidth(), h()); handle_->setOffsets(0, Side::Top); } else { handle_->resize(w(), slider_->handleWidth()); handle_->setOffsets(0, Side::Left); } double l = o == Orientation::Horizontal ? w() : h(); double pixelsPerUnit = (l - slider_->handleWidth()) / range(); std::string dir; std::string size; if (o == Orientation::Horizontal) { dir = rtl ? "right" : "left"; size = "width"; } else { dir = "top"; size = "height"; } char u = (o == Orientation::Horizontal ? 'x' : 'y'); double max = l - slider_->handleWidth(); bool horizontal = o == Orientation::Horizontal; char buf[30]; // Buffer for round_js_str /* * Note: cancelling the mouseDown event prevents the selection behaviour */ WStringStream mouseDownJS; mouseDownJS << "obj.setAttribute('down', " WT_CLASS << ".widgetCoordinates(obj, event)." << u << ");" << WT_CLASS ".cancelEvent(event);"; WStringStream computeD; // = 'u' position relative to background, corrected for slider computeD << "var objh = " << handle_->jsRef() << "," << "objf = " << fill_->jsRef() << "," << "objb = " << slider_->jsRef() << "," << "page_u = WT.pageCoordinates(event)." << u << "," << "widget_page_u = WT.widgetPageCoordinates(objb)." << u << "," << "pos = page_u - widget_page_u," << "rtl = " << rtl << "," << "horizontal = " << horizontal << ";" << "if (rtl && horizontal)"; computeD << "pos = " << Utils::round_js_str(l, 3, buf) << " - pos;"; computeD << "var d = pos - down;"; WStringStream mouseMovedJS; mouseMovedJS << "var down = obj.getAttribute('down');" << "var WT = " WT_CLASS ";" << "if (down != null && down != '') {" << computeD.str(); mouseMovedJS << "d = Math.max(0, Math.min(d, " << Utils::round_js_str(max, 3, buf) << "));"; mouseMovedJS << "var v = Math.round(d/" << Utils::round_js_str(pixelsPerUnit, 3, buf) << ");"; mouseMovedJS << "var intd = v*" << Utils::round_js_str(pixelsPerUnit, 3, buf) << ";"; mouseMovedJS << "if (Math.abs(WT.pxself(objh, '" << dir << "') - intd) > 1) {" << "objf.style." << size << " = "; if (o == Orientation::Vertical) { mouseMovedJS << '(' << Utils::round_js_str(max, 3, buf); mouseMovedJS << " - intd + " << (slider_->handleWidth() / 2) << ")"; } else mouseMovedJS << "intd + " << (slider_->handleWidth() / 2); mouseMovedJS << " + 'px';" << "objh.style." << dir << " = intd + 'px';" << "var vs = "; if (o == Orientation::Horizontal) mouseMovedJS << "v + " << slider_->minimum(); else mouseMovedJS << slider_->maximum() << " - v"; mouseMovedJS << ";" << "var f = objb.onValueChange;" << "if (f) f(vs);"; if (slider_->sliderMoved().needsUpdate(true)) { #ifndef WT_TARGET_JAVA mouseMovedJS << slider_->sliderMoved().createCall({"vs"}); #else mouseMovedJS << slider_->sliderMoved().createCall("vs"); #endif } mouseMovedJS << "}" << "}"; WStringStream mouseUpJS; mouseUpJS << "var down = obj.getAttribute('down');" << "var WT = " WT_CLASS ";" << "if (down != null && down != '') {" << computeD.str() << "d += " << (slider_->handleWidth() / 2) << ";" #ifndef WT_TARGET_JAVA << sliderReleased_.createCall({"Math.round(d)"}) #else << sliderReleased_.createCall("Math.round(d)") #endif << "obj.removeAttribute('down');" << "}"; bool enabled = !slider_->isDisabled(); mouseDownJS_.setJavaScript(std::string("function(obj, event) {") + (enabled ? mouseDownJS.str() : "") + "}"); mouseMovedJS_.setJavaScript(std::string("function(obj, event) {") + (enabled ? mouseMovedJS.str() : "") + "}"); mouseUpJS_.setJavaScript(std::string("function(obj, event) {") + (enabled ? mouseUpJS.str() : "") + "}"); handleClickedJS_.setJavaScript(std::string("function(obj, event) {") + WT_CLASS + ".cancelEvent(event," + WT_CLASS + ".CancelPropagate); }"); update(); updateSliderPosition(); }