Example #1
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 #2
0
void WWidgetCanvasPainter::createContents(DomElement *result,
					  WPaintDevice *device)
{
  std::string wstr = boost::lexical_cast<std::string>(widget_->renderWidth_);
  std::string hstr = boost::lexical_cast<std::string>(widget_->renderHeight_);

  result->setProperty(PropertyStylePosition, "relative");
  result->setProperty(PropertyStyleOverflowX, "hidden");
  result->setProperty(PropertyStyleOverflowY, "hidden");

  DomElement *canvas = DomElement::createNew(DomElement_CANVAS);
  canvas->setId('c' + widget_->id());
  canvas->setProperty(PropertyStyleDisplay, "block");
  canvas->setAttribute("width", wstr);
  canvas->setAttribute("height", hstr);
  result->addChild(canvas);
  widget_->sizeChanged_ = false;

  WCanvasPaintDevice *canvasDevice = dynamic_cast<WCanvasPaintDevice *>(device);

  DomElement *text = 0;
  if (canvasDevice->textMethod() == WCanvasPaintDevice::DomText) {
    text = DomElement::createNew(DomElement_DIV);
    text->setId('t' + widget_->id());
    text->setProperty(PropertyStylePosition, "absolute");
    text->setProperty(PropertyStyleZIndex, "1");
    text->setProperty(PropertyStyleTop, "0px");
    text->setProperty(PropertyStyleLeft, "0px");
  }

  DomElement *el = text ? text : result;
  bool hasJsObjects = widget_->jsObjects_.size() > 0;

  if (hasJsObjects) {
    WStringStream ss;
    WApplication *app = WApplication::instance();
    ss << "new " WT_CLASS ".WPaintedWidget("
      << app->javaScriptClass() << "," << widget_->jsRef() << ");";
    widget_->jsObjects_.updateJs(ss);
    el->callJavaScript(ss.str());
  }

  canvasDevice->render('c' + widget_->id(), el);

  if (hasJsObjects) {
    WStringStream ss;
    ss << widget_->objJsRef() << ".repaint=function(){";
    ss << canvasDevice->recordedJs_.str();
    ss << "};";
    el->callJavaScript(ss.str());
  }

  if (text)
    result->addChild(text);

  delete device;
}
Example #3
0
void WTextEdit::updateDom(DomElement& element, bool all)
{
  WTextArea::updateDom(element, all);

  if (element.type() == DomElement_TEXTAREA)
    element.removeProperty(PropertyStyleDisplay);

  // we are creating the actual element
  if (all && element.type() == DomElement_TEXTAREA) {
    std::stringstream config;
    config << "{";

    bool first = true;

    for (SettingsMapType::const_iterator it = configurationSettings_.begin();
	 it != configurationSettings_.end(); ++it) {
      if (it->first == "plugins")
	continue;

      if (!first)
	config << ',';

      first = false;

      config << it->first << ": "
	     << Impl::asJSLiteral(it->second, XHTMLUnsafeText);
    }

    if (!first)
      config << ',';

    config << "plugins: '" << plugins() << "'";

    config <<
      ",init_instance_callback: obj.init"
      "}";

    DomElement dummy(DomElement::ModeUpdate, DomElement_TABLE);
    updateDom(dummy, true);

    element.callJavaScript("(function() { "
			   """var obj = $('#" + id() + "').data('obj');"
			   """obj.render(" + config.str() + ","
			   + jsStringLiteral(dummy.cssStyle()) + ","
			   + (changed().isConnected() ? "true" : "false")
			   + ");"
			   "})();");

    contentChanged_ = false;
  }

  if (!all && contentChanged_) {
    element.callJavaScript(jsRef() + ".ed.load();");
    contentChanged_ = false;
  }
}
Example #4
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);
}
Example #5
0
void WWidgetCanvasPainter::updateContents(std::vector<DomElement *>& result,
					  WPaintDevice *device)
{
  WCanvasPaintDevice *canvasDevice = dynamic_cast<WCanvasPaintDevice *>(device);

  if (widget_->sizeChanged_) {
    DomElement *canvas = DomElement::getForUpdate('c' + widget_->id(),
						  DomElement_CANVAS);
    canvas->setAttribute("width",
		 boost::lexical_cast<std::string>(widget_->renderWidth_));
    canvas->setAttribute("height",
		 boost::lexical_cast<std::string>(widget_->renderHeight_));
    result.push_back(canvas);

    widget_->sizeChanged_ = false;
  }

  bool domText = canvasDevice->textMethod() == WCanvasPaintDevice::DomText;

  DomElement *el
    = DomElement::getForUpdate(domText ? 't' + widget_->id() : widget_->id(),
			       DomElement_DIV);
  if (domText)
    el->removeAllChildren();

  bool hasJsObjects = widget_->jsObjects_.size() > 0;

  if (hasJsObjects) {
    WStringStream ss;
    widget_->jsObjects_.updateJs(ss);
    el->callJavaScript(ss.str());
  }

  canvasDevice->render('c' + widget_->id(), el);

  if (hasJsObjects) {
    WStringStream ss;
    ss << widget_->objJsRef() << ".repaint=function(){";
    ss << canvasDevice->recordedJs_.str();
    ss << "};";
    el->callJavaScript(ss.str());
  }

  result.push_back(el);

  delete device;
}
Example #6
0
void WFormWidget::updateDom(DomElement& element, bool all)
{
  const WEnvironment& env = WApplication::instance()->environment();

  bool onChangeHandledElsewhere = dynamic_cast<WAbstractToggleButton *>(this);

  if (!onChangeHandledElsewhere) {
    EventSignal<> *s = voidEventSignal(CHANGE_SIGNAL, false);
    if (s)
      updateSignalConnection(element, *s, "change", all);
  }

  if (flags_.test(BIT_ENABLED_CHANGED) || all) {
    if (!all || !isEnabled())
      element.setProperty(Wt::PropertyDisabled,
			  isEnabled() ? "false" : "true");

    if (!all && isEnabled() && env.agentIsIE()) {
      /*
       * FIXME: implement a workaround for IE, reenabling a checkbox makes
       * the input box loose interactivity.
       */
    }
    flags_.reset(BIT_ENABLED_CHANGED);
  }

  if (flags_.test(BIT_READONLY_CHANGED) || all) {
    if (!all || isReadOnly())
      element.setProperty(Wt::PropertyReadOnly,
			  isReadOnly() ? "true" : "false");
    flags_.reset(BIT_READONLY_CHANGED);
  }

  if (flags_.test(BIT_TABINDEX_CHANGED) || all) {
    if (!all || tabIndex_)
      element.setProperty(PropertyTabIndex,
			  boost::lexical_cast<std::string>(tabIndex_));
    flags_.reset(BIT_TABINDEX_CHANGED);
  }

  if (isEnabled()) {
    if (all && flags_.test(BIT_GOT_FOCUS))
      flags_.set(BIT_INITIAL_FOCUS);

    if (flags_.test(BIT_GOT_FOCUS)
	|| (all && flags_.test(BIT_INITIAL_FOCUS))) {
      element.callJavaScript("setTimeout(function() {"
			     """var f = " + jsRef() + ";"
			     """if (f) try { f.focus(); } catch (e) { } }, "
			     + (env.agentIsIElt(9) ? "500" : "10") + ");");

      flags_.reset(BIT_GOT_FOCUS);
    }
  }

  WInteractWidget::updateDom(element, all);
}
Example #7
0
File: Widget.C Project: ReWeb3D/wt
DomElement *Widget::createDomElement(WApplication *app)
{
  DomElement *result = DomElement::createNew(domElementType());
  setId(result, app);

  std::stringstream js;
  createExtElement(js, result);
  result->callJavaScript(js.str());

  return result;
}
Example #8
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 #9
0
File: Widget.C Project: ReWeb3D/wt
void Widget::getDomChanges(std::vector<DomElement *>& result,
			   WApplication *app)
{
  std::string el = elRef() + ".el.dom";

  DomElement *e = DomElement::updateGiven(el, domElementType());

  updateExt();

  if (!jsUpdates_.empty()) {
    e->callJavaScript("var " + elVar() + "=" + elRef() + ";" + jsUpdates_);
    jsUpdates_.clear();
  }

  updateDom(*e, false);
  e->removeProperty(PropertyStyleDisplay);
  result.push_back(e);
}
Example #10
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 #11
0
void WAnchor::updateDom(DomElement& element, bool all)
{
  if (element.type() != DomElement_A) {
    WContainerWidget::updateDom(element, all);
    return;
  }

  if (flags_.test(BIT_CHANGE_TAG)) {
    if (!all)
      element.callJavaScript(WT_CLASS ".changeTag(" + jsRef() + ",'a');");

    flags_.reset(BIT_CHANGE_TAG);
  }

  bool needsUrlResolution = false;

  if (flags_.test(BIT_LINK_CHANGED) || all) {
    WApplication *app = WApplication::instance();

    std::string url = link_.resolveUrl(app);

    /*
     * From 但浩亮: setRefInternalPath() and setTarget(TargetNewWindow)
     * does not work without the check below:
     */
    if (target_ == TargetSelf)
      changeInternalPathJS_
	= link_.manageInternalPathChange(app, this, changeInternalPathJS_);
    else {
      delete changeInternalPathJS_;
      changeInternalPathJS_ = 0;
    }

    url = app->encodeUntrustedUrl(url);

    std::string href = resolveRelativeUrl(url);
    element.setAttribute("href", href);

    needsUrlResolution = !app->environment().hashInternalPaths()
      && href.find("://") == std::string::npos && href[0] != '/';

    flags_.reset(BIT_LINK_CHANGED);
  }

  if (flags_.test(BIT_TARGET_CHANGED) || all) {
    switch (target_) {
    case TargetSelf:
      if (!all)
	element.setProperty(PropertyTarget, "_self");
      break;
    case TargetThisWindow:
      element.setProperty(PropertyTarget, "_top");
      break;
    case TargetNewWindow:
      element.setProperty(PropertyTarget, "_blank");
    }
    flags_.reset(BIT_TARGET_CHANGED);
  }

  WContainerWidget::updateDom(element, all);

  if (needsUrlResolution) {
    if (all)
      element.setProperty(PropertyClass,
			  Utils::addWord(styleClass().toUTF8(), "Wt-rr"));
    else
      element.callJavaScript("$('#" + id() + "').addClass('Wt-rr');");
  }
}
Example #12
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 #13
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);
      }
    }
  }
}
Example #14
0
void WGLWidget::updateDom(DomElement &element, bool all)
{
  if (webGlNotAvailable_)
    return;

  DomElement *el = &element;
  if (all || sizeChanged_) {
    el->setAttribute("width", boost::lexical_cast<std::string>(renderWidth_));
    el->setAttribute("height", boost::lexical_cast<std::string>(renderHeight_));
    sizeChanged_ = false;
  }
  if (updateGL_ || updateResizeGL_ || updatePaintGL_) {
    std::stringstream tmp;
    tmp <<
      "var o = " << glObjJsRef() << ";\n"
      "if(o.ctx){\n";
    if (updateGL_) {
      js_.str("");
      updateGL();
      tmp << "var update =function(){\n"
        "var obj=" << glObjJsRef() << ";\n"
        "var ctx=obj.ctx;if (!ctx) return;\n"
        << js_.str() << "\n};\n"
        // cannot execute updates before initializeGL is executed
        "o.updates.push(update);";
    }
    if (updateResizeGL_) {
      js_.str("");
      resizeGL(renderWidth_, renderHeight_);
      tmp << "o.resizeGL=function(){\n"
        "var obj=" << glObjJsRef() << ";\n"
        "var ctx=obj.ctx;if (!ctx) return;\n"
        << js_.str() << "};";
    }
    if (updatePaintGL_) {
      js_.str("");
      paintGL();
      // TG: cannot overwrite paint before update is executed
      // therefore overwrite paintgl in a deferred function through the
      // tasks queue
      tmp << "var updatePaint = function(){\n";
      tmp << "var obj=" << glObjJsRef() << ";\n";

      tmp << "obj.paintGL=function(){\n"
        "var obj=" << glObjJsRef() << ";\n"
        "var ctx=obj.ctx;if (!ctx) return;\n"
        << js_.str() << "};";

      tmp << "};\n";
      tmp << "o.updates.push(updatePaint);";


    }
    js_.str("");
    // Make sure textures are loaded before we render
    tmp << "}\n";

    // Preloading images and buffers
    const bool preloadingSomething = preloadImages_.size()>0 || preloadArrayBuffers_.size() >0;

    if (preloadingSomething)  {
      if (preloadImages_.size() > 0) {
	tmp <<
	  //"debugger;"
	  "o.preloadingTextures++;"
	  "new Wt._p_.ImagePreloader([";
	for (unsigned i = 0; i < preloadImages_.size(); ++i) {
	  if (i != 0)
	    tmp << ',';
	  tmp << '\'' << resolveRelativeUrl(preloadImages_[i].second) << '\'';
	}
	tmp <<
	  "],function(images){\n"
	  //"debugger;\n"
	  "var o=" << glObjJsRef() << ";\n"
	  "var ctx=null;\n"
	  "if(o) ctx=o.ctx;\n"
	  "if(ctx == null) return;\n";
	for (unsigned i = 0; i < preloadImages_.size(); ++i) {
	  std::string texture = preloadImages_[i].first;
	  tmp << texture << "=ctx.createTexture();\n"
	    << texture << ".image=images[" << i << "];\n";
	}
	tmp << "o.preloadingTextures--;\n"
	  << "o.handlePreload();\n"
	  << "});";

	preloadImages_.clear();
      }

      // now check for buffers to preload
      if (preloadArrayBuffers_.size() > 0) {
	tmp <<
	  "o.preloadingBuffers++;"
	  "new Wt._p_.ArrayBufferPreloader([";
	for (unsigned i = 0; i < preloadArrayBuffers_.size(); ++i) {
	  if (i != 0)
	    tmp << ',';
	  //preloadingStream << '\'' << resolveRelativeUrl(preloadBufferResources_[i].second) << '\'';
	  tmp << '\'' << wApp->makeAbsoluteUrl(preloadArrayBuffers_[i].second) << '\'';
	}
	tmp <<
	  "],function(bufferResources){\n"
	  //"debugger;\n"
	  "var o=" << glObjJsRef() << ";\n"
	  "var ctx=null;\n"
	  " if(o) ctx=o.ctx;\n"
	  "if(ctx == null) return;\n";
	for (unsigned i = 0; i < preloadArrayBuffers_.size(); ++i) {
	  std::string bufferResource = preloadArrayBuffers_[i].first;
	  // setup datatype
	  tmp << bufferResource << "={data:0};\n";
	  // set the data
	  tmp << bufferResource << ".data=bufferResources[" << i << "];\n";
	}
	tmp << "o.preloadingBuffers--;"
	  << "o.handlePreload();\n"
	  << "});";

	preloadArrayBuffers_.clear();
      }
    } else {
      // No textures or buffers to load - go and paint
      tmp << "o.handlePreload();";
    }
    el->callJavaScript(tmp.str());
    updateGL_ = updatePaintGL_ = updateResizeGL_ = false;
  }

  WInteractWidget::updateDom(element, all);
}
Example #15
0
void WGLWidget::updateDom(DomElement &element, bool all)
{
  if (webGlNotAvailable_)
    return;

  DomElement *el = &element;
  if (all || sizeChanged_) {
    el->setAttribute("width", boost::lexical_cast<std::string>(renderWidth_));
    el->setAttribute("height", boost::lexical_cast<std::string>(renderHeight_));
    sizeChanged_ = false;
  }
  if (updateGL_ || updateResizeGL_ || updatePaintGL_) {
    std::stringstream tmp;
    tmp <<
      "var o = " << glObjJsRef() << ";\n"
      "if(o.ctx){\n";
    if (updateGL_) {
      js_.str("");
      updateGL();
      tmp << "var update =function(){\n"
        "var obj=" << glObjJsRef() << ";\n"
        "var ctx=obj.ctx;if (!ctx) return;\n"
        << js_.str() << "\n};\n"
        // cannot execute updates before initializeGL is executed
        "o.updates.push(update);";
    }
    if (updateResizeGL_) {
      js_.str("");
      resizeGL(renderWidth_, renderHeight_);
      tmp << "o.resizeGL=function(){\n"
        "var obj=" << glObjJsRef() << ";\n"
        "var ctx=obj.ctx;if (!ctx) return;\n"
        << js_.str() << "};";
    }
    if (updatePaintGL_) {
      js_.str("");
      paintGL();
      tmp << "o.paintGL=function(){\n"
        "var obj=" << glObjJsRef() << ";\n"
        "var ctx=obj.ctx;if (!ctx) return;\n"
        << js_.str() << "};";
    }
    js_.str("");
    // Make sure textures are loaded before we render
    tmp << "}\n";
    if (preloadImages_.size() > 0) {
      //tmp << "debugger;\n";
      tmp <<
        "o.preloadingTextures=true;"
        "new Wt._p_.ImagePreloader([";
      for (unsigned i = 0; i < preloadImages_.size(); ++i) {
        if (i != 0)
          tmp << ',';
        tmp << '\'' << resolveRelativeUrl(preloadImages_[i].second) << '\'';
      }
      tmp <<
        "],function(images){\n"
        "var o=" << glObjJsRef() << ";\n"
        "var ctx=null;\n"
        " if(o) ctx=o.ctx;\n"
        "o.preloadingTextures=false;"
        "if(ctx == null) return;\n";
      for (unsigned i = 0; i < preloadImages_.size(); ++i) {
        std::string texture = preloadImages_[i].first;
        tmp << texture << "=ctx.createTexture();\n"
          << texture << ".image=images[" << i << "];\n";
      }
      tmp <<
        "if(o.initialized){"
        // Delay calling of update() to after textures are loaded
        """var key;"
        """for(key in o.updates) o.updates[key]();"
        """o.updates = new Array();"
        // Delay calling of resizeGL() to after updates are executed
        """o.resizeGL();"
        """o.paintGL();"
        "} else {"
        // initializeGL will call updates and resizeGL
        """o.initializeGL();\n"
        """o.resizeGL();\n"
        """o.paintGL();\n"
        "}});";
      preloadImages_.clear();
    } else {
      // No textures to load - go and paint
      tmp <<
        "if(!o.preloadingTextures){"
        // It's not ok to execute an update method or initialize if we're
        // waiting for texture to load; this will result in undefined
        // symbols in JS. After textures are loaded, the code sequence below
        // is executed from there.
        """if(o.initialized) {"
        ""  "var key;"
        ""  "for(key in o.updates) o.updates[key]();"
        ""  "o.updates = new Array();"
        ""  "o.resizeGL();"
        ""  "o.paintGL();"
        """} else {"
        ""  "o.initializeGL();"
        ""  "o.resizeGL();"
        ""  "o.paintGL();"
        """}"
        "}";
    }
    el->callJavaScript(tmp.str());
    updateGL_ = updatePaintGL_ = updateResizeGL_ = false;
  }

  WInteractWidget::updateDom(element, all);
}
Example #16
0
void WFormWidget::updateDom(DomElement& element, bool all)
{
  const WEnvironment& env = WApplication::instance()->environment();

  bool onChangeHandledElsewhere = dynamic_cast<WAbstractToggleButton *>(this);

  if (!onChangeHandledElsewhere) {
    EventSignal<> *s = voidEventSignal(CHANGE_SIGNAL, false);
    if (s)
      updateSignalConnection(element, *s, "change", all);
  }

  if (flags_.test(BIT_ENABLED_CHANGED) || all) {
    if (!all || !isEnabled())
      element.setProperty(Wt::PropertyDisabled,
			  isEnabled() ? "false" : "true");

    if (!all && isEnabled() && env.agentIsIE()) {
      /*
       * FIXME: implement a workaround for IE, reenabling a checkbox makes
       * the input box loose interactivity.
       */
    }
    flags_.reset(BIT_ENABLED_CHANGED);
  }

  if (flags_.test(BIT_READONLY_CHANGED) || all) {
    if (!all || isReadOnly())
      element.setProperty(Wt::PropertyReadOnly,
			  isReadOnly() ? "true" : "false");
    flags_.reset(BIT_READONLY_CHANGED);
  }

  if (flags_.test(BIT_TABINDEX_CHANGED) || all) {
    if (!all || tabIndex_)
      element.setProperty(PropertyTabIndex,
			  boost::lexical_cast<std::string>(tabIndex_));
    flags_.reset(BIT_TABINDEX_CHANGED);
  }

  if (flags_.test(BIT_GOT_FOCUS)) {
    WApplication *app = WApplication::instance();

    element.callJavaScript("setTimeout(function() {"
			   """var o = " + jsRef() + ";"
			   """if (o) {"
			   ""   "if (!$(o).hasClass('" +
			         app->theme()->disabledClass() + "')) {"
			   ""      "try { "
			   ""          "o.focus();"
			   ""      "} catch (e) {}"
			   ""   "}"
			   """}"
			   "}, " + (env.agentIsIElt(9) ? "500" : "10") + ");");

    flags_.reset(BIT_GOT_FOCUS);
  }

  WInteractWidget::updateDom(element, all);

  if (flags_.test(BIT_VALIDATION_CHANGED)) {
    if (validationToolTip_.empty())
      element.setAttribute("title", toolTip().toUTF8());
    else
      element.setAttribute("title", validationToolTip_.toUTF8());
  }
}