2. Declare in binder implementation Map with values of attributes.
public final java.util.Map wbpAttributes = new
java.util.HashMap();
and fill it, here is example if code generated for ui.xml above
if (wbpObjectHandler != null) wbpObjectHandler.handle("0/1/0",
f_Button2);
f_Button2.setText("New Button");
wbpAttributes.put("0/1/0 text", "New Button");
f_FlowPanel1.add(f_Button2);
if (wbpObjectHandler != null) wbpObjectHandler.handle("0/1",
f_FlowPanel1);
f_FlowPanel1.setStyleName("" + style.panel() + "");
GWT Designer needs to know attribute values to show them to user in
properties table. Not all properties have getter, so we can not get
these values for existing Widget object.
3. In special parsers for panels, remember also values of attributes
for artificial elements. For example "Cell" in CellPanelParser (and
"Dock" in DockPanel).
// Parse horizontal and vertical alignment attributes.
if (cellElem.hasAttribute(HALIGN_ATTR)) {
String value = cellElem.consumeAttribute(HALIGN_ATTR,
hAlignConstantType);
writer.addStatement("%1$s.setCellHorizontalAlignment(%2$s,
%3$s);",
fieldName, childFieldName, value);
//XXX <Instantiations
writer.addStatement("wbpAttributes.put(\"%s\", %s);",
widgetElem.getPath() + " Cell." + HALIGN_ATTR, value);
//XXX >Instantiations
}
4. To allow quick updates of design canvas as user changes properties,
without reloading GWT context each time, we should:
4.1. Generate Binder implementation class with new name each time, so
be able to define each time new class in same ClassLoader. Right now
we just add current time to the name of class.
//XXX <Instantiations
// generate class with new name each time, to allow refresh in
same ClassLoader
implName += "_wbp" + System.currentTimeMillis();
//XXX >Instantiations
4.2. To parse/render UI.XML file content without saving, i.e. from
memory/editor, generate should try to read document from memory.
Something like this:
private Document getW3cDoc(MortalLogger logger, String templatePath)
throws UnableToCompleteException {
//XXX <Instantiations
{
String content = System.getProperty("wbp.gwt.UiBinder " +
templatePath);
if (content != null) {
Document doc = null;
try {
doc = new
W3cDomHelper(logger.getTreeLogger()).documentFor(content);
} catch (SAXParseException e) {
logger.die("Error parsing XML (line " + e.getLineNumber() +
"): "
+ e.getMessage() + " " + content, e);
} catch (Throwable e) {
logger.die("Error parsing XML " + content, e);
}
return doc;
}
}
//XXX >Instantiations
URL url =
UiBinderGenerator.class.getClassLoader().getResource(templatePath); //
this is default implementation
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors
What does WBP stand for?
Path in XML is "/" separated string of indexes.
For example in
<ui:UiBinder>
<ui:style/>
<g:FlowPanel styleName="{style.panel}">
<g:Button text="New Button"/>
</g:FlowPanel>
</ui:UiBinder>
"0/1" is FlowPanel
"0/1/0" is ButtonThis doesn't sound like a tooling hook, it sounds like a data binding framework, and a very run time one — not really how we like to do things, and not how we're gearing up to write our own data binding support this month.What is the model object we're talking about? Does GWT designer impose a particular architecture on its users, or is it an implementation detail of designer itself?
I'd be a lot more comfortable with hooks that happen at code generation time, e.g. to allow you to navigate the model binder builds before things get written to disk.
4. To allow quick updates of design canvas as user changes properties,
without reloading GWT context each time, we should:
4.1. Generate Binder implementation class with new name each time, so
be able to define each time new class in same ClassLoader. Right now
we just add current time to the name of class.
//XXX <Instantiations
// generate class with new name each time, to allow refresh in
same ClassLoader
implName += "_wbp" + System.currentTimeMillis();
//XXX >InstantiationsWe could not do this with a timestamp, as it's important that the same code always produce the same binary. Would appending an md5 sum to the class name do the trick?
What does WBP stand for?
WBP is acronym for "WindowBuilder Pro" - set of plugins for Eclipse for WYSIWYG development of GUI for Swing, SWT, RCP, XWT and GWT.
Path in XML is "/" separated string of indexes.
For example in
<ui:UiBinder>
<ui:style/>
<g:FlowPanel styleName="{style.panel}">
<g:Button text="New Button"/>
</g:FlowPanel>
</ui:UiBinder>
"0/1" is FlowPanel
"0/1/0" is ButtonThis doesn't sound like a tooling hook, it sounds like a data binding framework, and a very run time one — not really how we like to do things, and not how we're gearing up to write our own data binding support this month.What is the model object we're talking about? Does GWT designer impose a particular architecture on its users, or is it an implementation detail of designer itself?
GWT Designer is tool for WYSIWYG building of GWT UI, which development I lead at Instantiations.
Its latest release works only with Java source for GWT, but now I work on UiBinder support too and many things already work.
This is absolutely not related to databinding, we just want to produce GUI builder for UiBinder.
I think that tooling was specified as one of the reasons to use XML for GWT UI. So, this is on what I work now. :-)
In method createAndBindUi() directly after creating each Widget instance (but before applying setX() methods) "wbpObjectHandler" is used to notify GWT Designer about new widget and its path in XML. GWT Designer bind Widget instance to model (using path) and also asks default values for all properties using getX() methods.
I'd be a lot more comfortable with hooks that happen at code generation time, e.g. to allow you to navigate the model binder builds before things get written to disk.
Note, that nothing is going to be written on disk, because we speak only about design time.
For design time we use tweaked "dev" code, what we call "hosted mode support", which we use to create CompilingClassLoader. And for design time we don't write any output of generators on disk. Users don't need this at design time.
And any such "wbp" related code (note, this is just current name, we could use for example "designTime" prefix) will be generated only if Beans.isDesignTime() is set to true. Nothing will be generated for "dev mode" or "deploy mode".
4. To allow quick updates of design canvas as user changes properties,
without reloading GWT context each time, we should:
4.1. Generate Binder implementation class with new name each time, so
be able to define each time new class in same ClassLoader. Right now
we just add current time to the name of class.
//XXX <Instantiations
// generate class with new name each time, to allow refresh in
same ClassLoader
implName += "_wbp" + System.currentTimeMillis();
//XXX >InstantiationsWe could not do this with a timestamp, as it's important that the same code always produce the same binary. Would appending an md5 sum to the class name do the trick?
Well, I hope that now it is clear that nothing is going to be "produced" with such "design time" tweaks.
At these modes generated code will be exactly same as it is now.
This is absolutely not related to databinding, we just want to produce GUI builder for UiBinder.
I think that tooling was specified as one of the reasons to use XML for GWT UI. So, this is on what I work now. :-)
Well that makes a lot more sense. :-)It occurs to me that this could be a lot easier when we revive r7816, which I had to roll back (r7858) due to its naive handling of tables. If we make the paths the binder builds part of its public api, you could have your map and we wouldn't have to think as hard about hiding design time hooks from developers, or at least not all of them. Certainly, you shouldn't make your changes before that code comes back (and it really, really needs to come back).
In your original note you suggested:In method createAndBindUi() directly after creating each Widget instance (but before applying setX() methods) "wbpObjectHandler" is used to notify GWT Designer about new widget and its path in XML. GWT Designer bind Widget instance to model (using path) and also asks default values for all properties using getX() methods.Why do you need this notice before the set calls?
4. To allow quick updates of design canvas as user changes properties,
without reloading GWT context each time, we should:
4.1. Generate Binder implementation class with new name each time, so
be able to define each time new class in same ClassLoader. Right now
we just add current time to the name of class.
//XXX <Instantiations
// generate class with new name each time, to allow refresh in
same ClassLoader
implName += "_wbp" + System.currentTimeMillis();
//XXX >InstantiationsWe could not do this with a timestamp, as it's important that the same code always produce the same binary. Would appending an md5 sum to the class name do the trick?
Well, I hope that now it is clear that nothing is going to be "produced" with such "design time" tweaks.
At these modes generated code will be exactly same as it is now.
But if we can avoid having alternative behavior at design time life is simpler. Would check sums on the generated class names meet that need?