private void commitPosition(int pos) { lastElementX_ = pos; // check to see if we're overlapping with another tab for (int i = 0; i < dragTabsHost_.getChildCount(); i++) { // skip non-element DOM nodes Node node = dragTabsHost_.getChild(i); if (node.getNodeType() != Node.ELEMENT_NODE) { continue; } // skip the current candidate (no point in testing it for swap) if (i == candidatePos_) { continue; } // skip the element we're dragging and elements that are not tabs Element ele = (Element) node; if (ele == dragElement_ || ele.getClassName().indexOf("gwt-TabLayoutPanelTab") < 0) { continue; } int left = DomUtils.leftRelativeTo(dragTabsHost_, ele); int right = left + ele.getClientWidth(); int minOverlap = Math.min(initDragWidth_ / 2, ele.getClientWidth() / 2); // a little complicated: compute the number of overlapping pixels // with this element; if the overlap is more than half of our width // (or the width of the candidate), it's swapping time if (Math.min(lastElementX_ + initDragWidth_, right) - Math.max(lastElementX_, left) >= minOverlap) { dragTabsHost_.removeChild(dragPlaceholder_); if (candidatePos_ > i) { dragTabsHost_.insertBefore(dragPlaceholder_, ele); } else { dragTabsHost_.insertAfter(dragPlaceholder_, ele); } candidatePos_ = i; // account for the extra element when moving to the right of the // original location if (dragElement_ != null && startPos_ != null) { destPos_ = startPos_ <= candidatePos_ ? candidatePos_ - 1 : candidatePos_; } else { destPos_ = candidatePos_; } } } }
private void beginDrag(Event evt) { String docId = initDragParams_.getDocId(); int dragTabWidth = initDragWidth_; // set drag element state dragTabsHost_ = getTabBarElement(); dragScrollHost_ = dragTabsHost_.getParentElement(); outOfBounds_ = 0; candidatePos_ = null; startPos_ = null; // attempt to determine which tab the cursor is over Point hostPos = DomUtils.getRelativePosition(Document.get().getBody(), dragTabsHost_); int dragX = evt.getClientX() - hostPos.getX(); for (int i = 0; i < dragTabsHost_.getChildCount(); i++) { Node node = dragTabsHost_.getChild(i); if (node.getNodeType() == Node.ELEMENT_NODE) { int left = DomUtils.leftRelativeTo(dragTabsHost_, Element.as(node)) - dragScrollHost_.getScrollLeft(); int right = left + Element.as(node).getOffsetWidth(); if (left <= dragX && dragX <= right) { candidatePos_ = i; break; } } } // let the rest of the IDE know we're dragging (this will enable us to // disable drag targets that might otherwise be happy to accept the // data) curState_ = STATE_DRAGGING; events_.fireEvent( new DocTabDragStateChangedEvent(DocTabDragStateChangedEvent.STATE_DRAGGING)); // the relative position of the last node determines how far we // can drag dragMax_ = DomUtils.leftRelativeTo(dragTabsHost_, getLastChildElement(dragTabsHost_)) + getLastChildElement(dragTabsHost_).getClientWidth(); lastCursorX_ = evt.getClientX(); // account for cursor starting out of bounds (e.g. dragging into // empty space on the right of the panel) if (lastCursorX_ > dragMax_ + (initDragParams_.getCursorOffset())) outOfBounds_ = (lastCursorX_ - dragMax_) - initDragParams_.getCursorOffset(); // attempt to ascertain whether the element being dragged is one of // our own documents for (DocTab tab : docTabs_) { if (tab.getDocId() == docId) { dragElement_ = tab.getElement().getParentElement().getParentElement(); break; } } // if we couldn't find the horizontal drag position in any tab, append // to the end if (candidatePos_ == null) { candidatePos_ = dragTabsHost_.getChildCount(); } destPos_ = candidatePos_; // if we're dragging one of our own documents, figure out its physical // position if (dragElement_ != null) { for (int i = 0; i < dragTabsHost_.getChildCount(); i++) { if (dragTabsHost_.getChild(i) == dragElement_) { startPos_ = i; break; } } } // compute the start location for the drag if (candidatePos_ >= dragTabsHost_.getChildCount()) { Element lastTab = getLastChildElement(dragTabsHost_); lastElementX_ = DomUtils.leftRelativeTo(dragTabsHost_, lastTab) + lastTab.getOffsetWidth(); } else { lastElementX_ = DomUtils.leftRelativeTo( dragTabsHost_, Element.as(dragTabsHost_.getChild(candidatePos_))); } // if we're dragging one of our own tabs, snap it out of the // tabset if (dragElement_ != null) { dragElement_.getStyle().setPosition(Position.ABSOLUTE); dragElement_.getStyle().setLeft(lastElementX_, Unit.PX); dragElement_.getStyle().setZIndex(100); Scheduler.get() .scheduleDeferred( new ScheduledCommand() { @Override public void execute() { dragElement_.getStyle().setDisplay(Display.NONE); } }); } // create the placeholder that shows where this tab will go when the // mouse is released dragPlaceholder_ = Document.get().createDivElement(); dragPlaceholder_.getStyle().setWidth(dragTabWidth - 4, Unit.PX); dragPlaceholder_.getStyle().setHeight(dragTabsHost_.getClientHeight() - 3, Unit.PX); dragPlaceholder_.getStyle().setDisplay(Display.INLINE_BLOCK); dragPlaceholder_.getStyle().setPosition(Position.RELATIVE); dragPlaceholder_.getStyle().setFloat(Float.LEFT); dragPlaceholder_.getStyle().setBorderStyle(BorderStyle.DOTTED); dragPlaceholder_.getStyle().setBorderColor("#A1A2A3"); dragPlaceholder_.getStyle().setBorderWidth(1, Unit.PX); dragPlaceholder_.getStyle().setMarginLeft(1, Unit.PX); dragPlaceholder_.getStyle().setMarginRight(1, Unit.PX); dragPlaceholder_.getStyle().setProperty("borderTopLeftRadius", "4px"); dragPlaceholder_.getStyle().setProperty("borderTopRightRadius", "4px"); dragPlaceholder_.getStyle().setProperty("borderBottom", "0px"); if (candidatePos_ < dragTabsHost_.getChildCount()) { dragTabsHost_.insertBefore(dragPlaceholder_, dragTabsHost_.getChild(candidatePos_)); } else { dragTabsHost_.appendChild(dragPlaceholder_); } }