Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Drag and Drop in Canvas

    In the attached image, I am trying to drag and drop an "event" between tracks. But dragging the event causes the track to resize rather than moving between tracks. I need a canvas rather than a layout because the user can position the event within the canvas. I have drag and drop working in other projects without the layout changing size but am missing some setting here.
    Code:
    package edu.iastate.its.thinkspace.mycase.client.events;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.smartgwt.client.types.VerticalAlignment;
    import com.smartgwt.client.util.EventHandler;
    import com.smartgwt.client.widgets.Canvas;
    import com.smartgwt.client.widgets.Label;
    import com.smartgwt.client.widgets.events.DropEvent;
    import com.smartgwt.client.widgets.events.DropHandler;
    import com.smartgwt.client.widgets.layout.HLayout;
    
    import edu.iastate.its.thinkspace.common.client.UI;
    
    public class Track extends HLayout {
    	private Timeline timeline;
    	private int id;
    	private Canvas body;
    	public Track(final Timeline timeline, int id) {
    		this.timeline = timeline;
    		this.id = id;
    		setDefaultLayoutAlign(VerticalAlignment.CENTER);
    		setPadding(0);
    		setWidth100();
    		setHeight(24);
    		setMinHeight(24);
    		setMaxHeight(24);
    		setMembersMargin(4);
    		Label label = UI.getLabel("Track "+id);
    		label.setShowShadow(true);
    		label.setPadding(1);
    		label.setBackgroundColor(UI.getBackgroundColor());
    		label.setWidth(50);
    		label.setHeight100();
    		body = new Canvas();
    		body.setBackgroundColor("#eee");
    		body.setBorder("1px solid #BBB");
    		body.setPadding(0);
    		body.setWidth("*");
    		body.setHeight100();
    		body.setCanAcceptDrop(true);
    		final Track me = this;
    		body.addDropHandler(new DropHandler() {
    			public void onDrop(DropEvent e) {
    				if (EventHandler.getDragTarget() instanceof ResourceEvent) {
    					final ResourceEvent re = (ResourceEvent)EventHandler.getDragTarget();
    					if (re.getTrack().getId() != me.getId())
    						timeline.moveResourceEvent(me, re);
    				}
    			}
    		});
    		addMember(label);
    		addMember(body);
    	}
    	
    	public void addEvent(ResourceEvent e) {
    		body.addChild(e);
    	}
    	
    	public void deleteEvent(ResourceEvent e) {
    		body.removeChild(e);
    	}
    
    	public void updateEvent(ResourceEvent e) {
    		timeline.updateEvent(e);
    	}
    	
    	public boolean containsEvent(ResourceEvent e) {
    		for (ResourceEvent r: getResourceEvents()) {
    			if (r.getEventId() == e.getEventId())
    				return true;
    		}
    		return false;
    	}
    	
    	public ResourceEvent intersectsEvent(ResourceEvent e) {
    		for (ResourceEvent r: getResourceEvents()) {
    			if (r.getEventId() != e.getEventId() && r.intersects(e)) {
    				return (ResourceEvent)r;
    			}
    		}
    		return null;
    	}
    	
    	public int getId() {
    		return id;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    
    	public List<ResourceEvent> getResourceEvents() {
    		List<ResourceEvent> list = new ArrayList<ResourceEvent>();
    		for (Canvas c: body.getChildren())
    			if (c instanceof ResourceEvent)
    				list.add((ResourceEvent)c);
    		return list;
    	}
    }
    Code:
    package edu.iastate.its.thinkspace.mycase.client.events;
    
    import java.util.List;
    
    import com.smartgwt.client.core.Rectangle;
    import com.smartgwt.client.types.DragAppearance;
    import com.smartgwt.client.types.Overflow;
    import com.smartgwt.client.util.EventHandler;
    import com.smartgwt.client.widgets.Canvas;
    import com.smartgwt.client.widgets.Label;
    import com.smartgwt.client.widgets.events.DragRepositionMoveEvent;
    import com.smartgwt.client.widgets.events.DragRepositionMoveHandler;
    import com.smartgwt.client.widgets.events.DragRepositionStartEvent;
    import com.smartgwt.client.widgets.events.DragRepositionStartHandler;
    import com.smartgwt.client.widgets.events.DragResizeMoveEvent;
    import com.smartgwt.client.widgets.events.DragResizeMoveHandler;
    import com.smartgwt.client.widgets.events.DragResizeStartEvent;
    import com.smartgwt.client.widgets.events.DragResizeStartHandler;
    
    import edu.iastate.its.thinkspace.common.client.resources.Resource;
    
    public class ResourceEvent extends Label {
    	private int id;
    	private long start;
    	private long duration;
    	private List<Resource> resources;
    	private Track track;
    	private int lastLeft;
    	private int lastWidth;
    	public ResourceEvent(int id, long start, long duration) {
    		this.id = id;
    		this.start = start;
    		this.duration = duration;
    		setContents("Event "+id);
    		setMargin(0);
    		setTop(1);
    		setWidth(100);
    		setHeight(20);
    		setMinHeight(20);
    		setMaxHeight(20);
    		setOverflow(Overflow.HIDDEN);
    		setIcon("MyCase/time.png");
    		setBackgroundColor("#DFF");
    		setBorder("1px solid #999");
    		setCanDrop(true);
    		setCanDragResize(true);
    		setCanDragReposition(true);
    		setDragAppearance(DragAppearance.TARGET);
    		final ResourceEvent me = this;
    		
    		addDragRepositionStartHandler(new DragRepositionStartHandler() {
    			public void onDragRepositionStart(DragRepositionStartEvent event) {
    				me.setKeepInParentRect(false);
    				track = me.getTrack();
    				lastLeft = me.getLeft();
    			}
    		});
    		
    		addDragRepositionMoveHandler(new DragRepositionMoveHandler() {
    			public void onDragRepositionMove(DragRepositionMoveEvent event) {
    				if (track != null) {
    					ResourceEvent e = track.intersectsEvent(me);
    					if (e != null)
    						me.setLeft(lastLeft);
    					else
    						lastLeft = me.getLeft();
    					track.updateEvent(me);
    				}
    			}
    		});
    
    		addDragResizeStartHandler(new DragResizeStartHandler() {
    			public void onDragResizeStart(DragResizeStartEvent event) {
    				me.setKeepInParentRect(true);
    				track = me.getTrack();
    				lastWidth = EventHandler.getDragRect().getWidth();
    			}
    		});
    		
    		addDragResizeMoveHandler(new DragResizeMoveHandler() {
    			public void onDragResizeMove(DragResizeMoveEvent event) {
    				Rectangle rect = EventHandler.getDragRect();
    				if (track != null) {
    					ResourceEvent e = track.intersectsEvent(me);
    					if (e != null) {
    						me.setWidth(lastWidth);
    						if (me.getLeft() > e.getLeft())
    							me.setLeft(e.getRight()+4);
    					} else
    						lastWidth = rect.getWidth();
    					track.updateEvent(me);
    				}
    			}
    		});
    	}
    
    	public Track getTrack() {
    		Canvas c = getParentElement();
    		while(c != null && !(c instanceof Track))
    			c = c.getParentElement();
    		return (Track)c;
    	}
    	
    	public int getEventId() {
    		return id;
    	}
    	
    	public long getStart() {
    		return start;
    	}
    	
    	public void setStart(long start) {
    		this.start = start;
    	}
    	
    	public long getDuration() {
    		return duration;
    	}
    	
    	public void setDuration(long duration) {
    		this.duration = duration;
    	}
    	
    	public List<Resource> getResources() {
    		return resources;
    	}
    	
    	public void setResources(List<Resource> resources) {
    		this.resources = resources;
    	}
    }
    Attached Files

    #2
    Setting overflow:"hidden" on the whatever Canvas is being used as the "track" should keep it from being resized. However you probably do not want to extend "Label" for this as it's got a number of customizations specified to what it does - if you need background text or similar, just add a Label as a child.

    Comment


      #3
      Event now goes behind track

      Thanks, that solved the problem of the track resizing but now the event disappears underneath the track. The track consists of a label and a body and the body is where I set the overflow, which conforms to your suggestion.

      I tried setting the Zindex on the Event but that didn't help.

      Comment


        #4
        If zIndex is the issue, calling bringToFront() on the widget after it has been added to it's new parent will solve it. Alternatively, if it's the Label that's in front, call sendToBack() on the Label.

        If it's some other problem (like maybe the parent/child setup is not what you intended), then the Watch tab in the Developer Console should reveal this.

        Comment

        Working...
        X