/**
* Copyright 2007 Point5u, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.milescript.portal;
import org.milescript.dom.window;
import org.milescript.types.Box;
import org.milescript.types.Point;
import org.milescript.types.Padding;
import wrap.ext.Component;
import wrap.ext.Container;
import wrap.ext.EventObject;
import wrap.ext.Panel;
import wrap.ext.dd.DragSource;
import wrap.ext.dd.DDTarget;
import wrap.ext.dd.DropTarget;
import wrap.ext.dd.PanelProxy;
import wrap.ext.dd.ScrollManager;
import wrap.ext.dd.StatusProxy;
import wrap.ext.dd.types.DDScrollConfig;
import wrap.ext.dd.types.DropTargetConfig;
import wrap.ext.types.DefaultExtDelegate;
public class PortalDropZone {
private Portal portal;
private Panel panel;
private DropTarget target;
private PortalBox grid;
private PortalBox box;
private int lastCW;
private PortalPos lastPos;
private Padding scrollPos;
private int st;
public PortalDropZone(Portal portal) {
this.portal = portal;
panel = portal.getPanel();
ScrollManager.register(panel.body);
DDScrollConfig ddscroll = new DDScrollConfig{
vthresh: 50,
hthresh: -1,
animate: true,
increment: 200
};
panel.body.ddScrollConfig = ddscroll;
DropTargetConfig targetConfig = new DropTargetConfig{
ddScrollConfig: ddscroll,
notifyOver: notifyOver,
notifyOut: notifyOut,
notifyDrop: notifyDrop
};
target = new DropTarget(panel.body.dom, targetConfig);
}
private String notifyOver(DragSource dd, EventObject e, Object data) {
Array<int> xy = e.getXY();
PanelProxy px = (PanelProxy)dd.getProxy();
// case column widths
if(this.grid == null) {
this.grid = this.getGrid();
}
// handle case scroll where scrollbars appear during drag
int cw = panel.body.dom.clientWidth;
if(this.lastCW == null) {
this.lastCW = cw;
} else if(this.lastCW != cw) {
this.lastCW = cw;
panel.doLayout();
this.grid = this.getGrid();
}
// determine column
int col = 0;
Array<PortalBox> xs = this.grid.columnX;
boolean cmatch = false;
for(int len = xs.length; len > col; col++) {
if(xy[0] < (xs[col].x + xs[col].w)) {
cmatch = true;
break;
}
}
// no match fix last index
if(!cmatch) {
col--;
}
// find insertion position
Component p = null;
boolean match = false;
int pos = 0;
Container c = (Container)panel.items.itemAt(col);
Array<Component> items = c.items.items;
for(int len = items.length; len > pos; pos++) {
p = items[pos];
int h = p.getEl().getHeight();
int temp = (p.getEl().getY()+(h/2));
if(h !== 0 && temp > xy[1]) {
match = true;
break;
}
}
int posVal = pos;
if(!match || p == null) {
posVal = c.items.getCount();
}
PortalEvent overEvent = new PortalEvent(panel, dd, e, data, col, c, posVal, target.dropAllowed);
if(panel.fireEvent("validatedrop", overEvent) !== false &&
panel.fireEvent("beforedragover", overEvent) !== false) {
// make sure proxy width is fluid
px.getProxy().setWidth("auto");
if(p != null) {
if(match) {
px.moveProxy(p.getEl().dom.parentNode, p.getEl().dom);
} else {
px.moveProxy(p.getEl().dom.parentNode, null);
}
} else {
px.moveProxy(c.getEl().dom, null);
}
if(!match || p == null) {
this.lastPos = new PortalPos(c, col, null);
} else {
this.lastPos = new PortalPos(c, col, pos);
}
this.scrollPos = panel.body.getScroll();
return overEvent.status;
} else {
return overEvent.status;
}
}
private void notifyOut() {
this.grid = null;
}
private void notifyDrop(DragSource dd, EventObject e, Object data) {
this.grid = null;
PanelProxy px = (PanelProxy)dd.getProxy();
Container c = this.lastPos.c;
int col = this.lastPos.col;
int pos = c.items.getCount();
if(this.lastPos.p != null) {
pos = this.lastPos.p;
}
PortalEvent dropEvent = new PortalEvent(panel, dd, e, data, col, c, pos, target.dropAllowed);
if(this.panel.fireEvent('validatedrop', dropEvent) !== false &&
this.panel.fireEvent('beforedrop', dropEvent) !== false) {
if(px.getEl() != null) {
px.getEl().remove();
px.panel.getEl().dom.parentNode.removeChild(px.panel.getEl().dom);
}
if(pos !== null){
c.insert(pos, px.panel);
}else{
c.add(px.panel);
}
c.doLayout();
panel.fireEvent('drop', dropEvent);
// scroll position is lost on drop, fix it
this.st = this.scrollPos.top;
if(st != null){
window.setTimeout(timeoutFunc, 10);
}
}
}
private void timeoutFunc() {
this.panel.body.dom.scrollTop = this.st;
}
private PortalBox getGrid() {
box = new PortalBox(this.panel.getBox());
box.columnX = new Array<PortalBox>();
this.panel.items.each(getGridHelper);
return box;
}
private void getGridHelper(Component c) {
PortalBox val = new PortalBox();
val.x = c.getEl().getX();
val.w = c.getEl().getWidth();
box.columnX.push(val);
}
}
|