Exemplo n.º 1
0
void WContainerWidget::updateDom(DomElement& element, bool all)
{
  if (contentAlignmentChanged_ || all) {
    switch(contentAlignment_) {
    case AlignLeft:
      if (contentAlignmentChanged_)
	element.setProperty(PropertyStyleTextAlign, "left");
      break;
    case AlignRight:
      element.setProperty(PropertyStyleTextAlign, "right");
      break;
    case AlignCenter:
      element.setProperty(PropertyStyleTextAlign, "center");
      break;
    case AlignJustify:
      element.setProperty(PropertyStyleTextAlign, "justify");
    }

    /*
     * Welcome to CSS hell.
     *
     * Apparently, the text-align property only applies to inline elements.
     * To center non-inline children, the standard says to set its left and
     * right margin to 'auto'.
     *
     * I assume the same applies for aligning to the right ?
     */
    for (unsigned i = 0; i < children().size(); ++i) {
      WWidget *child = children()[i];

      if (!child->isInline()) {
	if (contentAlignment_ == AlignCenter) {
	  if (!child->margin(Left).isAuto())
	    child->setMargin(WLength(), Left);
	  if (!child->margin(Right).isAuto())
	    child->setMargin(WLength(), Right);
	}
	if (contentAlignment_ == AlignRight) {
	  if (!child->margin(Left).isAuto())
	    child->setMargin(WLength(), Left);
	}
      }
    }

    contentAlignmentChanged_ = false;
  }

  if (paddingsChanged_ || all) {
    if (paddingsChanged_
	|| !padding_[0].isAuto()
	|| !padding_[1].isAuto()
	|| !padding_[2].isAuto()
	|| !padding_[3].isAuto()) {
      if ((padding_[0] == padding_[1])
	  && (padding_[0] == padding_[2])
	  && (padding_[0] == padding_[3]))
	element.setProperty(PropertyStylePadding,
			    padding_[0].cssText());
      else
	element.setProperty(PropertyStylePadding,
			    padding_[0].cssText()
			    + " " + padding_[1].cssText()
			    + " " + padding_[2].cssText()
			    + " " + padding_[3].cssText());
    }

    paddingsChanged_ = false;
  }

  WInteractWidget::updateDom(element, all);

  bool wasEmpty 
    = (((addedChildren_ ? addedChildren_->size() : 0) == children_->size())
       && (otherImpl_ ? (otherImpl_->scriptFunctions_
			? otherImpl_->scriptFunctions_->empty() : true)
	   : true));
  element.setWasEmpty(wasEmpty);

  if (addedChildren_) {
    for (unsigned i = 0; i < addedChildren_->size(); ++i) {
      DomElement *c = (*addedChildren_)[i]->webWidget()->createSDomElement();
      element.addChild(c);
    }

    delete addedChildren_;
    addedChildren_ = 0;
  }
}
Exemplo n.º 2
0
void WContainerWidget::updateDom(DomElement& element, bool all)
{
  if (all && element.type() == DomElement_LI && isInline())
    element.setProperty(PropertyStyleDisplay, "inline");

  if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED) || all) {
    AlignmentFlag hAlign = contentAlignment_ & AlignHorizontalMask;

    bool ltr = WApplication::instance()->layoutDirection() == LeftToRight;

    switch (hAlign) {
    case AlignLeft:
      if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED))
	element.setProperty(PropertyStyleTextAlign, ltr ? "left" : "right");
      break;
    case AlignRight:
      element.setProperty(PropertyStyleTextAlign, ltr ? "right" : "left");
      break;
    case AlignCenter:
      element.setProperty(PropertyStyleTextAlign, "center");
      break;
    case AlignJustify:
#ifndef WT_NO_LAYOUT
      if (!layout_)
#endif // WT_NO_LAYOUT
	element.setProperty(PropertyStyleTextAlign, "justify");
      break;
    default:
      break;
    }

    if (domElementType() == DomElement_TD) {
      AlignmentFlag vAlign = contentAlignment_ & AlignVerticalMask;
      switch (vAlign) {
      case AlignTop:
	if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED))
	  element.setProperty(PropertyStyleVerticalAlign, "top");
	break;
      case AlignMiddle:
	element.setProperty(PropertyStyleVerticalAlign, "middle");
	break;
      case AlignBottom:
	element.setProperty(PropertyStyleVerticalAlign, "bottom");
      default:
	break;
      }
    }
  }

  if (flags_.test(BIT_ADJUST_CHILDREN_ALIGN)
      || flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED) || all) {
    /*
     * Welcome to CSS hell.
     *
     * Apparently, the text-align property only applies to inline elements.
     * To center non-inline children, the standard says to set its left and
     * right margin to 'auto'.
     *
     * I assume the same applies for aligning to the right ?
     */
    for (unsigned i = 0; i < children_->size(); ++i) {
      WWidget *child = (*children_)[i];

      if (!child->isInline()) {
	AlignmentFlag ha = contentAlignment_ & AlignHorizontalMask;
	if (ha == AlignCenter) {
	  if (!child->margin(Left).isAuto())
	    child->setMargin(WLength::Auto, Left);
	  if (!child->margin(Right).isAuto())
	    child->setMargin(WLength::Auto, Right);
	} else if (ha == AlignRight) {
	  if (!child->margin(Left).isAuto())
	    child->setMargin(WLength::Auto, Left);
	}
      }
    }

    flags_.reset(BIT_CONTENT_ALIGNMENT_CHANGED);
    flags_.reset(BIT_ADJUST_CHILDREN_ALIGN);
  }

  if (flags_.test(BIT_PADDINGS_CHANGED)
      || (all && padding_ &&
	  !(   padding_[0].isAuto() && padding_[1].isAuto()
	    && padding_[2].isAuto() && padding_[3].isAuto()))) {

    if ((padding_[0] == padding_[1])
	&& (padding_[0] == padding_[2])
	&& (padding_[0] == padding_[3]))
      element.setProperty(PropertyStylePadding,
			  padding_[0].cssText());
    else
      element.setProperty(PropertyStylePadding,
			  padding_[0].cssText()
			  + " " + padding_[1].cssText()
			  + " " + padding_[2].cssText()
			  + " " + padding_[3].cssText());

    flags_.reset(BIT_PADDINGS_CHANGED);
  }

  WInteractWidget::updateDom(element, all);

  if (flags_.test(BIT_OVERFLOW_CHANGED)
      || (all && overflow_ &&
	  !(overflow_[0] == OverflowVisible
	    && overflow_[1] == OverflowVisible))) {
    static const char *cssText[] = { "visible", "auto", "hidden", "scroll" };

    element.setProperty(PropertyStyleOverflowX, cssText[overflow_[0]]);
    element.setProperty(PropertyStyleOverflowY, cssText[overflow_[1]]);

    flags_.reset(BIT_OVERFLOW_CHANGED);

    /* If a container widget has overflow, then, if ever something
     * inside it has position scheme relative/absolute, it will not
     * scroll properly unless every element up to the container and including 
     * the container itself has overflow: relative.
     *
     * The following fixes the common case:
     * container (overflow) - container - layout
     */
    WApplication *app = WApplication::instance();
    if (app->environment().agentIsIE()
	&& (overflow_[0] == OverflowAuto || overflow_[0] == OverflowScroll))
      if (positionScheme() == Static)
	element.setProperty(PropertyStylePosition, "relative");
  }
}