GravatarApp(const WEnvironment& env): WApplication(env) { GravatarImage* gravatar = new GravatarImage("*****@*****.**", root()); new WBreak(root()); WLineEdit* email = new WLineEdit(root()); email->changed().connect(boost::bind(set_email, gravatar, email)); email->setText("*****@*****.**"); new WBreak(root()); WSlider* size = new WSlider(root()); size->setRange(1, 512); size->setValue(80); size->valueChanged().connect(boost::bind(set_size, gravatar, size)); new WBreak(root()); WButtonGroup* builtin = new WButtonGroup(this); builtin->addButton(new WRadioButton("default", root()), GravatarImage::DEFAULT); builtin->addButton(new WRadioButton("404", root()), GravatarImage::RETURN_404); builtin->addButton(new WRadioButton("mm", root()), GravatarImage::MM); builtin->addButton(new WRadioButton("identicon", root()), GravatarImage::IDENTICON); builtin->addButton(new WRadioButton("monsterid", root()), GravatarImage::MONSTERID); builtin->addButton(new WRadioButton("wavatar", root()), GravatarImage::WAVATAR); builtin->addButton(new WRadioButton("retro", root()), GravatarImage::RETRO); builtin->addButton(new WRadioButton("custom url", root()), 9000); WLineEdit* custom_url = new WLineEdit(root()); custom_url->setText("https://www.google.com/favicon.ico"); builtin->setCheckedButton(builtin->button(GravatarImage::DEFAULT)); builtin->checkedChanged().connect(boost::bind(set_default, gravatar, builtin, custom_url)); new WBreak(root()); WButtonGroup* rating = new WButtonGroup(this); rating->addButton(new WRadioButton("G", root()), GravatarImage::G); rating->addButton(new WRadioButton("PG", root()), GravatarImage::PG); rating->addButton(new WRadioButton("R", root()), GravatarImage::R); rating->addButton(new WRadioButton("X", root()), GravatarImage::X); rating->setCheckedButton(rating->button(GravatarImage::G)); rating->checkedChanged().connect(boost::bind(set_rating, gravatar, rating)); new WBreak(root()); WCheckBox* fd = new WCheckBox("Force default", root()); fd->checked().connect(boost::bind(&GravatarImage::set_force_default, gravatar, true)); fd->unChecked().connect(boost::bind(&GravatarImage::set_force_default, gravatar, false)); new WBreak(root()); WCheckBox* sr = new WCheckBox("Use https", root()); sr->setTristate(); sr->setCheckState(PartiallyChecked); sr->checked().connect(boost::bind(&GravatarImage::set_secure_requests, gravatar, GravatarImage::ALWAYS)); sr->unChecked().connect(boost::bind(&GravatarImage::set_secure_requests, gravatar, GravatarImage::NEVER)); }
void PaintedSlider::paintEvent(WPaintDevice *paintDevice) { if (slider_->tickPosition()) { WPainter painter(paintDevice); int w, h; if (slider_->orientation() == Horizontal) { w = (int)width().toPixels(); h = (int)height().toPixels(); } else { w = (int)height().toPixels(); h = (int)width().toPixels(); painter.translate(0, w); painter.rotate(-90); } int tickInterval = slider_->tickInterval(); int r = range(); if (tickInterval == 0) tickInterval = r / 2; double tickStep = ((double)w - (HANDLE_WIDTH - 10)) / (r / tickInterval); if (tickStep <= 0) return; WPen pen; pen.setColor(WColor(0xd7, 0xd7, 0xd7)); pen.setCapStyle(FlatCap); pen.setWidth(1); painter.setPen(pen); int y1 = h / 4; int y2 = h / 2 - 4; int y3 = h / 2 + 4; int y4 = h - h/4; for (unsigned i = 0; ; ++i) { int x = (HANDLE_WIDTH - 10)/2 + (int) (i * tickStep); if (x > w - (HANDLE_WIDTH - 10)/2) break; if (slider_->tickPosition() & WSlider::TicksAbove) painter.drawLine(x + 0.5, y1, x + 0.5, y2); if (slider_->tickPosition() & WSlider::TicksBelow) painter.drawLine(x + 0.5, y3, x + 0.5, y4); } } }
void PaintedSlider::updateSliderPosition() { double l = (slider_->orientation() == Horizontal) ? w() : h(); double pixelsPerUnit = (l - HANDLE_WIDTH) / range(); double u = ((double)slider_->value() - slider_->minimum()) * pixelsPerUnit; if (slider_->orientation() == Horizontal) handle_->setOffsets(u, Left); else handle_->setOffsets(h() - HANDLE_WIDTH - u, Top); }
void PaintedSlider::propagateSetEnabled(bool enabled) { if (enabled) { removeStyleClass("Wt-disabled"); slider_->removeStyleClass("Wt-disabled"); } else { addStyleClass("Wt-disabled"); slider_->addStyleClass("Wt-disabled"); } WPaintedWidget::propagateSetEnabled(enabled); }
void PaintedSlider::onSliderClick(const WMouseEvent& event) { int x = event.widget().x; int y = event.widget().y; if (WApplication::instance()->layoutDirection() == RightToLeft) x = (int)(w() - x); onSliderReleased(slider_->orientation() == Horizontal ? x : y); }
void PaintedSlider::updateSliderPosition() { double l = (slider_->orientation() == Orientation::Horizontal) ? w() : h(); double pixelsPerUnit = (l - slider_->handleWidth()) / range(); double u = ((double)slider_->value() - slider_->minimum()) * pixelsPerUnit; if (slider_->orientation() == Orientation::Horizontal) { handle_->setOffsets(u, Side::Left); fill_->setWidth(u + slider_->handleWidth() / 2); } else { handle_->setOffsets(h() - slider_->handleWidth() - u, Side::Top); fill_->setHeight(u + slider_->handleWidth() / 2); } }
void PaintedSlider::paintEvent(WPaintDevice *paintDevice) { int tickInterval = slider_->tickInterval(); int r = range(); if (r == 0) { // Empty range, don't paint anything return; } if (tickInterval == 0) tickInterval = r / 2; int numTicks = tickInterval == 0 ? 2 : r / tickInterval + 1; if (numTicks < 1) return; int w = 0, h = 0; switch (slider_->orientation()) { case Orientation::Horizontal: w = (int)paintDevice->width().toPixels(); h = (int)paintDevice->height().toPixels(); break; case Orientation::Vertical: w = (int)paintDevice->height().toPixels(); h = (int)paintDevice->width().toPixels(); } double tickStep = ((double)w + 10 - slider_->handleWidth()) / (numTicks - 1); WPainter painter(paintDevice); for (int i = 0; i < numTicks; ++i) { int v = slider_->minimum() + i * tickInterval; int x = -5 + slider_->handleWidth()/2 + (int) (i * tickStep); switch (slider_->orientation()) { case Orientation::Horizontal: slider_->paintTick(painter, v, x, h/2); break; case Orientation::Vertical: slider_->paintTick(painter, v, h/2, w - x); } } }
void PaintedSlider::connectSlots() { if (Wt::WApplication::instance()->environment().ajax()) { handle_->mouseWentDown().connect(mouseDownJS_); handle_->touchStarted().connect(mouseDownJS_); handle_->mouseMoved().connect(mouseMovedJS_); handle_->touchMoved().connect(mouseMovedJS_); handle_->mouseWentUp().connect(mouseUpJS_); handle_->touchEnded().connect(mouseUpJS_); handle_->clicked().connect(handleClickedJS_); slider_->clicked().connect(this, &PaintedSlider::onSliderClick); sliderReleased_.connect(this, &PaintedSlider::onSliderReleased); } }
void PaintedSlider::sliderResized(const WLength& width, const WLength& height) { if (slider_->orientation() == Orientation::Horizontal) { WLength w = width; if (!w.isAuto()) w = WLength(w.toPixels() - 10); resize(w, height); } else { WLength h = height; if (!h.isAuto()) h = WLength(h.toPixels() - 10); resize(width, h); } updateState(); }
void PaintedSlider::onSliderReleased(int u) { if (slider_->orientation() == Horizontal) u -= HANDLE_WIDTH / 2; else u = (int)h() - (u + HANDLE_WIDTH / 2); double l = (slider_->orientation() == Horizontal) ? w() : h(); double pixelsPerUnit = (l - HANDLE_WIDTH) / range(); double v = std::max(slider_->minimum(), std::min(slider_->maximum(), slider_->minimum() + (int)((double)u / pixelsPerUnit + 0.5))); // TODO changed() ? slider_->sliderMoved().emit(static_cast<int>(v)); slider_->setValue(static_cast<int>(v)); slider_->valueChanged().emit(slider_->value()); updateSliderPosition(); }
int range() const { return slider_->maximum() - slider_->minimum(); }
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(); }
double PaintedSlider::h() const { return height().toPixels() + (slider_->orientation() == Orientation::Vertical ? 10 : 0); }
double PaintedSlider::w() const { return width().toPixels() + (slider_->orientation() == Orientation::Horizontal ? 10 : 0); }
DetailManipulation::DetailManipulation(bool enhance, WContainerWidget *parent) : WContainerWidget(parent), onlySmooth(!enhance) { resize(WLength::Auto, WLength::Auto); // Image bar prepareInputImages(); WContainerWidget *imageBar = new WContainerWidget; WVBoxLayout *imageBarLayout = new WVBoxLayout(); for (size_t i = 0; i < inputImages.size(); ++i) { WImage *img = inputImages[i]->getOriginalImage(); img->setStyleClass("image_button"); img->resize(160, 120); img->setAttributeValue("onMouseOver", "this.width=192; this.height=144;"); img->setAttributeValue("onMouseOut", "this.width=160; this.height=120;"); img->clicked().connect( boost::bind(&DetailManipulation::selectImage, this, i ) ); imageBarLayout->addWidget(img); } imageBar->resize(200, WLength::Auto); imageBar->setLayout(imageBarLayout); selectedImageId = 0; // Main component imageTab = new WTabWidget(); imageTab->addTab(inputImages[selectedImageId]->getOriginalImage(), "Original"); if (onlySmooth) { imageTab->addTab(new WImage(smoothedResult[selectedImageId].second), smoothedResult[selectedImageId].first); } else { imageTab->addTab(new WImage(enhancedResult[selectedImageId].second), enhancedResult[selectedImageId].first); } imageTab->resize(600, WLength::Auto); WGridLayout *controllerLayout = new WGridLayout(); WSlider *rSlider = new WSlider(Wt::Vertical); rSlider->setRange(SLIDER_MINIMUM, SLIDER_MAXIMUM); rSlider->setTickPosition(Wt::WSlider::TicksBothSides); WDoubleSpinBox *rSpinBox = new WDoubleSpinBox(); rSpinBox->setMinimum(R_MINIMUM); rSpinBox->setMaximum(R_MAXIMUM); rSlider->sliderMoved().connect( boost::bind(&DetailManipulation::changeDoubleSpinBoxValue, this, rSpinBox, true, _1) ); rSpinBox->valueChanged().connect( boost::bind(&DetailManipulation::changeSliderValue, this, rSlider, 1.f/(R_MAXIMUM-R_MINIMUM), _1) ); controllerLayout->addWidget(rSlider, 2, 0, 6, 1); controllerLayout->addWidget(rSpinBox, 9, 0); controllerLayout->addWidget(new WText("radius"), 10, 0); WSlider *epsSlider = new WSlider(Wt::Vertical); epsSlider->setMinimum(SLIDER_MINIMUM); epsSlider->setMaximum(SLIDER_MAXIMUM); epsSlider->setRange(SLIDER_MINIMUM, SLIDER_MAXIMUM); epsSlider->setTickPosition(WSlider::TicksBothSides); WDoubleSpinBox *epsSpinBox = new WDoubleSpinBox(); epsSpinBox->setMinimum(EPS_MINIMUM); epsSpinBox->setMaximum(EPS_MAXIMUM); epsSlider->sliderMoved().connect( boost::bind(&DetailManipulation::changeDoubleSpinBoxValue, this, epsSpinBox, false, _1) ); epsSpinBox->valueChanged().connect( boost::bind(&DetailManipulation::changeSliderValue, this, epsSlider, 1.f/(EPS_MAXIMUM-EPS_MINIMUM), _1) ); controllerLayout->addWidget(epsSlider, 2, 1, 6, 1); controllerLayout->addWidget(epsSpinBox, 9, 1); controllerLayout->addWidget(new WText("epsilon"), 10, 1); WPushButton *apply = new WPushButton("Apply"); apply->clicked().connect( boost::bind(&DetailManipulation::applyEnhancement, this, rSpinBox, epsSpinBox ) ); controllerLayout->addWidget(apply, 1, 0, 1, 2); WContainerWidget *controller = new WContainerWidget(); controller->resize(120, WLength::Auto); controller->setLayout(controllerLayout); WBorderLayout *mainLayout = new WBorderLayout(this); mainLayout->addWidget(imageBar, WBorderLayout::West); mainLayout->addWidget(imageTab, WBorderLayout::Center); mainLayout->addWidget(controller, WBorderLayout::East); //setLayout(mainLayout, Wt::AlignTop | Wt::AlignJustify); /* doJavaScript( "(function () { \ var imageTags = document.getElementsByClassName(\"image_button\"); \ for (var i=0; image=imageTags[i]; ++i) { \ if (image.width>200 && image.height>0) { \ image.width = 192; \ } \ }\ })();" );*/ }
void PaintedSlider::updateState() { bool rtl = WApplication::instance()->layoutDirection() == RightToLeft; std::string resourcesURL = WApplication::resourcesUrl(); Orientation o = slider_->orientation(); handle_->setStyleClass("handle"); if (o == Horizontal) { handle_->resize(HANDLE_WIDTH, h()); handle_->setOffsets(0, Top); } else { handle_->resize(w(), HANDLE_WIDTH); handle_->setOffsets(0, Left); } double l = o == Horizontal ? w() : h(); double pixelsPerUnit = (l - HANDLE_WIDTH) / range(); std::string dir; if (o == Horizontal) dir = rtl ? "right" : "left"; else dir = "top"; std::string u = (o == Horizontal ? "x" : "y"); std::string U = (o == Horizontal ? "X" : "Y"); std::string maxS = boost::lexical_cast<std::string>(l - HANDLE_WIDTH); std::string ppU = boost::lexical_cast<std::string>(pixelsPerUnit); std::string minimumS = boost::lexical_cast<std::string>(slider_->minimum()); std::string maximumS = boost::lexical_cast<std::string>(slider_->maximum()); std::string width = boost::lexical_cast<std::string>(w()); std::string horizontal = boost::lexical_cast<std::string>(o == Horizontal); /* * Note: cancelling the mouseDown event prevents the selection behaviour */ std::string mouseDownJS = """obj.setAttribute('down', " WT_CLASS ".widgetCoordinates(obj, event)." + u + "); " WT_CLASS ".cancelEvent(event);"; // = 'u' position relative to background, corrected for slider std::string computeD = "" "var objh = " + handle_->jsRef() + "," "" "objb = " + jsRef() + "," "" "page_u = WT.pageCoordinates(event)." + u + "," "" "widget_page_u = WT.widgetPageCoordinates(objb)." + u + "," "" "pos = page_u - widget_page_u," "" "rtl = " + boost::lexical_cast<std::string>(rtl) + "," "" "horizontal = " + horizontal + ";" "" "if (rtl && horizontal)" "" " pos = " + width + " - pos;" "" "var d = pos - down;"; std::string mouseMovedJS = """var down = obj.getAttribute('down');" """var WT = " WT_CLASS ";" """if (down != null && down != '') {" + computeD + "" "d = Math.max(0, Math.min(d, " + maxS + "));" "" "var v = Math.round(d/" + ppU + ");" "" "var intd = v*" + ppU + ";" "" "if (Math.abs(WT.pxself(objh, '" + dir + "') - intd) > 1) {" "" "objh.style." + dir + " = intd + 'px';" + slider_->sliderMoved().createCall(o == Horizontal ? "v + " + minimumS : maximumS + " - v") + "" "}" """}"; std::string mouseUpJS = """var down = obj.getAttribute('down');" """var WT = " WT_CLASS ";" """if (down != null && down != '') {" + computeD + """d += " + boost::lexical_cast<std::string>(HANDLE_WIDTH / 2) + ";" + sliderReleased_.createCall("d") + "" "obj.removeAttribute('down');" """}"; bool enabled = !slider_->isDisabled(); mouseDownJS_.setJavaScript(std::string("function(obj, event) {") + (enabled ? mouseDownJS : "") + "}"); mouseMovedJS_.setJavaScript(std::string("function(obj, event) {") + (enabled ? mouseMovedJS : "") + "}"); mouseUpJS_.setJavaScript(std::string("function(obj, event) {") + (enabled ? mouseUpJS : "") + "}"); update(); updateSliderPosition(); }