views:

198

answers:

1

I'm attempting to create some simple UI components with dojo.gfx. I've managed to extend dojo.gfx.Group, but am out of my depth getting any of the default shapes drawn to the surface. Inspecting the rendered SVG in Firebug, there's rightfully a node but no rect.

The simplified class looks like this:

dojo.provide("gfxui.SimpleButton");

dojo.require("dojox.gfx.shape");//-¿ needed?
dojo.require("dojox.gfx.svg");
dojo.require("dojox.gfx._base");

dojo.declare("gfxui.SimpleButton", dojox.gfx.Group, {
    constructor: function(){
     this.draw();
    },
    draw:function(){
     var bg = this.createRect(this.rect_props);
     //var bg = this.createObject(dojox.gfx.Rect);
    }
}

gfxui.SimpleButton.nodeType = dojox.gfx.Group.nodeType;

dojo.extend(dojox.gfx.Surface, {
    createButton: function(){
     var button = this.createObject(gfxui.SimpleButton, null, true);
     this.add(button);
     return button;
    }
});

And the javascript in the HTML looks like this:

dojo.require("dojox.gfx");
dojo.require("gfxui.SimpleButton");

function init(){
    var g = dojox.gfx;
    var surface = dojox.gfx.createSurface(dojo.byId("gfx_holder"), 800, 280, "#eee");
    var button = container.createButton();
};
dojo.addOnLoad(init);
A: 

I prefer a simple augmentation technique. Below is the content of a script tag:

// let's include gfx (renderer will be selected dynamically)
dojo.require("dojox.gfx");

// useful short names
var d = dojo, g = dojox.gfx;

// our creator function
function createButton(color){
  // let's create our main shape: group
  var group = this.createGroup();
  // add custom properties, if any
  group._rect = group.createRect().
    setShape({x: 5, y: 5, width: 100, height: 30}).
    setStroke("black").
    setFill(color);
  return group;
}

// we want it to be available on groups and surfaces
d.extend(g.Surface, {createButton: createButton});
d.extend(g.Group,   {createButton: createButton});

// let's test the result
dojo.addOnLoad(function(){
  var s = g.createSurface(dojo.byId("surface"), 500, 400),
      b = s.createButton("red");
});

The example above assumes that there is a <div> called "surface".

The augmentation technique works for any renderer regardless its implementation, and uses only published APIs.

Eugene Lazutkin
Yes, this is indeed nice as, you said, it uses only the published gfx API. In the context of creating a small UI library though (prototyping purposes) I would be loosing out on accessing properties with the likes of getBoundingBox and direct matrix manipulation which would be beneficial for doing automatic positioning. Furthermore serialization would be trickier.In the meanwhile though I found it more beneficial to use widgets and let CSS do the positioning work, then draw the interface with gfx as demoed here:http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/gfx/demos/tooltip.html
Linus