30 Dec 2011 3:08 PM #11
I just tried using a ContentPanel wrapped with Draggable instead of a Window as the conversation/cell widget. The problems are:
- Now the user can grab any location in the panel and perform the DnD, I want them to just be able to grab the title bar for DnD.
- Also because of the previous behavior the user cannot select/access any of the content IN the conversation/call because clicking anywhere is seen as the start of a drag operation. For instance there is a scroll panel in the cell...that is impossible to use now. Do I need to capture where the user's mouse is and disable dragable somehow?
- The panel is not resizable. I need them to be able to at least resize via the lower right corner and stretch the panel. Can this be done with a ContentPanel?
30 Dec 2011 3:18 PM #12
If you can paste code that isn't working, I (and other community members) can be of more help...
As mentioned in an earlier post, and in the Draggable javadoc, use the Draggable(Widget,Widget) constructor to specify that the entire ContentPanel can be dragged via the header.
ContentPanel panel = new ContentPanel();
Draggable d = new Draggable(panel, panel.getHeader());
30 Dec 2011 9:21 PM #13
Your suggestion of:
Draggable draggable = new Draggable(contentPanel, contentPanel.getHeader()); draggable.setConstrainClient(true); draggable.setSizeProxyToSource(true); draggable.addDragHandler(gridPanelDragHandler);
30 Dec 2011 9:26 PM #14
I'd highly recomend taking a look at the javadoc for both Draggable and Resizable - if it is unclear, let me know, but it seems clear to me for both of the setters you mention. Otherwise, try turning them off and on, and see what effect each has.
To make something both resizable and draggable, simply create one of each - something like this (config, handlers ommitted for brevity)
ContentPanel panel = new ContentPanel(); Draggable d = new Draggable(panel, panel.getHeader()); Resizable r = new Resizable(panel);//add one or more directions to limit how it can be resized, see the javadocs for details outerPanel.add(panel, ...);
30 Dec 2011 10:44 PM #15
I did try with and without...
Regarding making a content panel drag-able and re-sizable, I now see that I can wrap the same content panel with Draggable and with Resizable but the code seems odd to me, i.e.
private ContentPanel someMethod()
ContentPanel contentPanel = new ContentPanel();
Draggable draggable = new Draggable(contentPanel, contentPanel.getHeader());
Resizable resizable = new Resizable(contentPanel);
draggable & resizable both fall out of scope...not very Java/OO programing norm...one would think that Draggable & Resizable would do nothing in this case ...when you say wrap an object I naturally think the wrapped object must be the input of the next object/method. But although strange code this seems to be working so I will see if I can refine it for my needs.
31 Dec 2011 8:27 AM #16
If you don't yourself maintain a refernce to the object, then yes, it falls out of scope, and _you_ have no way of accessing it, but why should it do nothing? Other code still has references to it - take a look in each of the Resizable and Draggable constructors, and notice how they add handlers to watch for events.
Do you keep references to all event handlers you write? Or do you add them to the component, and leave it at that? This is the same idea.
As for the setters, yes, the defaults are true, which is why i suggested turning them both on and off - from their descriptions in javadoc constrainClient should keep the thing you are dragging within the bounds of the window, and sizeProxyToSource should make the draggable proxy (if any) the same size as the original object. Both setters trindicate that the default is true already.
31 Dec 2011 8:59 AM #17
Yes I see the constructors do a lot of work...but they shouldn't IMHO. Just like event listeners you don't expect to pass something into its constructor you expect to create the event listener instance and attach it to something...then it's up to you if you keep a reference to the object. E.g.
ContentPanel panel = new ContentPanel(); Draggable d = new Draggable(panel, panel.getHeader()); Resizable r = new Resizable(panel); outerPanel.add(panel, ...);
ContentPanel panel = new ContentPanel(); panel.supportDraggable(new Draggable(...)); panel.supportResizable(new Resizable(...)); outerPanel.add(panel, ...);
ContentPanel panel = new ContentPanel(new Draggable(...), new Resizable(...)); outerPanel.add(panel, ...);
31 Dec 2011 9:49 AM #18
We're straying significantly from the discussion at hand, but there are a few reasons that will make things worse. First, you'll be multiplying the number of args required to create the thing - and you'll need to find some common interface all of these will adhere to, which may have the effect of just changing
ContentPanel panel = new ContentPanel(); Draggable d = new Draggable(panel, panel.getHeader()); new Draggable(panel, panel.getHeader()); new Resizable(panel, Dir.N, Dir.E, Dir.S, Dir.W);
ContentPanel panel = new ContentPanel(); //need to still specify the header is the actual draggable part //hypothetical Behavior interface would specify some way to indicate the compoent that gets the behavior panel.addBehavior(new Draggable(panel.getHeader())); panel.addBehavior(new Resizable(Dir.N, Dir.E, Dir.S, Dir.W);
We're far enough into GXT 3 that I don't think major modifications will be made at this time to how these are working, especially as Draggable and Resizable are mostly unchanged from 2.x (and 1.x I believe) - philosophical discussions of perfect APIs aside, they do the job more than adaquetly. Keep in mind that holding a reference to these can be very beneficial across the life of the object - both classes have a release() method to remove handlers and prevent the effect from continuing. Additionally, if one of these is attached to a detached ContentPanel (or any Widget), and the only reference to it are from the Resizable/Draggable, it will be garbarge collected, thanks to GWT's dom event listener bookkeeping occuring on detach.
That said, if you have a complete suggestion to how this can be built while still supporting all existing use cases, we'd be interested in discussing it. Feel free to join us on irc.freenode.net at #extgwt for more discussion.
31 Dec 2011 10:19 AM #19
I concur we are straying now from the topic but...
My point here is basically that the way things are now may work, like you say, but the problem is it's not intuitive from an API perspective. Now the things are completely decoupled and that can have some advantages but it requires deep knowledge of the GXT library to know how to get things to work. Normally one expects to see methods on objects (or constructor params) that provide all the functionality one can do with an object. Furthermore there is a setResize() method on ContentPanel that does absolutely nothing (from what I can tell), so not knowing that a separate decoupled Resizable existed I switched to using a Window instead of ContentPanel because it in the the resizing worked as expected. How is one to know that resizing is completely decoupled? What other completely decoupled things am I missing? Again, for new folks using a library the natural thing to do is start with an object and look to its methods to know what it can and can't do, not browse for all completely decoupled objects and see if I can combine them somehow.
31 Dec 2011 11:01 AM #20
SimpleContainer.setResize/isResize should be used by doLayout, but this seems to not be called as normal due to how ContentPanel.onResize overrides things. I'll look into how that should behave. However, if you look at the setResize javadoc, it clearly has nothing to do with the user resizing and dragging:
True to resize the child widget to match the container size (defaults to true).