Example #1
0
DomElement *WPaintedWidget::createDomElement(WApplication *app)
{
  createPainter();

  DomElement *result = DomElement::createNew(domElementType());
  setId(result, app);

  DomElement *wrap = result;

  if (width().isAuto() && height().isAuto()) {
    result->setProperty(PropertyStylePosition, "relative");

    wrap = DomElement::createNew(DomElement_DIV);
    wrap->setProperty(PropertyStylePosition, "absolute");
    wrap->setProperty(PropertyStyleLeft, "0");
    wrap->setProperty(PropertyStyleRight, "0");
  }

  DomElement *canvas = DomElement::createNew(DomElement_DIV);

  if (!app->environment().agentIsSpiderBot())
    canvas->setId('p' + id());

  WPaintDevice *device = painter_->getPaintDevice(false);

  //handle the widget correctly when inline and using VML 
  if (painter_->renderType() == WWidgetPainter::InlineVml && isInline()) {
    result->setProperty(PropertyStyle, "zoom: 1;");
    canvas->setProperty(PropertyStyleDisplay, "inline");
    canvas->setProperty(PropertyStyle, "zoom: 1;");
  }

  if (renderWidth_ != 0 && renderHeight_ != 0) {
    paintEvent(device);

#ifdef WT_TARGET_JAVA
    if (device->painter())
      device->painter()->end();
#endif // WT_TARGET_JAVA
  }

  painter_->createContents(canvas, device);

  needRepaint_ = false;

  wrap->addChild(canvas);
  if (wrap != result)
    result->addChild(wrap);

  updateDom(*result, true);

  return result;
}
Example #2
0
File: WTable.C Project: ReWeb3D/wt
DomElement *WTable::createDomElement(WApplication *app)
{
  bool withIds = !app->environment().agentIsSpiderBot();

  DomElement *table = DomElement::createNew(domElementType());
  setId(table, app);

  DomElement *thead = 0;
  if (headerRowCount_ != 0) {
    thead = DomElement::createNew(DomElement_THEAD);
    if (withIds)
      thead->setId(id() + "th");
  }

  DomElement *tbody = DomElement::createNew(DomElement_TBODY);
  if (withIds)
    tbody->setId(id() + "tb");

  for (unsigned col = 0; col < columns_.size(); ++col) {
    DomElement *c = DomElement::createNew(DomElement_COL);
    if (withIds)
      c->setId(columns_[col]->id());
    columns_[col]->updateDom(*c, true);
    table->addChild(c);
  }
  
  flags_.reset(BIT_COLUMNS_CHANGED);

  for (unsigned row = 0; row < (unsigned)rowCount(); ++row)
    for (unsigned col = 0; col < (unsigned)columnCount(); ++col)
      itemAt(row, col).overSpanned = false;
  
  for (unsigned row = 0; row < (unsigned)rowCount(); ++row) {
    DomElement *tr = createRow(row, withIds, app);
    if (row < static_cast<unsigned>(headerRowCount_))
      thead->addChild(tr);
    else
      tbody->addChild(tr);
  }
  rowsAdded_ = 0;

  if (thead)
    table->addChild(thead);
  table->addChild(tbody);

  updateDom(*table, true);

  flags_.reset(BIT_GRID_CHANGED);
  delete rowsChanged_;
  rowsChanged_ = 0;

  return table;
}
Example #3
0
DomElement *WGLWidget::createDomElement(WApplication *app)
{
  DomElement *result = 0;
  if (app->environment().agentIsIElt(9) ||
      app->environment().agent() == WEnvironment::MobileWebKitAndroid) {
    // Shortcut: IE misbehaves when it encounters a canvas element
    result = DomElement::createNew(DomElement_DIV);
    if (alternative_)
      result->addChild(alternative_->createSDomElement(app));
  } else {
    result = DomElement::createNew(DomElement_CANVAS);;
    if (alternative_) {
      result->addChild(alternative_->createSDomElement(app));
    }
  }
  setId(result, app);

  std::stringstream tmp;
    tmp <<
      "{\n"
      """var o = new " WT_CLASS ".WGLWidget(" << app->javaScriptClass() << "," << jsRef() << ");\n"
      """o.discoverContext(function(){" << webglNotAvailable_.createCall() << "});\n";

    js_.str("");
    initializeGL();
    tmp <<
      """o.initializeGL=function(){\n"
      //"""debugger;\n"
      """var obj=" << glObjJsRef() << ";\n"
      """var ctx=obj.ctx; if(!ctx) return;\n" <<
      "" << js_.str() <<
      """obj.initialized = true;\n"
      // updates are queued until initialization is complete
      """var key;\n"
      """for(key in obj.updates) obj.updates[key]();\n"
      """obj.updates = new Array();\n"
      // Similar, resizeGL is not executed until initialized
      """obj.resizeGL();\n"
      "};\n"
      "}\n";
  tmp << delayedJavaScript_.str();
  delayedJavaScript_.str("");
  result->callJavaScript(tmp.str());

  repaintGL(PAINT_GL | RESIZE_GL);

  updateDom(*result, true);


  return result;
}
Example #4
0
void WFileUpload::updateDom(DomElement& element, bool all)
{
  bool containsProgress = progressBar_ && progressBar_->parent() == this;
  DomElement *inputE = 0;

  if (element.type() != DomElement_INPUT
      && flags_.test(BIT_DO_UPLOAD)
      && containsProgress && !progressBar_->isRendered())
    element.addChild(progressBar_->createSDomElement(WApplication::instance()));

  // upload() + disable() does not work. -- fix after this release,
  // change order of javaScript_ and properties rendering in DomElement

  if (fileUploadTarget_ && flags_.test(BIT_DO_UPLOAD)) {
    element.callMethod("submit()");
    flags_.reset(BIT_DO_UPLOAD);

    if (containsProgress) {
      inputE = DomElement::getForUpdate("in" + id(), DomElement_INPUT);
      inputE->setProperty(PropertyStyleDisplay, "none");
    }
  }

  if (flags_.test(BIT_ENABLED_CHANGED)) {
    if (!inputE)
      inputE = DomElement::getForUpdate("in" + id(), DomElement_INPUT);

    if (isDisabled())
      inputE->callMethod("disabled=true");
    else
      inputE->callMethod("disabled=false");

    flags_.reset(BIT_ENABLED_CHANGED);
  }

  EventSignal<> *change = voidEventSignal(CHANGE_SIGNAL, false);
  if (change && change->needsUpdate(all)) {
    if (!inputE)
      inputE = DomElement::getForUpdate("in" + id(), DomElement_INPUT);

    updateSignalConnection(*inputE, *change, "change", all);
  }

  if (inputE)
    element.addChild(inputE);

  WWebWidget::updateDom(element, all);
}
Example #5
0
DomElement *WFileUpload::createDomElement()
{
  if (methodIframe_) {
    DomElement *form = DomElement::createNew(DomElement::FORM);
    form->setId(this, true);
    form->setAttribute("method", "post");
    form->setAttribute("action", generateUrl());
    form->setAttribute("enctype", "multipart/form-data");
    form->setAttribute("style", "margin:0;padding:0;display:inline");

    DomElement *input = DomElement::createNew(DomElement::INPUT);
    input->setAttribute("type", "file");
    input->setAttribute("name", "data");
    input->setAttribute("size", boost::lexical_cast<std::string>(textSize_));
    input->setId("in" + formName());

    updateSignalConnection(*input, changed, "change", true);

    form->addChild(input);

    updateDom(*form, true);

    return form;
  } else {
    DomElement *result = DomElement::createNew(DomElement::INPUT);
    result->setAttribute("type", "file");
    result->setAttribute("size", boost::lexical_cast<std::string>(textSize_));
    result->setId(this, true);
    updateSignalConnection(*result, changed, "change", true);

    updateDom(*result, true);

    return result;
  }
}
Example #6
0
void WAbstractMedia::getDomChanges(std::vector<DomElement *>& result,
				   WApplication *app)
{
  if (!mediaId_.empty()) {
    DomElement *media = DomElement::getForUpdate(mediaId_, DomElement_DIV);
    updateMediaDom(*media, false);
    if (sourcesChanged_) {
      // Updating source elements seems to be ill-supported in at least FF,
      // so we delete them all and reinsert them.
      // Delete source elements that are no longer required
      for (std::size_t i = 0; i < sourcesRendered_; ++i)
	media->callJavaScript
	  (WT_CLASS ".remove('" + mediaId_ + "s"
	   + boost::lexical_cast<std::string>(i) + "');",
	   true);
      sourcesRendered_ = 0;
      for (std::size_t i = 0; i < sources_.size(); ++i) {
        DomElement *src = DomElement::createNew(DomElement_SOURCE);
        src->setId(mediaId_ + "s" + boost::lexical_cast<std::string>(i));
        renderSource(src, *sources_[i], i + 1 >= sources_.size());
        media->addChild(src);
      }
      sourcesRendered_ = sources_.size();
      sourcesChanged_ = false;
      // Explicitly request rerun of media selection algorithm
      // 4.8.9.2 says it should happen automatically, but FF doesn't
      media->callJavaScript(jsMediaRef() + ".load();");
    }
    result.push_back(media);
  }
  WInteractWidget::getDomChanges(result, app);
}
Example #7
0
void WComboBox::updateDom(DomElement& element, bool all)
{
  if (itemsChanged_ || all) {
    if (!all)
      element.removeAllChildren();

    for (unsigned i = 0; i < items_.size(); ++i) {
      DomElement *item = DomElement::createNew(DomElement::OPTION);
      item->setAttribute("value", boost::lexical_cast<std::string>(i));
      item->setProperty(Wt::PropertyInnerHTML, items_[i]);
      if ((int)i == currentIndex_)
	item->setProperty(Wt::PropertySelected, "true");

      element.addChild(item);
    }

    itemsChanged_ = false;
  }

  if (selectionChanged_) {
    element.setProperty(Wt::PropertySelectedIndex,
			boost::lexical_cast<std::string>(currentIndex_));
    selectionChanged_ = false;
  }

  const WSignalInstance_ *s1 = getSignal(SIGNAL(activated(int)));
  const WSignalInstance_ *s2 = getSignal(SIGNAL(activated(const std::string)));
  if (isConnected(s1) || isConnected(s2))
    connect(this, SIGNAL(changed()), this, SLOT(propagateChanged()));

  WFormWidget::updateDom(element, all);

  renderOk();
}
Example #8
0
void WComboBox::updateDom(DomElement& element, bool all)
{
  if (itemsChanged_ || all) {
    if (!all)
      element.removeAllChildren();

    for (unsigned i = 0; i < items_.size(); ++i) {
      DomElement *item = DomElement::createNew(DomElement::OPTION);
      item->setAttribute("value", boost::lexical_cast<std::string>(i));
      item->setProperty(Wt::PropertyInnerHTML,
			toUTF8(escapeText(items_[i].value())));
      if ((int)i == currentIndex_)
	item->setProperty(Wt::PropertySelected, "true");

      element.addChild(item);
    }

    itemsChanged_ = false;
  }

  if (selectionChanged_) {
    element.setProperty(Wt::PropertySelectedIndex,
			boost::lexical_cast<std::string>(currentIndex_));
    selectionChanged_ = false;
  }

  if (activated.isConnected() || sactivated.isConnected())
      changed.connect(SLOT(this, WComboBox::propagateChange));

  WFormWidget::updateDom(element, all);

  renderOk();
}
Example #9
0
void PaintedSlider::doUpdateDom(DomElement& element, bool all)
{
  if (all) {
    WApplication *app = WApplication::instance();

    element.addChild(createSDomElement(app));
    element.addChild(((WWebWidget *)handle_)->createSDomElement(app));

    DomElement *west = DomElement::createNew(DomElement_DIV);
    west->setProperty(PropertyClass, "Wt-w");
    element.addChild(west);

    DomElement *east = DomElement::createNew(DomElement_DIV);
    east->setProperty(PropertyClass, "Wt-e");
    element.addChild(east);
  }
}
Example #10
0
void WPaintedWidget::updateDom(DomElement& element, bool all)
{
  if ((all && areaImage_) || areaImageAdded_) {
    element.addChild(areaImage_->createSDomElement(WApplication::instance()));
    areaImageAdded_ = false;
  }

  WInteractWidget::updateDom(element, all);
}
Example #11
0
void WProgressBar::updateDom(DomElement& element, bool all)
{
  DomElement *bar = 0, *label = 0;

  if (all) {
    WApplication *app = WApplication::instance();

    bar = DomElement::createNew(DomElement_DIV);
    bar->setId("bar" + id());
    bar->setProperty(PropertyClass, valueStyleClass_);
    app->theme()->apply(this, *bar, ProgressBarBarRole);

    label = DomElement::createNew(DomElement_DIV);
    label->setId("lbl" + id());
    app->theme()->apply(this, *label, ProgressBarLabelRole);
  }

  if (changed_ || all) {
    if (!bar)
      bar = DomElement::getForUpdate("bar" + id(), DomElement_DIV);
    if (!label)
      label = DomElement::getForUpdate("lbl" + id(), DomElement_DIV);

    bar->setProperty(PropertyStyleWidth,
		     boost::lexical_cast<std::string>(percentage()) + "%");

    WString s = text();
    removeScript(s);

    label->setProperty(PropertyInnerHTML, s.toUTF8());

    changed_ = false;
  }

  if (bar)
    element.addChild(bar);

  if (label)
    element.addChild(label);

  WInteractWidget::updateDom(element, all);
}
Example #12
0
DomElement *WTable::createDomElement()
{
  //printDebug();

  DomElement *table = DomElement::createNew(DomElement::TABLE);
  table->setId(this);
  DomElement *tbody = DomElement::createNew(DomElement::TBODY);

  for (unsigned row = 0; row < (unsigned)numRows(); ++row)
    for (unsigned col = 0; col < (unsigned)numColumns(); ++col)
      itemAt(row, col).overSpanned = false;
  
  for (unsigned row = 0; row < (unsigned)numRows(); ++row) {
    DomElement *tr = DomElement::createNew(DomElement::TR);
    tr->setId(rows_[row]);
    
    for (unsigned col = 0; col < (unsigned)numColumns(); ++col) {
      WTableRow::TableData& d = itemAt(row, col);

      if (!d.overSpanned) {
	DomElement *td = d.cell->createSDomElement();
	tr->addChild(td);

	for (int i = 0; i < d.cell->rowSpan(); ++i)
	  for (int j = 0; j < d.cell->columnSpan(); ++j)
	    if (i + j > 0)
	      itemAt(row + i, col + j).overSpanned = true;
      }
    }

    tbody->addChild(tr);
  }

  table->addChild(tbody);

  updateDom(*table, true);

  gridChanged_ = false;

  return table;
}
Example #13
0
void WContainerWidget::createDomChildren(DomElement& parent)
{
  for (unsigned i = 0; i < children().size(); ++i) {
    DomElement *c = children()[i]->webWidget()->createSDomElement();
    parent.addChild(c);
  }

  if (addedChildren_) {
    delete addedChildren_;
    addedChildren_ = 0;
  }
}
Example #14
0
void WImage::updateDom(DomElement& element, bool all)
{
  DomElement *img = &element;
  if (all && element.type() == DomElement_SPAN) {
    DomElement *map = map_->createSDomElement(WApplication::instance());
    element.addChild(map);

    img = DomElement::createNew(DomElement_IMG);
    img->setId("i" + id());
  }

  if (flags_.test(BIT_IMAGE_LINK_CHANGED) || all) {
    if (!imageLink_.isNull()) {
      std::string url = resolveRelativeUrl(imageLink_.url());

      WApplication *app = WApplication::instance();
      url = app->encodeUntrustedUrl(url);

      img->setProperty(Wt::PropertySrc, url);
    } else
      img->setProperty(Wt::PropertySrc, "#");

    flags_.reset(BIT_IMAGE_LINK_CHANGED);
  }

  if (flags_.test(BIT_ALT_TEXT_CHANGED) || all) {
    img->setAttribute("alt", altText_.toUTF8());
    flags_.reset(BIT_ALT_TEXT_CHANGED);
  }

  if (flags_.test(BIT_MAP_CREATED) || (all && map_)) {
    img->setAttribute("usemap", '#' + map_->id());
    flags_.reset(BIT_MAP_CREATED);
  }

  WInteractWidget::updateDom(*img, all);

  if (&element != img)
    element.addChild(img);
}
Example #15
0
void WAbstractMedia::updateMediaDom(DomElement& element, bool all)
{
  // Only if not IE
  if (all && alternative_) {
    element.setAttribute("onerror",
      """if(event.target.error && event.target.error.code=="
      ""   "event.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED){"
      ""  "while (this.hasChildNodes())"
      ""    "if (" WT_CLASS ".hasTag(this.firstChild,'SOURCE')){"
      ""      "this.removeChild(this.firstChild);"
      ""    "}else{"
      ""      "this.parentNode.insertBefore(this.firstChild, this);"
      ""    "}"
      ""  "this.style.display= 'none';"
      """}"
      );
  }
  if (all || flagsChanged_) {
    if ((!all) || flags_.test(PlayerOption::Controls))
      element.setAttribute("controls",
			   flags_.test(PlayerOption::Controls) ? "controls" : "");
    if ((!all) || flags_.test(PlayerOption::Autoplay))
      element.setAttribute("autoplay",
			   flags_.test(PlayerOption::Autoplay) ? "autoplay" : "");
    if ((!all) || flags_.test(PlayerOption::Loop))
      element.setAttribute("loop",
			   flags_.test(PlayerOption::Loop) ? "loop" : "");
  }
  if (all || preloadChanged_) {
    switch (preloadMode_) {
    case MediaPreloadMode::None:
      element.setAttribute("preload", "none");
      break;
    default:
    case MediaPreloadMode::Auto:
      element.setAttribute("preload", "auto");
      break;
    case MediaPreloadMode::Metadata:
      element.setAttribute("preload", "metadata");
      break;
    }
  }

  updateEventSignals(element, all);

  if (all)
    if (alternative_) {
      element.addChild(alternative_->createSDomElement(wApp));
    }
  flagsChanged_ = preloadChanged_ = false;
}
Example #16
0
File: WTable.C Project: DTidd/wt
void WTable::getDomChanges(std::vector<DomElement *>& result,
			   WApplication *app)
{
  DomElement *e = DomElement::getForUpdate(this, domElementType());

  if (!isStubbed() && flags_.test(BIT_GRID_CHANGED)) {
    DomElement *newE = createDomElement(app);
    e->replaceWith(newE);
  } else {
    if (rowsChanged_) {
      for (std::set<WTableRow *>::iterator i = rowsChanged_->begin();
	   i != rowsChanged_->end(); ++i) {
	DomElement *e2 = DomElement::getForUpdate(*i, DomElement_TR);
	(*i)->updateDom(*e2, false);
	result.push_back(e2);
      }

      delete rowsChanged_;
      rowsChanged_ = 0;
    }

    if (rowsAdded_) {
      DomElement *etb = DomElement::getForUpdate(id() + "tb",
						 DomElement_TBODY);
      for (unsigned i = 0; i < static_cast<unsigned>(rowsAdded_); ++i) {
        DomElement *tr = createRowDomElement(rowCount() - rowsAdded_ + i, true, app);
	etb->addChild(tr);
      }

      result.push_back(etb);

      rowsAdded_ = 0;
    }

    if (flags_.test(BIT_COLUMNS_CHANGED)) {
	for (unsigned i = 0; i < columns_.size(); ++i) {
	  DomElement *e2
	    = DomElement::getForUpdate(columns_[i], DomElement_COL);
	  columns_[i]->updateDom(*e2, false);
	  result.push_back(e2);
	}

      flags_.reset(BIT_COLUMNS_CHANGED);
    }

    updateDom(*e, false);
  }

  result.push_back(e);
}
Example #17
0
DomElement *WGroupBox::createDomElement()
{
  DomElement *result = DomElement::createNew(DomElement::FIELDSET);
  result->setId(this);

  DomElement *legend = DomElement::createNew(DomElement::LEGEND);
  legend->setId(formName() + "l");
  legend->setProperty(Wt::PropertyInnerHTML,
		      toUTF8(escapeText(title_.value())));
  result->addChild(legend);

  createDomChildren(*result);

  updateDom(*result, true);

  return result;
}
Example #18
0
void WGroupBox::updateDom(DomElement& element, bool all)
{
  if (all || titleChanged_) {
    DomElement *legend;
    if (all) {
      legend = DomElement::createNew(DomElement_LEGEND);
      legend->setId(id() + "l");
    } else
      legend = DomElement::getForUpdate(id() + "l", DomElement_LEGEND);

    legend->setProperty(Wt::PropertyInnerHTML, escapeText(title_).toUTF8());
    element.addChild(legend);

    titleChanged_ = false;
  }

  WContainerWidget::updateDom(element, all);
}
Example #19
0
DomElement *WGLWidget::createDomElement(WApplication *app)
{
  DomElement *result = nullptr;

  if (!pImpl_) { // no GL support whatsoever
    result = DomElement::createNew(DomElementType::DIV);
    result->addChild(alternative_->createSDomElement(app));
    webGlNotAvailable_ = true;
  } else {
    result = DomElement::createNew(domElementType());
    repaintGL(GLClientSideRenderer::PAINT_GL | GLClientSideRenderer::RESIZE_GL);
  }
  setId(result, app);

  updateDom(*result, true);

  return result;
}
Example #20
0
void WContainerWidget::updateDomChildren(DomElement& parent, WApplication *app)
{
  if (!app->session()->renderer().preLearning() && !layout_) {
    if (parent.mode() == DomElement::ModeUpdate)
      parent.setWasEmpty(wasEmpty());

    if (transientImpl_) {
      std::vector<int> orderedInserts;
      std::vector<WWidget *>& ac = transientImpl_->addedChildren_;

      for (unsigned i = 0; i < ac.size(); ++i)
	orderedInserts.push_back(Utils::indexOf(*children_, ac[i]));

      Utils::sort(orderedInserts);

      int addedCount = transientImpl_->addedChildren_.size();
      int totalCount = children_->size();
      int insertCount = 0;
      for (unsigned i = 0; i < orderedInserts.size(); ++i) {
	int pos = orderedInserts[i];
	
	DomElement *c = (*children_)[pos]->createSDomElement(app);

	if (pos + (addedCount - insertCount) == totalCount)
	  parent.addChild(c);
	else
	  parent.insertChildAt(c, pos + firstChildIndex());

	++insertCount;
      }

      transientImpl_->addedChildren_.clear();
    }
  }

#ifndef WT_NO_LAYOUT
  if (flags_.test(BIT_LAYOUT_NEEDS_UPDATE)) {
    if (layout_)
      layoutImpl()->updateDom(parent);

    flags_.reset(BIT_LAYOUT_NEEDS_UPDATE);
  }
#endif // WT_NO_LAYOUT
}
Example #21
0
void WScrollArea::updateDom(DomElement& element, bool all)
{
  if (widgetChanged_ || all) {
    if (widget_)
      element.addChild(widget_->webWidget()->createDomElement());

    widgetChanged_ = false;
  }

  if (scrollBarChanged_ || all) {
    if ((horizontalScrollBar_->tiesChanged_)
	|| (verticalScrollBar_->tiesChanged_)) {
      horizontalScrollBar_->tiesChanged_ = true;
      verticalScrollBar_->tiesChanged_ = true;
    }
    horizontalScrollBar_->updateDom(element, all);
    verticalScrollBar_->updateDom(element, all);

    scrollBarChanged_ = false;
  }

  if (scrollBarPolicyChanged_ || all) {
    switch (scrollBarPolicy_) {
    case ScrollBarAsNeeded:
      element.setProperty(Wt::PropertyStyleOverflowX, "auto");
      break;
    case ScrollBarAlwaysOff:
      element.setProperty(Wt::PropertyStyleOverflowX, "hidden");
      break;
    case ScrollBarAlwaysOn:
      element.setProperty(Wt::PropertyStyleOverflowX, "scroll");
      break;
    }
    //result->setProperty(Wt::PropertyStyleOverflowY, "auto");

    scrollBarPolicyChanged_ = false;
  }    

  WWebWidget::updateDom(element, all);

  renderOk();
}
Example #22
0
File: WTable.C Project: DTidd/wt
DomElement *WTable::createRowDomElement(int row, bool withIds, WApplication *app)
{
  DomElement *tr = DomElement::createNew(DomElement_TR);
  if (withIds)
    tr->setId(rows_[row]->id());
  rows_[row]->updateDom(*tr, true);

  // because of the mix of addChild() and insertChildAt()
  tr->setWasEmpty(false);
  int spanCounter = 0;

  for (int col = 0; col < columnCount(); ++col) {
    WTableRow::TableData& d = itemAt(row, col);

    if (!d.overSpanned) {
      DomElement *td = d.cell->createSDomElement(app);

      /*
       * So, IE gets confused when doing appendChild() for TH followed by
       * insertCell(-1) for TD. But, we cannot insertChild() for element 0,
       * so we do TH with appendChild, and insertCell(col).
       */
      if (col < headerColumnCount_ || row < headerRowCount_)
	tr->addChild(td);
      else
	tr->insertChildAt(td, col - spanCounter);

      for (int i = 0; i < d.cell->rowSpan(); ++i)
	for (int j = 0; j < d.cell->columnSpan(); ++j)
	  if (i + j > 0) {
	    itemAt(row + i, col + j).overSpanned = true;
	    itemAt(row + i, col + j).cell->setRendered(false);
	  }
    } else {
      spanCounter++;
    }
  }

  return tr;
}
Example #23
0
void WComboBox::updateDom(DomElement& element, bool all)
{
  if (itemsChanged_ || all) {
    if (!all)
      element.removeAllChildren();

    for (int i = 0; i < count(); ++i) {
      DomElement *item = DomElement::createNew(DomElement_OPTION);
      item->setProperty(PropertyValue, boost::lexical_cast<std::string>(i));
      item->setProperty(PropertyInnerHTML,
			escapeText(asString(model_->data(i, modelColumn_)))
			.toUTF8());
      if (isSelected(i))
	item->setProperty(PropertySelected, "true");

      WString sc = asString(model_->data(i, modelColumn_, StyleClassRole));
      if (!sc.empty())
	item->setProperty(PropertyClass, sc.toUTF8());

      element.addChild(item);
    }

    itemsChanged_ = false;
    selectionChanged_ = false;
  }

  if (selectionChanged_) {
    element.setProperty(PropertySelectedIndex,
			boost::lexical_cast<std::string>(currentIndex_));
    selectionChanged_ = false;
  }

  if (!currentlyConnected_
      && (activated_.isConnected() || sactivated_.isConnected())) {
    currentlyConnected_ = true;
    changed().connect(this, &WComboBox::propagateChange);
  }

  WFormWidget::updateDom(element, all);
}
Example #24
0
void FlexLayoutImpl::updateDom(DomElement& parent)
{
  WApplication *app = WApplication::instance();

  DomElement *div = DomElement::getForUpdate(elId_, DomElementType::DIV);

  Orientation orientation = getOrientation();

  std::vector<int> orderedInserts;
  for (unsigned i = 0; i < addedItems_.size(); ++i)
    orderedInserts.push_back(indexOf(addedItems_[i], orientation));

  Utils::sort(orderedInserts);

  int totalStretch = getTotalStretch(orientation);

  for (unsigned i = 0; i < orderedInserts.size(); ++i) {
    int pos = orderedInserts[i];
    DomElement *el = createElement(orientation, pos, totalStretch, app);
    div->insertChildAt(el, pos);
  }

  addedItems_.clear();

  for (unsigned i = 0; i < removedItems_.size(); ++i)
    div->callJavaScript(WT_CLASS ".remove('" + removedItems_[i] + "');",
			true);

  removedItems_.clear();

  WStringStream js;
  js << "layout.adjust(" << grid_.horizontalSpacing_ << ")";
  div->callMethod(js.str());

  parent.addChild(div);
}
Example #25
0
DomElement *WFileUpload::createDomElement(WApplication *app)
{
  DomElement *result = DomElement::createNew(domElementType());
  if (result->type() == DomElement_FORM)
    result->setId(id());
  else
    result->setName(id());

  EventSignal<> *change = voidEventSignal(CHANGE_SIGNAL, false);

  if (fileUploadTarget_) {
    DomElement *i = DomElement::createNew(DomElement_IFRAME);
    i->setProperty(PropertyClass, "Wt-resource");
    i->setProperty(PropertySrc, fileUploadTarget_->url());
    i->setName("if" + id());
    if (app->environment().agentIsIE()) {
      // http://msdn.microsoft.com/en-us/library/ms536474%28v=vs.85%29.aspx
      // HTA's (started by mshta.exe) have a different security model than
      // a normal web app, and therefore a HTA browser does not allow
      // interaction from iframes to the parent window unless this
      // attribute is set. If omitted, this causes the 'uploaded()'
      // signal to be blocked when a Wt app is executed as a HTA.
      i->setAttribute("APPLICATION", "yes");
    }

    DomElement *form = result;

    form->setAttribute("method", "post");
    form->setAttribute("action", fileUploadTarget_->url());
    form->setAttribute("enctype", "multipart/form-data");
    form->setProperty(PropertyStyle, "margin:0;padding:0;display:inline");
    form->setProperty(PropertyTarget, "if" + id());

    /*
     * wrap iframe in an extra span to work around bug in IE which does
     * not set the name use DOM methods
     */
    DomElement *d = DomElement::createNew(DomElement_SPAN);
    d->addChild(i);

    form->addChild(d);

    DomElement *input = DomElement::createNew(DomElement_INPUT);
    input->setAttribute("type", "file");
    if (flags_.test(BIT_MULTIPLE))
      input->setAttribute("multiple", "multiple");
    input->setAttribute("name", "data");
    input->setAttribute("size", boost::lexical_cast<std::string>(textSize_));
    input->setId("in" + id());

    if (!isEnabled())
      input->setProperty(Wt::PropertyDisabled, "true");

    if (change)
      updateSignalConnection(*input, *change, "change", true);

    form->addChild(input);

  } else {
    result->setAttribute("type", "file");
    if (flags_.test(BIT_MULTIPLE))
      result->setAttribute("multiple", "multiple");
    result->setAttribute("size", boost::lexical_cast<std::string>(textSize_));

    if (!isEnabled())
      result->setProperty(Wt::PropertyDisabled, "true");

    if (change)
      updateSignalConnection(*result, *change, "change", true);
  }

  updateDom(*result, true);

  flags_.reset(BIT_ENABLE_AJAX);

  return result;
}
Example #26
0
DomElement *WAbstractMedia::createDomElement(WApplication *app)
{
  DomElement *result = 0;

  if (isInLayout()) {
    // It's easier to set WT_RESIZE_JS after the following code,
    // but if it's not set, the alternative content will think that
    // it is not included in a layout manager. Set some phony function
    // now, which will be overwritten later in this method.
    setJavaScriptMember(WT_RESIZE_JS, "function() {}");
  }

  if (app->environment().agentIsIElt(9) ||
      app->environment().agent() == WEnvironment::MobileWebKitAndroid) {
    // Shortcut: IE misbehaves when it encounters a media element
    result = DomElement::createNew(DomElement_DIV);
    if (alternative_)
      result->addChild(alternative_->createSDomElement(app));
  } else {
    DomElement *media = createMediaDomElement();
    DomElement *wrap = 0;
    if (isInLayout()) {
      media->setProperty(PropertyStylePosition, "absolute");
      media->setProperty(PropertyStyleLeft, "0");
      media->setProperty(PropertyStyleRight, "0");
      wrap = DomElement::createNew(DomElement_DIV);
      wrap->setProperty(PropertyStylePosition, "relative");
    }
    result = wrap ? wrap : media;
    if (wrap) {
      mediaId_ = id() + "_media";
      media->setId(mediaId_);
    } else {
      mediaId_ = id();
    }

    updateMediaDom(*media, true);
    // Create the 'source' elements
    for (std::size_t i = 0; i < sources_.size(); ++i) {
      DomElement *src = DomElement::createNew(DomElement_SOURCE);
      src->setId(mediaId_ + "s" + boost::lexical_cast<std::string>(i));
      renderSource(src, *sources_[i], i + 1 >= sources_.size());
      media->addChild(src);
    }
    sourcesRendered_ = sources_.size();
    sourcesChanged_ = false;

    if (wrap) {
      wrap->addChild(media);
    }
  }

  if (isInLayout()) {
    std::stringstream ss;
    ss <<
      """function(self, w, h) {";
    if (!mediaId_.empty()) {
      ss <<
        ""  "v=" + jsMediaRef() + ";"
        ""  "if (v) {"
	""    "if (w >= 0) "
        ""      "v.setAttribute('width', w);"
        ""    "if (h >= 0) "
	""      "v.setAttribute('height', h);"
        ""  "}";
    }
    if (alternative_) {
      ss <<
        """a=" + alternative_->jsRef() + ";"
        ""  "if (a && a." << WT_RESIZE_JS <<")"
        ""    "a." << WT_RESIZE_JS << "(a, w, h);";
    }
    ss
      <<"}";
    setJavaScriptMember(WT_RESIZE_JS, ss.str());
  }

  setId(result, app);
  updateDom(*result, true);

  if (isInLayout()) {
    result->setEvent(PLAYBACKSTARTED_SIGNAL, std::string());
    result->setEvent(PLAYBACKPAUSED_SIGNAL, std::string());
    result->setEvent(ENDED_SIGNAL, std::string());
    result->setEvent(TIMEUPDATED_SIGNAL, std::string());
    result->setEvent(VOLUMECHANGED_SIGNAL, std::string());
  }

  setJavaScriptMember("mediaId", "'" + mediaId_ + "'");

  return result;
}
Example #27
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);
  }
}
Example #29
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;
}
Example #30
0
void StdGridLayoutImpl2::updateDom(DomElement& parent)
{
  WApplication *app = WApplication::instance();

  if (needConfigUpdate_) {
    needConfigUpdate_ = false;

    DomElement *div = DomElement::getForUpdate(this, DomElement_DIV);

    for (unsigned i = 0; i < addedItems_.size(); ++i) {
      WLayoutItem *item = addedItems_[i];
      DomElement *c = createElement(item, app);
      div->addChild(c);
    }

    addedItems_.clear();

    for (unsigned i = 0; i < removedItems_.size(); ++i)
      parent.callJavaScript(WT_CLASS ".remove('" + removedItems_[i] + "');",
			    true);

    removedItems_.clear();

    parent.addChild(div);

    WStringStream js;
    js << app->javaScriptClass() << ".layouts2.updateConfig('"
       << id() << "',";
    streamConfig(js, app);
    js << ");";

    app->doJavaScript(js.str());
  }

  if (needRemeasure_) {
    needRemeasure_ = false;
    WStringStream js;
    js << app->javaScriptClass() << ".layouts2.setDirty('" << id() << "');";
    app->doJavaScript(js.str());
  }

  if (needAdjust_) {
    needAdjust_ = false;

    WStringStream js;
    js << app->javaScriptClass() << ".layouts2.adjust('" << id() << "', [";

    bool first = true;

    const unsigned colCount = grid_.columns_.size();
    const unsigned rowCount = grid_.rows_.size();

    for (unsigned row = 0; row < rowCount; ++row)
      for (unsigned col = 0; col < colCount; ++col)
	if (grid_.items_[row][col].update_) {
	  grid_.items_[row][col].update_ = false;
	  if (!first)
	    js << ",";
	  first = false;
	  js << "[" << (int)row << "," << (int)col << "]";
	}

    js << "]);";

    app->doJavaScript(js.str());
  }

  const unsigned colCount = grid_.columns_.size();
  const unsigned rowCount = grid_.rows_.size();

  for (unsigned i = 0; i < rowCount; ++i) {
    for (unsigned j = 0; j < colCount; ++j) {
      WLayoutItem *item = grid_.items_[i][j].item_;
      if (item) {
	WLayout *nested = item->layout();
	if (nested)
	  (dynamic_cast<StdLayoutImpl *>(nested->impl()))->updateDom(parent);
      }
    }
  }
}