Пример #1
0
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);
}
Пример #2
0
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);
  }
}
Пример #4
0
/*
 * 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;
}
Пример #5
0
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;
  }
}
Пример #6
0
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;
  }
}
Пример #7
0
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;
  }
}