Example #1
0
DomElement *FlexLayoutImpl::createElement(Orientation orientation,
					  unsigned index,
					  int totalStretch,
					  WApplication *app)
{
  Impl::Grid::Item& it = item(orientation, index);
  Impl::Grid::Section& s = section(orientation, index);

  DomElement *el
    = getImpl(it.item_.get())->createDomElement(nullptr, true, true, app);
  if (dynamic_cast<StdGridLayoutImpl2*>(getImpl(it.item_.get()))) {
    DomElement *wrapEl = DomElement::createNew(DomElementType::DIV);
    wrapEl->addChild(el);
    el = wrapEl;
  }

  int m[] = { 0, 0, 0, 0 };
  if (FlexLayoutImpl *flexImpl = dynamic_cast<FlexLayoutImpl*>(getImpl(it.item_.get()))) {
    Orientation elOrientation = flexImpl->getOrientation();
    if (elOrientation == Orientation::Horizontal) {
      m[3] -= (flexImpl->grid_.horizontalSpacing_) / 2;
      m[1] -= (flexImpl->grid_.horizontalSpacing_ + 1) / 2;
    } else {
      m[0] -= (flexImpl->grid_.verticalSpacing_) / 2;
      m[2] -= (flexImpl->grid_.horizontalSpacing_ + 1) / 2;
    }
  }

  AlignmentFlag hAlign = it.alignment_ & AlignHorizontalMask;
  AlignmentFlag vAlign = it.alignment_ & AlignVerticalMask;

  /*
   * If not justifying along main axis, then we need to wrap inside
   * an additional (flex) element
   */
  if (orientation == Orientation::Horizontal) {
    if (hAlign != static_cast<AlignmentFlag>(0)) {
      el->setProperty(Property::StyleFlex, "0 0 auto");

      DomElement *wrap = DomElement::createNew(DomElementType::DIV);
      wrap->setId("w" + el->id());
      wrap->setProperty(Property::StyleDisplay, styleDisplay());
      wrap->setProperty(Property::StyleFlexFlow, styleFlex());
      wrap->addChild(el);
      el = wrap;

      switch (hAlign) {
      case AlignmentFlag::Left:
	el->setProperty(Property::StyleJustifyContent, "flex-start");
	break;
      case AlignmentFlag::Center:
	el->setProperty(Property::StyleJustifyContent, "center");
	break;
      case AlignmentFlag::Right:
	el->setProperty(Property::StyleJustifyContent, "flex-end");
      default:
	break;
      }
    }

    if (vAlign != static_cast<AlignmentFlag>(0))
      switch (vAlign) {
      case AlignmentFlag::Top:
	el->setProperty(Property::StyleAlignSelf, "flex-start");
	break;
      case AlignmentFlag::Middle:
	el->setProperty(Property::StyleAlignSelf, "center");
	break;
      case AlignmentFlag::Bottom:
	el->setProperty(Property::StyleAlignSelf, "flex-end");
	break;
      case AlignmentFlag::Baseline:
	el->setProperty(Property::StyleAlignSelf, "baseline");
      default:
	break;
      }
  } else {
    if (vAlign != static_cast<AlignmentFlag>(0)) {
      el->setProperty(Property::StyleFlex, "0 0 auto");

      DomElement *wrap = DomElement::createNew(DomElementType::DIV);
      wrap->setId("w" + el->id());
      wrap->setProperty(Property::StyleDisplay, styleDisplay());
      wrap->setProperty(Property::StyleFlexFlow, styleFlex());
      wrap->addChild(el);
      el = wrap;

      switch (vAlign) {
      case AlignmentFlag::Top:
	el->setProperty(Property::StyleJustifyContent, "flex-start");
	break;
      case AlignmentFlag::Middle:
	el->setProperty(Property::StyleJustifyContent, "center");
	break;
      case AlignmentFlag::Bottom:
	el->setProperty(Property::StyleJustifyContent, "flex-end");
      default:
	break;
      }
    }

    if (hAlign != static_cast<AlignmentFlag>(0)) 
      switch (hAlign) {
      case AlignmentFlag::Left:
	el->setProperty(Property::StyleAlignSelf, "flex-start");
	break;
      case AlignmentFlag::Center:
	el->setProperty(Property::StyleAlignSelf, "center");
	break;
      case AlignmentFlag::Right:
	el->setProperty(Property::StyleAlignSelf, "flex-end");
	break;
      default:
	break;
      }
  }
      
  {
    WStringStream flexProperty;
    int flexGrow = totalStretch == 0 ? 1 : s.stretch_;
    int flexShrink = totalStretch == 0 ? 1 : (s.stretch_ == 0 ? 0 : 1);
    flexProperty << flexGrow << ' ' << flexShrink << ' ' << s.initialSize_.cssText();
    if (s.stretch_ == 0)
      el->setAttribute("flg", "0");
    el->setProperty(Property::StyleFlex, flexProperty.str());
  }

  switch (getDirection()) {
  case LayoutDirection::LeftToRight:
    m[3] += (grid_.horizontalSpacing_ + 1) / 2;
    m[1] += (grid_.horizontalSpacing_) / 2;
    break;

  case LayoutDirection::RightToLeft:
    m[1] += (grid_.horizontalSpacing_ + 1) / 2;
    m[3] += (grid_.horizontalSpacing_) / 2;
    break;

  case LayoutDirection::TopToBottom:
    m[0] += (grid_.horizontalSpacing_ + 1) / 2;
    m[2] += (grid_.horizontalSpacing_) / 2;
    break;

  case LayoutDirection::BottomToTop:
    m[2] += (grid_.horizontalSpacing_ + 1) / 2;
    m[0] += (grid_.horizontalSpacing_) / 2;
    break;
  }

  if (m[0] != 0 || m[1] != 0 || m[2] != 0 || m[3] != 0) {
    WStringStream marginProperty;
    marginProperty << m[0] << "px " << m[1] << "px "
		   << m[2] << "px " << m[3] << "px";
    el->setProperty(Property::StyleMargin, marginProperty.str());
  }

  return el;
}