I am using this example as starting point for my implementation:
https://jgraph.github.io/mxgraph/javascript/examples/constituent.html
My requirement is that user should be able to select constituent component. However, independent movement of constituent element should be avoided. I.e. parent should move along with constituent element.
To enable selection of constituent element, I removed these two method overrides:
graph.selectCellForEvent = function(cell){
}
mxGraphHandler.prototype.getInitialCellForEvent = function(me){
}
I have overridden isCellMovable method to prevent movement of constituent:
graph.isCellMovable = function(cell){
cell.parent === graph.getDefaultParent();
}
This works to an extent since it prevent movement of just the constituent element.
However, I would like to enable movement of constituent and move parent vertex along with it.
Related
I am building large application in Starling and one of my main problems is who should I layout first: the parent or the children?
What is the default behavior in starling and also in flash:
By default Sprite will get his size based on his children after they have been added to stage.
What if I want to layout the children based on the parent? For example: What if I want to set one of the children to be at position of 20 pixels from the bottom, like bottom menu?
In this case I should:
Add the children
Determine their sizes. If you are building your application cross platform, you need to support many screens, and many times you come to have complicate logic for calculating the scale percentage of your components, which is their size.
Determine your size and layout yourself.
now the bottom menu could be layout at 20 pixels from the bottom. Also it doesn't matter if you place this logic inside the bottom menu or it's parent.
But this not always the case, sometimes you want to layout the parent based on his children. A common example if one of the children is the parent background. In this case you should:
Add the background.
Determinate background size and layout it.
Now you can layout the parent.
But what if I got both of the cases? If one of parent children is background and the other is bottom menu? What if the bottom menu got his own background and other children that need to be layouted base on the parent?
What solution can be used so I will not get lost inside all of this, and can Gazman SDK help here?
What you need is to create layout dependencies between all the components. Each Sprite should have an event that tells us when its layouting is complete.
Now if you have some layouting logic inside the parent that cannot start until its background child is complete layouting, you should create a dependency between the background and the parent. The parent should listen to LayoutComplete event from the background and then he can layout himself, and when he complete layouting he can dispatch LayoutComplete event, and now its child bottom menu can layout himself.
You can implement it yourself or use Gazman-SDK that do exactly that. If you choose Gazman-SDK your code will look like this:
public class ParentClass extends Group
{
private var background:Background = new Background();
private var bottomMenu:BottomMenu = new BottomMenu();
override protected function initialize():void
{
// check if not already added to stage
if(!background.parent){
addChild(background);
addChild(bottomMenu);
}
// Create dependency for background. If background have not
// been initialized yet the subscription will succeed
// And this.initialize() will be called again once
// background initialize is complete
if (subscribeForInitilize(background)){
return;
}
// do layouting logic here
}
}
public class BottomMenu extends Group
{
override protected function initialize():void
{
// Create dependency for parent. If parent have not
// been initialized yet the subscription will succeed
// And this.initialize() will be called again once
// parent initialize is complete
if (subscribeForInitilize(parent as Group)){
return;
}
// do layouting logic here
}
}
I'm working on a UI project that requires that the automatic resizing buttons (based on label length) have a focus indicator graphic for keyboard or controller focus. This graphic must obviously scale with the parent as you would imagine.
This causes a problem; the parent clip is 9sliced, and that slicing doesn't fall through to the child Sprites/MovieClips of this clip. The focus indicator needs to be an accessible property because it has to be capable of being turned on or off.
Currently the only solution I can image is an extremely programmatical reimplementation of scale9Grid where I split the focus indicator into 9 and alter the 9 parts' properties any time the parent width/height/scaleX/scaleY is changed. This would also mean turning all 9 parts on and off when that button is focused
Is there any better way than that?
I recommend you create some wrapper class AppButton (or may be you already have one since you have some resizing by label functionality) with method setSkin(skin:MovieClip) (where skin is your MovieClip from the library) and overridden setters for width and height, so you can implement here skin resizing logic in method arrange() that called each time width or height are changed.
Skin can be complex - with other movie clips in children (focus border in your case), so don't use scale9Grid for the hole skin, but set sizes directly to the children with set scale9grid them as well, so your arrange method can be like that:
private function arrange():void
{
var child:DisplayObject;
for(var i:int = 0; i < numChildren; i++)
{
child = getChildAt(i);
child.width = width;
child.height = height;
}
}
It's also worth to make one skin format for button skins in project, so you can use one wrapper for all buttons.
Later you can add more features to this AppButton - switching view states on mouse events, setting text label, animating skins and so.
This approach work for me for many years, we have base ToggleButton and LabelButton extends ToggleButton classes, and extends them in every project with custom skin parsing and arranging.
Is there a way to change the style of the white squares that are used as vertex handles by default when a polyline is set to editable:true?
I can see that changing the stroke of the polyline affects those handle squares, but I'd like to either change the shape of handle (e.g. to a circle), or substitute an image.
The only way I've managed to found is a direct manipulation of DOM elements corresponding to those markers. For instance, they may be selected using
$('div').filter(function() {
return $(this).css('width') == '11px';
})
Probably, more reliable approach is a DOM tree traverse starting from $('.gm-style') element.
I have create a custom contextMenu using AS3 and can apply that to the stage. Any movie clip I place onto the stage does not inherit the contextMenu from the stage, i.e. they display the default contextMenu.
How do I apply my custom contextMenu to every child in my application?
[edit]
This is a simplified version of what I have in my main.as file:
var my_menu:ContextMenu = new ContextMenu();
my_menu.hideBuiltInItems();
var my_copyright = new ContextMenuItem("Copyright - 2012");
my_copyright.enabled = false;
my_copyright.separatorBefore = true;
my_menu.customItems.push(my_copyright);
stage.contextMenu = my_menu;
If I right-click on the stage then I get the copyright. If I add a movieclip (or anything else) to the stage then right-click on that, then I get the default context-menu.
[edit]
I have found the problem, and fixed it. I was adding a background image using stage.addChildAt(mc, 0);. For some reason this removes the context menu. Placing the child at 1 fixes this and allows everything to inherit the contextMenu.
Before: http://richard.parnaby-king.co.uk/examples/stackoverflow/stackoverflow.swf
After: http://richard.parnaby-king.co.uk/examples/stackoverflow/stackoverflow-after.swf
I am changing the purpose of the bounty - can someone explain WHY this happens!?
Ok, so after a bit of testing this is what I have. I can't say it's that definitively, as flash doesn't give the events for right-click, so it's only a guess, but it seems to hold up.
On a side note, you can't add a context menu to the stage, it won't allow it, so the lowest item you can add it to is the document class
When you right-click on a DisplayObject, it'll look for a ContextMenu on that object. It it doesn't find one, it'll continue on up the hierarchy for that object looking for one, stopping when it finds one. Something like this:
stage
- document (has context menu1)
- parent (has context menu2)
- child
- parent2
In this example, if you right click on child, there's no menu, so it looks to parent. Here it finds context menu2 so it shows that. However if you right-click on parent2, there's no menu, so it looks to document and here it finds context menu1.
There seems to be a bit of a hack though when you right-click somewhere else on the stage (i.e. somewhere with no graphics). In this case, as the stage can't have a ContextMenu (or at least you can't set one), it seems to decide to use the context menu of the child at depth 0 (normally the document class).
When you added your background image at depth 0, you were bumping up your document class to depth 1. Your hierarchy now looks something like this:
stage
- bg
- document (has context menu1)
- parent (has context menu2)
- child
- parent2
I'm assuming you're adding your context menu to the document class (in this example context menu1), so unless your document class has some graphics in it, your event would search up to the stage, find no context menu, then try to look for the context menu of child 0 - in this case bg which doesn't have one.
You can test this by drawing something in the graphics object of your document class (or clicking on one of the nested elements). If you right click on the graphics, you'll see your custom menu, even though bg is at depth 0. Alternatively, you can add another menu to bg to see what I mean.
The answer to your why really is subjective to what else you add into the stage & their order.
I could quote 2 points from the adobe live docs relating to the same :
An index of 0 represents the back (bottom) of the display list for
this DisplayObjectContainer object.
If you specify a currently occupied index position, the child object
that exists at that position and all higher positions are moved up one
position in the child list.
I think if you properly analyse all that is added onto the stage, you yourself might get the answer.
try changing stage.contextMenu = my_menu; to just contextMenu = my_menu;
I have a DefaultTreeModel containing a subclass of DefaultMutableTreeNode. I have only overridden isLeaf() to always return true because I lazily load the children when the node is expanded. Then, when the node is collapsed, I remove the children (firing the proper treeNodesRemoved event) because I have unsubscribed from updates from the server.
The problem is that after the user collapses a node and I remove the children, the stupid little expand circle disappears (but clicking that area still works to expand the node). How can I always show the expand control when the children have been removed?
Related: Add 'expand' button to JTree node that has no children?. Is adding a fake child the only way?
The way I did it is I add a fake child and expansion listener when children are removed. When I get notification that the node with fake child is going to be expanded I replace the fake child with actual lazily loaded children.
This way the node always has children and expand control is always presented