void WWidgetItemImpl::createComponent(DomElement *parentContainer) { DomElement *e = item_->widget()->createSDomElement(WApplication::instance()); e->setProperty(PropertyStyle, e->getProperty(PropertyStyle) + "position:absolute;left:-10000px;top:-10000px;" "visibility:hidden;"); Container *c = dynamic_cast<Container *>(item_->widget()); if (!c) { std::stringstream js; js << "var " << var_ << "=new Ext.BoxComponent({id:'" << id_ << "',applyTo:'" << item_->widget()->id() << "'"; addConfig(js); Container::setSizeConfig(js, item_->widget()); js << "});{var s=" << item_->widget()->jsRef() << ";s.style.position='';" "s.style.left='';" "s.style.top='';" "s.style.visibility='';}"; e->callJavaScript(js.str()); } parentContainer->addChild(e); }
void WAbstractToggleButton::updateDom(DomElement& element, bool all) { WApplication *app = WApplication::instance(); const WEnvironment& env = app->environment(); DomElement *input = 0; DomElement *span = 0; DomElement *label = 0; // Already apply theme here because it may determine its organization if (all) app->theme()->apply(this, element, 1); if (element.type() == DomElement_INPUT) input = &element; else { if (all) { input = DomElement::createNew(DomElement_INPUT); input->setName("in" + id()); span = DomElement::createNew(DomElement_SPAN); span->setName("t" + id()); if (element.type() != DomElement_LABEL) { label = DomElement::createNew(DomElement_LABEL); label->setName("l" + id()); } } else { input = DomElement::getForUpdate("in" + id(), DomElement_INPUT); span = DomElement::getForUpdate("t" + id(), DomElement_SPAN); } } if (all) updateInput(*input, all); EventSignal<> *check = voidEventSignal(CHECKED_SIGNAL, false); EventSignal<> *uncheck = voidEventSignal(UNCHECKED_SIGNAL, false); EventSignal<> *change = voidEventSignal(CHANGE_SIGNAL, false); EventSignal<WMouseEvent> *click = mouseEventSignal(M_CLICK_SIGNAL, false); /* * We piggy-back the checked and uncheck signals on the change signal. * * If agent is IE, then we piggy-back the change on the clicked signal. */ bool piggyBackChangeOnClick = env.agentIsIE(); bool needUpdateChangeSignal = (change && change->needsUpdate(all)) || (check && check->needsUpdate(all)) || (uncheck && uncheck->needsUpdate(all)); bool needUpdateClickedSignal = (click && click->needsUpdate(all)) || (piggyBackChangeOnClick && needUpdateChangeSignal); WFormWidget::updateDom(*input, all); /* * Copy all properties to the exterior element, as they relate to style, * etc... We ignore here attributes (except for tooltip), * see WWebWidget: other attributes need not be moved. * * But -- bug #423, disabled and readonly are properties that should be * kept on the interior element. */ if (&element != input) { if (element.properties().find(PropertyClass) != element.properties().end()) input->addPropertyWord(PropertyClass, element.getProperty(PropertyClass)); element.setProperties(input->properties()); input->clearProperties(); std::string v = element.getProperty(Wt::PropertyDisabled); if (!v.empty()) { input->setProperty(Wt::PropertyDisabled, v); element.removeProperty(Wt::PropertyDisabled); } v = element.getProperty(Wt::PropertyReadOnly); if (!v.empty()) { input->setProperty(Wt::PropertyReadOnly, v); element.removeProperty(Wt::PropertyReadOnly); } v = input->getAttribute("title"); if (!v.empty()) element.setAttribute("title", v); } if (flags_.test(BIT_STATE_CHANGED) || all) { input->setProperty(Wt::PropertyChecked, state_ == Unchecked ? "false" : "true"); if (supportsIndeterminate(env)) input->setProperty(Wt::PropertyIndeterminate, state_ == PartiallyChecked ? "true" : "false"); else input->setProperty(Wt::PropertyStyleOpacity, state_ == PartiallyChecked ? "0.5" : ""); flags_.reset(BIT_STATE_CHANGED); } std::vector<DomElement::EventAction> changeActions; if (needUpdateChangeSignal || (piggyBackChangeOnClick && needUpdateClickedSignal) || all) { std::string dom = "o"; if (check) { if (check->isConnected()) changeActions.push_back (DomElement::EventAction(dom + ".checked", check->javaScript(), check->encodeCmd(), check->isExposedSignal())); check->updateOk(); } if (uncheck) { if (uncheck->isConnected()) changeActions.push_back (DomElement::EventAction("!" + dom + ".checked", uncheck->javaScript(), uncheck->encodeCmd(), uncheck->isExposedSignal())); uncheck->updateOk(); } if (change) { if (change->isConnected()) changeActions.push_back (DomElement::EventAction(std::string(), change->javaScript(), change->encodeCmd(), change->isExposedSignal())); change->updateOk(); } if (!piggyBackChangeOnClick) { if (!(all && changeActions.empty())) input->setEvent("change", changeActions); } } if (needUpdateClickedSignal || all) { if (piggyBackChangeOnClick) { if (click) { changeActions.push_back (DomElement::EventAction(std::string(), click->javaScript(), click->encodeCmd(), click->isExposedSignal())); click->updateOk(); } if (!(all && changeActions.empty())) input->setEvent(CLICK_SIGNAL, changeActions); } else if (click) updateSignalConnection(*input, *click, CLICK_SIGNAL, all); } if (span) { if (all || flags_.test(BIT_TEXT_CHANGED)) { span->setProperty(PropertyInnerHTML, text_.formattedText()); if(all || flags_.test(BIT_WORD_WRAP_CHANGED)) { span->setProperty(PropertyStyleWhiteSpace, flags_.test(BIT_WORD_WRAP) ? "normal" : "nowrap"); flags_.reset(BIT_WORD_WRAP_CHANGED); } flags_.reset(BIT_TEXT_CHANGED); } } if (&element != input) { if (label) { label->addChild(input); label->addChild(span); element.addChild(label); } else { element.addChild(input); element.addChild(span); } } }
void WAbstractToggleButton::updateDom(DomElement& element, bool all) { WApplication *app = WApplication::instance(); const WEnvironment& env = app->environment(); DomElement *input = 0; DomElement *span = 0; if (element.type() == DomElement_LABEL) { if (all) { input = DomElement::createNew(DomElement_INPUT); input->setName("in" + id()); span = DomElement::createNew(DomElement_SPAN); span->setName("l" + id()); } else { input = DomElement::getForUpdate("in" + id(), DomElement_INPUT); span = DomElement::getForUpdate("l" + id(), DomElement_SPAN); } } else input = &element; if (all) updateInput(*input, all); EventSignal<> *check = voidEventSignal(CHECKED_SIGNAL, false); EventSignal<> *uncheck = voidEventSignal(UNCHECKED_SIGNAL, false); EventSignal<> *change = voidEventSignal(CHANGE_SIGNAL, false); EventSignal<WMouseEvent> *click = mouseEventSignal(M_CLICK_SIGNAL, false); /* * We piggy-back the checked and uncheck signals on the change signal. * * If agent is IE, then we piggy-back the change on the clicked signal. */ bool piggyBackChangeOnClick = env.agentIsIE(); bool needUpdateChangeSignal = (change && change->needsUpdate(all)) || (check && check->needsUpdate(all)) || (uncheck && uncheck->needsUpdate(all)); bool needUpdateClickedSignal = (click && click->needsUpdate(all)) || (piggyBackChangeOnClick && needUpdateChangeSignal); WFormWidget::updateDom(*input, all); /* * Copy all properties to the exterior element, as they relate to style, * etc... We ignore here attributes, see WWebWidget: there seems not to * be attributes that sensibly need to be moved. * * But -- bug #423, disabled and readonly are properties that should be * kept on the interior element. */ if (&element != input) { element.setProperties(input->properties()); input->clearProperties(); std::string v = element.getProperty(Wt::PropertyDisabled); if (!v.empty()) { input->setProperty(Wt::PropertyDisabled, v); element.removeProperty(Wt::PropertyDisabled); } v = element.getProperty(Wt::PropertyReadOnly); if (!v.empty()) { input->setProperty(Wt::PropertyReadOnly, v); element.removeProperty(Wt::PropertyReadOnly); } } if (stateChanged_ || all) { input->setProperty(Wt::PropertyChecked, state_ == Unchecked ? "false" : "true"); if (supportsIndeterminate(env)) input->setProperty(Wt::PropertyIndeterminate, state_ == PartiallyChecked ? "true" : "false"); else input->setProperty(Wt::PropertyStyleOpacity, state_ == PartiallyChecked ? "0.5" : ""); stateChanged_ = false; } std::vector<DomElement::EventAction> changeActions; if (needUpdateChangeSignal || (piggyBackChangeOnClick && needUpdateClickedSignal) || all) { std::string dom = "o"; if (check) { if (check->isConnected()) changeActions.push_back (DomElement::EventAction(dom + ".checked", check->javaScript(), check->encodeCmd(), check->isExposedSignal())); check->updateOk(); } if (uncheck) { if (uncheck->isConnected()) changeActions.push_back (DomElement::EventAction("!" + dom + ".checked", uncheck->javaScript(), uncheck->encodeCmd(), uncheck->isExposedSignal())); uncheck->updateOk(); } if (change) { if (change->needsUpdate(all)) changeActions.push_back (DomElement::EventAction(std::string(), change->javaScript(), change->encodeCmd(), change->isExposedSignal())); change->updateOk(); } if (!piggyBackChangeOnClick) { if (!(all && changeActions.empty())) input->setEvent("change", changeActions); } } if (needUpdateClickedSignal || all) { if (piggyBackChangeOnClick) { if (click) { changeActions.push_back (DomElement::EventAction(std::string(), click->javaScript(), click->encodeCmd(), click->isExposedSignal())); click->updateOk(); } if (!(all && changeActions.empty())) input->setEvent(CLICK_SIGNAL, changeActions); } else if (click) updateSignalConnection(*input, *click, CLICK_SIGNAL, all); } if (span) { if (all || textChanged_) { span->setProperty(PropertyInnerHTML, text_.formattedText()); textChanged_ = false; } } if (&element != input) { element.addChild(input); element.addChild(span); } }
/* * fitWidth, fitHeight: * - from setLayout(AlignLeft | AlignTop) * is being deprecated but still needs to be implemented * - nested layouts: handles as other layout items */ DomElement *StdGridLayoutImpl2::createDomElement(bool fitWidth, bool fitHeight, WApplication *app) { needAdjust_ = needConfigUpdate_ = needRemeasure_ = false; addedItems_.clear(); removedItems_.clear(); const unsigned colCount = grid_.columns_.size(); const unsigned rowCount = grid_.rows_.size(); int margin[] = { 0, 0, 0, 0}; int maxWidth = 0, maxHeight = 0; if (layout()->parentLayout() == 0) { #ifndef WT_TARGET_JAVA layout()->getContentsMargins(margin + 3, margin, margin + 1, margin + 2); #else // WT_TARGET_JAVA margin[3] = layout()->getContentsMargin(Left); margin[0] = layout()->getContentsMargin(Top); margin[1] = layout()->getContentsMargin(Right); margin[2] = layout()->getContentsMargin(Bottom); #endif // WT_TARGET_JAVA maxWidth = pixelSize(container()->maximumWidth()); maxHeight = pixelSize(container()->maximumHeight()); } WStringStream js; js << app->javaScriptClass() << ".layouts2.add(new " WT_CLASS ".StdLayout2(" << app->javaScriptClass() << ",'" << id() << "',"; if (layout()->parentLayout()) js << "'" << getImpl(layout()->parentLayout())->id() << "',"; else js << "null,"; bool progressive = !app->environment().ajax(); js << (fitWidth ? '1' : '0') << "," << (fitHeight ? '1' : '0') << "," << (progressive ? '1' : '0') << ","; js << maxWidth << "," << maxHeight << ",[" << grid_.horizontalSpacing_ << "," << margin[3] << "," << margin[1] << "],[" << grid_.verticalSpacing_ << "," << margin[0] << "," << margin[2] << "],"; streamConfig(js, app); DomElement *div = DomElement::createNew(DomElement_DIV); div->setId(id()); div->setProperty(PropertyStylePosition, "relative"); DomElement *table = 0, *tbody = 0, *tr = 0; if (progressive) { table = DomElement::createNew(DomElement_TABLE); WStringStream style; if (maxWidth) style << "max-width: " << maxWidth << "px;"; if (maxHeight) style << "max-height: " << maxHeight << "px;"; style << "width: 100%;"; table->setProperty(PropertyStyle, style.str()); int totalColStretch = 0; for (unsigned col = 0; col < colCount; ++col) totalColStretch += std::max(0, grid_.columns_[col].stretch_); for (unsigned col = 0; col < colCount; ++col) { DomElement *c = DomElement::createNew(DomElement_COL); int stretch = std::max(0, grid_.columns_[col].stretch_); if (stretch || totalColStretch == 0) { char buf[30]; double pct = totalColStretch == 0 ? 100.0 / colCount : (100.0 * stretch / totalColStretch); WStringStream ss; ss << "width:" << Utils::round_css_str(pct, 2, buf) << "%;"; c->setProperty(PropertyStyle, ss.str()); } table->addChild(c); } tbody = DomElement::createNew(DomElement_TBODY); } #ifndef WT_TARGET_JAVA std::vector<bool> overSpanned(colCount * rowCount, false); #else std::vector<bool> overSpanned; overSpanned.insert(0, colCount * rowCount, false); #endif // WT_TARGET_JAVA int prevRowWithItem = -1; for (unsigned row = 0; row < rowCount; ++row) { if (table) tr = DomElement::createNew(DomElement_TR); bool rowVisible = false; int prevColumnWithItem = -1; for (unsigned col = 0; col < colCount; ++col) { Impl::Grid::Item& item = grid_.items_[row][col]; if (!overSpanned[row * colCount + col]) { for (int i = 0; i < item.rowSpan_; ++i) for (int j = 0; j < item.colSpan_; ++j) if (i + j > 0) overSpanned[(row + i) * colCount + col + j] = true; AlignmentFlag hAlign = item.alignment_ & AlignHorizontalMask; AlignmentFlag vAlign = item.alignment_ & AlignVerticalMask; DomElement *td = 0; if (table) { bool itemVisible = hasItem(row, col); rowVisible = rowVisible || itemVisible; td = DomElement::createNew(DomElement_TD); if (itemVisible) { int padding[] = { 0, 0, 0, 0 }; int nextRow = nextRowWithItem(row, col); int prevRow = prevRowWithItem; int nextCol = nextColumnWithItem(row, col); int prevCol = prevColumnWithItem; if (prevRow == -1) padding[0] = margin[0]; else padding[0] = (grid_.verticalSpacing_+1) / 2; if (nextRow == (int)rowCount) padding[2] = margin[2]; else padding[2] = grid_.verticalSpacing_ / 2; if (prevCol == -1) padding[3] = margin[3]; else padding[3] = (grid_.horizontalSpacing_ + 1)/2; if (nextCol == (int)colCount) padding[1] = margin[1]; else padding[1] = (grid_.horizontalSpacing_)/2; WStringStream style; if (app->layoutDirection() == RightToLeft) std::swap(padding[1], padding[3]); if (padding[0] == padding[1] && padding[0] == padding[2] && padding[0] == padding[3]) { if (padding[0] != 0) style << "padding:" << padding[0] << "px;"; } else style << "padding:" << padding[0] << "px " << padding[1] << "px " << padding[2] << "px " << padding[3] << "px;"; if (vAlign != 0) switch (vAlign) { case AlignTop: style << "vertical-align:top;"; break; case AlignMiddle: style << "vertical-align:middle;"; break; case AlignBottom: style << "vertical-align:bottom;"; default: break; } td->setProperty(PropertyStyle, style.str()); if (item.rowSpan_ != 1) td->setProperty(PropertyRowSpan, boost::lexical_cast<std::string>(item.rowSpan_)); if (item.colSpan_ != 1) td->setProperty(PropertyColSpan, boost::lexical_cast<std::string>(item.colSpan_)); prevColumnWithItem = col; } } DomElement *c = 0; if (!table) { if (item.item_) { c = createElement(item.item_, app); div->addChild(c); } } else if (item.item_) c = getImpl(item.item_)->createDomElement(true, true, app); if (table) { if (c) { if (!app->environment().agentIsIElt(9)) c->setProperty(PropertyStyleBoxSizing, "border-box"); if (hAlign == 0) hAlign = AlignJustify; switch (hAlign) { case AlignCenter: { DomElement *itable = DomElement::createNew(DomElement_TABLE); itable->setProperty(PropertyClass, "Wt-hcenter"); if (vAlign == 0) itable->setProperty(PropertyStyle, "height:100%;"); DomElement *irow = DomElement::createNew(DomElement_TR); DomElement *itd = DomElement::createNew(DomElement_TD); if (vAlign == 0) itd->setProperty(PropertyStyle, "height:100%;"); bool haveMinWidth = !c->getProperty(PropertyStyleMinWidth).empty(); itd->addChild(c); if (app->environment().agentIsIElt(9)) { // IE7 and IE8 do support min-width but do not enforce it // properly when in a table. // see http://stackoverflow.com/questions/2356525 // /css-min-width-in-ie6-7-and-8 if (haveMinWidth) { DomElement *spacer = DomElement::createNew(DomElement_DIV); spacer->setProperty(PropertyStyleWidth, c->getProperty(PropertyStyleMinWidth)); spacer->setProperty(PropertyStyleHeight, "1px"); itd->addChild(spacer); } } irow->addChild(itd); itable->addChild(irow); c = itable; break; } case AlignRight: if (!c->isDefaultInline()) c->setProperty(PropertyStyleFloat, "right"); else td->setProperty(PropertyStyleTextAlign, "right"); break; case AlignLeft: if (!c->isDefaultInline()) c->setProperty(PropertyStyleFloat, "left"); else td->setProperty(PropertyStyleTextAlign, "left"); break; default: break; } td->addChild(c); if (app->environment().agentIsIElt(9)) { // IE7 and IE8 do support min-width but do not enforce it properly // when in a table. // see http://stackoverflow.com/questions/2356525 // /css-min-width-in-ie6-7-and-8 if (!c->getProperty(PropertyStyleMinWidth).empty()) { DomElement *spacer = DomElement::createNew(DomElement_DIV); spacer->setProperty(PropertyStyleWidth, c->getProperty(PropertyStyleMinWidth)); spacer->setProperty(PropertyStyleHeight, "1px"); td->addChild(spacer); } } } tr->addChild(td); } } } if (tr) { if (!rowVisible) tr->setProperty(PropertyStyleDisplay, "hidden"); else prevRowWithItem = row; tbody->addChild(tr); } } js << "));"; if (table) { table->addChild(tbody); div->addChild(table); } div->callJavaScript(js.str()); return div; }
void WBootstrapTheme::apply(WWidget *widget, DomElement& element, int elementRole) const { bool creating = element.mode() == DomElement::Mode::Create; if (!widget->isThemeStyleEnabled()) return; { WPopupWidget *popup = dynamic_cast<WPopupWidget *>(widget); if (popup) { WDialog *dialog = dynamic_cast<WDialog *>(widget); if (!dialog) element.addPropertyWord(Property::Class, "dropdown-menu"); } } switch (element.type()) { case DomElementType::A: { if (creating && dynamic_cast<WPushButton *>(widget)) element.addPropertyWord(Property::Class, classBtn(widget)); WPushButton *btn = dynamic_cast<WPushButton *>(widget); if (creating && btn && btn->isDefault()) element.addPropertyWord(Property::Class, "btn-primary"); if (element.getProperty(Property::Class).find("dropdown-toggle") != std::string::npos) { WMenuItem *item = dynamic_cast<WMenuItem *>(widget->parent()); if (!dynamic_cast<WPopupMenu *>(item->parentMenu())) { DomElement *b = DomElement::createNew(DomElementType::B); b->setProperty(Property::Class, "caret"); element.addChild(b); } } break; } case DomElementType::BUTTON: { if (creating && !widget->hasStyleClass("list-group-item")) element.addPropertyWord(Property::Class, classBtn(widget)); WPushButton *button = dynamic_cast<WPushButton *>(widget); if (button) { if (creating && button->isDefault()) element.addPropertyWord(Property::Class, "btn-primary"); if (button->menu() && element.properties().find(Property::InnerHTML) != element.properties().end()) { element.addPropertyWord(Property::InnerHTML, "<span class=\"caret\"></span>"); } if (creating && !button->text().empty()) element.addPropertyWord(Property::Class, "with-label"); if (!button->link().isNull()) LOG_ERROR("Cannot use WPushButton::setLink() after the button has " "been rendered with WBootstrapTheme"); } break; } case DomElementType::DIV: { WDialog *dialog = dynamic_cast<WDialog *>(widget); if (dialog) { if (version_ == BootstrapVersion::v2) element.addPropertyWord(Property::Class, "modal"); else element.addPropertyWord(Property::Class, "modal-dialog Wt-dialog"); return; } WPanel *panel = dynamic_cast<WPanel *>(widget); if (panel) { element.addPropertyWord(Property::Class, classAccordionGroup()); return; } WProgressBar *bar = dynamic_cast<WProgressBar *>(widget); if (bar) { switch (elementRole) { case MainElement: element.addPropertyWord(Property::Class, "progress"); break; case ProgressBarBar: element.addPropertyWord(Property::Class, classBar()); break; case ProgressBarLabel: element.addPropertyWord(Property::Class, "bar-label"); } return; } WGoogleMap *map = dynamic_cast<WGoogleMap *>(widget); if (map) { element.addPropertyWord(Property::Class, "Wt-googlemap"); return; } WAbstractItemView *itemView = dynamic_cast<WAbstractItemView *>(widget); if (itemView) { element.addPropertyWord(Property::Class, "form-inline"); return; } WNavigationBar *navBar = dynamic_cast<WNavigationBar *>(widget); if (navBar) { element.addPropertyWord(Property::Class, classNavbar()); return; } } break; case DomElementType::LABEL: { if (elementRole == 1) { if (version_ == BootstrapVersion::v3) { WCheckBox *cb = dynamic_cast<WCheckBox *>(widget); WRadioButton *rb = nullptr; if (cb) { element.addPropertyWord(Property::Class, widget->isInline() ? "checkbox-inline" : "checkbox"); } else { rb = dynamic_cast<WRadioButton *>(widget); if (rb) element.addPropertyWord(Property::Class, widget->isInline() ? "radio-inline" : "radio"); } if ((cb || rb) && !widget->isInline()) element.setType(DomElementType::DIV); } else { WCheckBox *cb = dynamic_cast<WCheckBox *>(widget); WRadioButton *rb = nullptr; if (cb) { element.addPropertyWord(Property::Class, "checkbox"); } else { rb = dynamic_cast<WRadioButton *>(widget); if (rb) element.addPropertyWord(Property::Class, "radio"); } if ((cb || rb) && widget->isInline()) element.addPropertyWord(Property::Class, "inline"); } } } break; case DomElementType::LI: { WMenuItem *item = dynamic_cast<WMenuItem *>(widget); if (item) { if (item->isSeparator()) element.addPropertyWord(Property::Class, "divider"); if (item->isSectionHeader()) element.addPropertyWord(Property::Class, "nav-header"); if (item->menu()) { if (dynamic_cast<WPopupMenu *>(item->parentMenu())) element.addPropertyWord(Property::Class, "dropdown-submenu"); else element.addPropertyWord(Property::Class, "dropdown"); } } } break; case DomElementType::INPUT: { if (version_ == BootstrapVersion::v3 && formControlStyle_) { WAbstractToggleButton *tb = dynamic_cast<WAbstractToggleButton *>(widget); if (!tb) element.addPropertyWord(Property::Class, "form-control"); } WAbstractSpinBox *spinBox = dynamic_cast<WAbstractSpinBox *>(widget); if (spinBox) { element.addPropertyWord(Property::Class, "Wt-spinbox"); return; } WDateEdit *dateEdit = dynamic_cast<WDateEdit *>(widget); if (dateEdit) { element.addPropertyWord(Property::Class, "Wt-dateedit"); return; } WTimeEdit *timeEdit = dynamic_cast<WTimeEdit *>(widget); if (timeEdit) { element.addPropertyWord(Property::Class, "Wt-timeedit"); return; } } break; case DomElementType::TEXTAREA: case DomElementType::SELECT: if (version_ == BootstrapVersion::v3 && formControlStyle_) element.addPropertyWord(Property::Class, "form-control"); break; case DomElementType::UL: { WPopupMenu *popupMenu = dynamic_cast<WPopupMenu *>(widget); if (popupMenu) { element.addPropertyWord(Property::Class, "dropdown-menu"); if (popupMenu->parentItem() && dynamic_cast<WPopupMenu *>(popupMenu->parentItem()->parentMenu())) element.addPropertyWord(Property::Class, "submenu"); } else { WMenu *menu = dynamic_cast<WMenu *>(widget); if (menu) { element.addPropertyWord(Property::Class, "nav"); WTabWidget *tabs = dynamic_cast<WTabWidget *>(menu->parent()->parent()); if (tabs) element.addPropertyWord(Property::Class, "nav-tabs"); } else { WSuggestionPopup *suggestions = dynamic_cast<WSuggestionPopup *>(widget); if (suggestions) element.addPropertyWord(Property::Class, "typeahead"); } } } case DomElementType::SPAN: { WInPlaceEdit *inPlaceEdit = dynamic_cast<WInPlaceEdit *>(widget); if (inPlaceEdit) element.addPropertyWord(Property::Class, "Wt-in-place-edit"); else { WDatePicker *picker = dynamic_cast<WDatePicker *>(widget); if (picker) element.addPropertyWord(Property::Class, "Wt-datepicker"); } } break; default: break; } }
void WCssDecorationStyle::updateDomElement(DomElement& element, bool all) { /* * set cursor */ if (cursorChanged_ || all) { switch (cursor_) { case AutoCursor: if (cursorChanged_) element.setProperty(PropertyStyleCursor, "auto"); break; case ArrowCursor: element.setProperty(PropertyStyleCursor, "default"); break; case CrossCursor: element.setProperty(PropertyStyleCursor, "crosshair"); break; case PointingHandCursor: element.setProperty(PropertyStyleCursor, "pointer"); break; case OpenHandCursor: element.setProperty(PropertyStyleCursor, "move"); break; case WaitCursor: element.setProperty(PropertyStyleCursor, "wait"); break; case IBeamCursor: element.setProperty(PropertyStyleCursor, "text"); break; case WhatsThisCursor: element.setProperty(PropertyStyleCursor, "help"); break; } if (!cursorImage_.empty()) { element.setProperty(PropertyStyleCursor, "url(" + cursorImage_ + ")," + element.getProperty(PropertyStyleCursor)); } cursorChanged_ = false; } /* * set font */ font_.updateDomElement(element, fontChanged_, all); fontChanged_ = false; /* * set border */ Property properties[4] = { PropertyStyleBorderTop, PropertyStyleBorderRight, PropertyStyleBorderBottom, PropertyStyleBorderLeft }; if (borderChanged_ || all) { for (unsigned i = 0; i < 4; ++i) { if (border_[i]) element.setProperty(properties[i], border_[i]->cssText()); else if (borderChanged_) element.setProperty(properties[i], ""); } borderChanged_ = false; } /* * set colors */ if (foregroundColorChanged_ || all) { if ((all && !foregroundColor_.isDefault()) || foregroundColorChanged_) element.setProperty(PropertyStyleColor, foregroundColor_.cssText()); foregroundColorChanged_ = false; } if (backgroundColorChanged_ || all) { if ((all && !backgroundColor_.isDefault()) || backgroundColorChanged_) element.setProperty(PropertyStyleBackgroundColor, backgroundColor_.cssText()); backgroundColorChanged_ = false; } if (backgroundImageChanged_ || all) { if (!backgroundImage_.isNull() || backgroundImageChanged_) { if (backgroundImage_.isNull()) element.setProperty(PropertyStyleBackgroundImage, "none"); else { Wt::WApplication *app = Wt::WApplication::instance(); std::string url = app->encodeUntrustedUrl (app->resolveRelativeUrl(backgroundImage_.url())); element.setProperty(PropertyStyleBackgroundImage, "url(" + WWebWidget::jsStringLiteral(url, '"') + ")"); } if (backgroundImageRepeat_ != RepeatXY || backgroundImageLocation_ != 0) { switch (backgroundImageRepeat_) { case RepeatXY: element.setProperty(PropertyStyleBackgroundRepeat, "repeat"); break; case RepeatX: element.setProperty(PropertyStyleBackgroundRepeat, "repeat-x"); break; case RepeatY: element.setProperty(PropertyStyleBackgroundRepeat, "repeat-y"); break; case NoRepeat: element.setProperty(PropertyStyleBackgroundRepeat, "no-repeat"); break; } if (backgroundImageLocation_) { // www3schools claims this is needed for mozilla -- but not true ? //element.setProperty(PropertyStyleBackgroundAttachment, "fixed"); std::string location; if (backgroundImageLocation_ & CenterY) location += " center"; else if (backgroundImageLocation_ & Bottom) location += " bottom"; else location += " top"; if (backgroundImageLocation_ & CenterX) location += " center"; else if (backgroundImageLocation_ & Right) location += " right"; else location += " left"; element.setProperty(PropertyStyleBackgroundPosition, location); } } } backgroundImageChanged_ = false; } if (textDecorationChanged_ || all) { std::string options; if (textDecoration_ & Underline) options += " underline"; if (textDecoration_ & Overline) options += " overline"; if (textDecoration_ & LineThrough) options += " line-through"; if (textDecoration_ & Blink) options += " blink"; if (!options.empty() || textDecorationChanged_) element.setProperty(PropertyStyleTextDecoration, options); textDecorationChanged_ = false; } }
void WBootstrapTheme::apply(WWidget *widget, DomElement& element, int elementRole) const { bool creating = element.mode() == DomElement::ModeCreate; { WPopupWidget *popup = dynamic_cast<WPopupWidget *>(widget); if (popup) { WDialog *dialog = dynamic_cast<WDialog *>(widget); if (!dialog) element.addPropertyWord(PropertyClass, "dropdown-menu"); } } switch (element.type()) { case DomElement_A: if (creating && dynamic_cast<WPushButton *>(widget)) element.addPropertyWord(PropertyClass, "btn"); if (element.getProperty(PropertyClass).find("dropdown-toggle") != std::string::npos) { WMenuItem *item = dynamic_cast<WMenuItem *>(widget->parent()); if (!dynamic_cast<WPopupMenu *>(item->parentMenu())) { DomElement *b = DomElement::createNew(DomElement_B); b->setProperty(PropertyClass, "caret"); element.addChild(b); } } break; case DomElement_BUTTON: { if (creating) element.addPropertyWord(PropertyClass, "btn"); WPushButton *button = dynamic_cast<WPushButton *>(widget); if (button) { if (creating && button->isDefault()) element.addPropertyWord(PropertyClass, "btn-primary"); if (button->menu() && element.properties().find(PropertyInnerHTML) != element.properties().end()) { element.addPropertyWord(PropertyInnerHTML, "<span class=\"caret\"></span>"); } } break; } case DomElement_DIV: { WDialog *dialog = dynamic_cast<WDialog *>(widget); if (dialog) { element.addPropertyWord(PropertyClass, "modal"); return; } WPanel *panel = dynamic_cast<WPanel *>(widget); if (panel) { element.addPropertyWord(PropertyClass, "accordion-group"); return; } WProgressBar *bar = dynamic_cast<WProgressBar *>(widget); if (bar) { switch (elementRole) { case MainElementThemeRole: element.addPropertyWord(PropertyClass, "progress"); break; case ProgressBarBarRole: element.addPropertyWord(PropertyClass, "bar"); break; case ProgressBarLabelRole: element.addPropertyWord(PropertyClass, "bar-label"); } return; } WGoogleMap *map = dynamic_cast<WGoogleMap *>(widget); if (map) { element.addPropertyWord(PropertyClass, "Wt-googlemap"); return; } WAbstractItemView *itemView = dynamic_cast<WAbstractItemView *>(widget); if (itemView) { element.addPropertyWord(PropertyClass, "form-horizontal"); return; } } break; case DomElement_LABEL: { WCheckBox *cb = dynamic_cast<WCheckBox *>(widget); if (cb) { element.addPropertyWord(PropertyClass, "checkbox"); if (cb->isInline()) element.addPropertyWord(PropertyClass, "inline"); } else { WRadioButton *rb = dynamic_cast<WRadioButton *>(widget); if (rb) { element.addPropertyWord(PropertyClass, "radio"); if (rb->isInline()) element.addPropertyWord(PropertyClass, "inline"); } } } break; case DomElement_LI: { WMenuItem *item = dynamic_cast<WMenuItem *>(widget); if (item) { if (item->isSeparator()) element.addPropertyWord(PropertyClass, "divider"); if (item->isSectionHeader()) element.addPropertyWord(PropertyClass, "nav-header"); if (item->menu()) { if (dynamic_cast<WPopupMenu *>(item->parentMenu())) element.addPropertyWord(PropertyClass, "dropdown-submenu"); else element.addPropertyWord(PropertyClass, "dropdown"); } } } break; case DomElement_INPUT: { WAbstractSpinBox *spinBox = dynamic_cast<WAbstractSpinBox *>(widget); if (spinBox) { element.addPropertyWord(PropertyClass, "Wt-spinbox"); return; } WDateEdit *dateEdit = dynamic_cast<WDateEdit *>(widget); if (dateEdit) { element.addPropertyWord(PropertyClass, "Wt-dateedit"); return; } } break; case DomElement_UL: { WPopupMenu *popupMenu = dynamic_cast<WPopupMenu *>(widget); if (popupMenu) { element.addPropertyWord(PropertyClass, "dropdown-menu"); if (popupMenu->parentItem() && dynamic_cast<WPopupMenu *>(popupMenu->parentItem()->parentMenu())) element.addPropertyWord(PropertyClass, "submenu"); } else { WMenu *menu = dynamic_cast<WMenu *>(widget); if (menu) { element.addPropertyWord(PropertyClass, "nav"); WTabWidget *tabs = dynamic_cast<WTabWidget *>(menu->parent()->parent()); if (tabs) element.addPropertyWord(PropertyClass, "nav-tabs"); } else { WSuggestionPopup *suggestions = dynamic_cast<WSuggestionPopup *>(widget); if (suggestions) element.addPropertyWord(PropertyClass, "typeahead"); } } } case DomElement_SPAN: { WInPlaceEdit *inPlaceEdit = dynamic_cast<WInPlaceEdit *>(widget); if (inPlaceEdit) element.addPropertyWord(PropertyClass, "Wt-in-place-edit"); } break; default: break; } }