void nsSplitterFrameInner::MouseDrag(nsPresContext* aPresContext, nsGUIEvent* aEvent) { if (mDragging && mOuter) { //printf("Dragging\n"); bool isHorizontal = !mOuter->IsHorizontal(); // convert coord to pixels nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, mParentBox); nscoord pos = isHorizontal ? pt.x : pt.y; // mDragStart is in frame coordinates nscoord start = mDragStart; // take our current position and subtract the start location pos -= start; //printf("Diff=%d\n", pos); ResizeType resizeAfter = GetResizeAfter(); bool bounded; if (resizeAfter == nsSplitterFrameInner::Grow) bounded = false; else bounded = true; int i; for (i=0; i < mChildInfosBeforeCount; i++) mChildInfosBefore[i].changed = mChildInfosBefore[i].current; for (i=0; i < mChildInfosAfterCount; i++) mChildInfosAfter[i].changed = mChildInfosAfter[i].current; nscoord oldPos = pos; ResizeChildTo(aPresContext, pos, mChildInfosBefore, mChildInfosAfter, mChildInfosBeforeCount, mChildInfosAfterCount, bounded); State currentState = GetState(); bool supportsBefore = SupportsCollapseDirection(Before); bool supportsAfter = SupportsCollapseDirection(After); const bool isRTL = mOuter->GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL; bool pastEnd = oldPos > 0 && oldPos > pos; bool pastBegin = oldPos < 0 && oldPos < pos; if (isRTL) { // Swap the boundary checks in RTL mode bool tmp = pastEnd; pastEnd = pastBegin; pastBegin = tmp; } const bool isCollapsedBefore = pastBegin && supportsBefore; const bool isCollapsedAfter = pastEnd && supportsAfter; // if we are in a collapsed position if (isCollapsedBefore || isCollapsedAfter) { // and we are not collapsed then collapse if (currentState == Dragging) { if (pastEnd) { //printf("Collapse right\n"); if (supportsAfter) { nsCOMPtr<nsIContent> outer = mOuter->mContent; outer->SetAttr(kNameSpaceID_None, nsGkAtoms::substate, NS_LITERAL_STRING("after"), true); outer->SetAttr(kNameSpaceID_None, nsGkAtoms::state, NS_LITERAL_STRING("collapsed"), true); } } else if (pastBegin) { //printf("Collapse left\n"); if (supportsBefore) { nsCOMPtr<nsIContent> outer = mOuter->mContent; outer->SetAttr(kNameSpaceID_None, nsGkAtoms::substate, NS_LITERAL_STRING("before"), true); outer->SetAttr(kNameSpaceID_None, nsGkAtoms::state, NS_LITERAL_STRING("collapsed"), true); } } } } else { // if we are not in a collapsed position and we are not dragging make sure // we are dragging. if (currentState != Dragging) mOuter->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::state, NS_LITERAL_STRING("dragging"), true); AdjustChildren(aPresContext); } mDidDrag = true; } }
nsresult nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent) { NS_ENSURE_TRUE(mOuter, NS_OK); nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(aMouseEvent)); if (!mouseEvent) return NS_OK; PRUint16 button = 0; mouseEvent->GetButton(&button); // only if left button if (button != 0) return NS_OK; if (mOuter->GetContent()-> AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true, eCaseMatters)) return NS_OK; mParentBox = mOuter->GetParentBox(); if (!mParentBox) return NS_OK; // get our index nsPresContext* outerPresContext = mOuter->PresContext(); const nsFrameList& siblingList(mParentBox->PrincipalChildList()); PRInt32 childIndex = siblingList.IndexOf(mOuter); // if it's 0 (or not found) then stop right here. // It might be not found if we're not in the parent's primary frame list. if (childIndex <= 0) return NS_OK; PRInt32 childCount = siblingList.GetLength(); // if it's the last index then we need to allow for resizeafter="grow" if (childIndex == childCount - 1 && GetResizeAfter() != Grow) return NS_OK; nsRefPtr<nsRenderingContext> rc = outerPresContext->PresShell()->GetReferenceRenderingContext(); NS_ENSURE_TRUE(rc, NS_ERROR_FAILURE); nsBoxLayoutState state(outerPresContext, rc); mCurrentPos = 0; mPressed = true; mDidDrag = false; EnsureOrient(); bool isHorizontal = !mOuter->IsHorizontal(); ResizeType resizeBefore = GetResizeBefore(); ResizeType resizeAfter = GetResizeAfter(); delete[] mChildInfosBefore; delete[] mChildInfosAfter; mChildInfosBefore = new nsSplitterInfo[childCount]; mChildInfosAfter = new nsSplitterInfo[childCount]; // create info 2 lists. One of the children before us and one after. PRInt32 count = 0; mChildInfosBeforeCount = 0; mChildInfosAfterCount = 0; nsIFrame* childBox = mParentBox->GetChildBox(); while (nullptr != childBox) { nsIContent* content = childBox->GetContent(); nsIDocument* doc = content->OwnerDoc(); PRInt32 dummy; nsIAtom* atom = doc->BindingManager()->ResolveTag(content, &dummy); // skip over any splitters if (atom != nsGkAtoms::splitter) { nsSize prefSize = childBox->GetPrefSize(state); nsSize minSize = childBox->GetMinSize(state); nsSize maxSize = nsBox::BoundsCheckMinMax(minSize, childBox->GetMaxSize(state)); prefSize = nsBox::BoundsCheck(minSize, prefSize, maxSize); mOuter->AddMargin(childBox, minSize); mOuter->AddMargin(childBox, prefSize); mOuter->AddMargin(childBox, maxSize); nscoord flex = childBox->GetFlex(state); nsMargin margin(0,0,0,0); childBox->GetMargin(margin); nsRect r(childBox->GetRect()); r.Inflate(margin); // We need to check for hidden attribute too, since treecols with // the hidden="true" attribute are not really hidden, just collapsed if (!content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::fixed, nsGkAtoms::_true, eCaseMatters) && !content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden, nsGkAtoms::_true, eCaseMatters)) { if (count < childIndex && (resizeBefore != Flex || flex > 0)) { mChildInfosBefore[mChildInfosBeforeCount].childElem = content; mChildInfosBefore[mChildInfosBeforeCount].min = isHorizontal ? minSize.width : minSize.height; mChildInfosBefore[mChildInfosBeforeCount].max = isHorizontal ? maxSize.width : maxSize.height; mChildInfosBefore[mChildInfosBeforeCount].current = isHorizontal ? r.width : r.height; mChildInfosBefore[mChildInfosBeforeCount].flex = flex; mChildInfosBefore[mChildInfosBeforeCount].index = count; mChildInfosBefore[mChildInfosBeforeCount].changed = mChildInfosBefore[mChildInfosBeforeCount].current; mChildInfosBeforeCount++; } else if (count > childIndex && (resizeAfter != Flex || flex > 0)) { mChildInfosAfter[mChildInfosAfterCount].childElem = content; mChildInfosAfter[mChildInfosAfterCount].min = isHorizontal ? minSize.width : minSize.height; mChildInfosAfter[mChildInfosAfterCount].max = isHorizontal ? maxSize.width : maxSize.height; mChildInfosAfter[mChildInfosAfterCount].current = isHorizontal ? r.width : r.height; mChildInfosAfter[mChildInfosAfterCount].flex = flex; mChildInfosAfter[mChildInfosAfterCount].index = count; mChildInfosAfter[mChildInfosAfterCount].changed = mChildInfosAfter[mChildInfosAfterCount].current; mChildInfosAfterCount++; } } } childBox = childBox->GetNextBox(); count++; } if (!mParentBox->IsNormalDirection()) { // The before array is really the after array, and the order needs to be reversed. // First reverse both arrays. Reverse(mChildInfosBefore, mChildInfosBeforeCount); Reverse(mChildInfosAfter, mChildInfosAfterCount); // Now swap the two arrays. nscoord newAfterCount = mChildInfosBeforeCount; mChildInfosBeforeCount = mChildInfosAfterCount; mChildInfosAfterCount = newAfterCount; nsSplitterInfo* temp = mChildInfosAfter; mChildInfosAfter = mChildInfosBefore; mChildInfosBefore = temp; } // if resizebefore is not Farthest, reverse the list because the first child // in the list is the farthest, and we want the first child to be the closest. if (resizeBefore != Farthest) Reverse(mChildInfosBefore, mChildInfosBeforeCount); // if the resizeafter is the Farthest we must reverse the list because the first child in the list // is the closest we want the first child to be the Farthest. if (resizeAfter == Farthest) Reverse(mChildInfosAfter, mChildInfosAfterCount); // grow only applys to the children after. If grow is set then no space should be taken out of any children after // us. To do this we just set the size of that list to be 0. if (resizeAfter == Grow) mChildInfosAfterCount = 0; PRInt32 c; nsPoint pt = nsLayoutUtils::GetDOMEventCoordinatesRelativeTo(mouseEvent, mParentBox); if (isHorizontal) { c = pt.x; mSplitterPos = mOuter->mRect.x; } else { c = pt.y; mSplitterPos = mOuter->mRect.y; } mDragStart = c; //printf("Pressed mDragStart=%d\n",mDragStart); nsIPresShell::SetCapturingContent(mOuter->GetContent(), CAPTURE_IGNOREALLOWED); return NS_OK; }
void nsSplitterFrameInner::MouseDrag(nsPresContext* aPresContext, nsGUIEvent* aEvent) { if (mDragging && mOuter) { //printf("Dragging\n"); PRBool isHorizontal = !mOuter->IsHorizontal(); // convert coord to pixels nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, mParentBox); nscoord pos = isHorizontal ? pt.x : pt.y; // mDragStart is in frame coordinates nscoord start = mDragStart; // take our current position and subtract the start location pos -= start; //printf("Diff=%d\n", pos); ResizeType resizeAfter = GetResizeAfter(); PRBool bounded; if (resizeAfter == nsSplitterFrameInner::Grow) bounded = PR_FALSE; else bounded = PR_TRUE; int i; for (i=0; i < mChildInfosBeforeCount; i++) mChildInfosBefore[i].changed = mChildInfosBefore[i].current; for (i=0; i < mChildInfosAfterCount; i++) mChildInfosAfter[i].changed = mChildInfosAfter[i].current; nscoord oldPos = pos; ResizeChildTo(aPresContext, pos, mChildInfosBefore, mChildInfosAfter, mChildInfosBeforeCount, mChildInfosAfterCount, bounded); State currentState = GetState(); PRBool supportsBefore = SupportsCollapseDirection(Before); PRBool supportsAfter = SupportsCollapseDirection(After); // if we are in a collapsed position if ((oldPos > 0 && oldPos > pos && supportsAfter) || (oldPos < 0 && oldPos < pos && supportsBefore)) { // and we are not collapsed then collapse if (currentState == Dragging) { if (oldPos > 0 && oldPos > pos) { //printf("Collapse right\n"); if (supportsAfter) { nsCOMPtr<nsIContent> outer = mOuter->mContent; outer->SetAttr(kNameSpaceID_None, nsGkAtoms::substate, NS_LITERAL_STRING("after"), PR_TRUE); outer->SetAttr(kNameSpaceID_None, nsGkAtoms::state, NS_LITERAL_STRING("collapsed"), PR_TRUE); } } else if (oldPos < 0 && oldPos < pos) { //printf("Collapse left\n"); if (supportsBefore) { nsCOMPtr<nsIContent> outer = mOuter->mContent; outer->SetAttr(kNameSpaceID_None, nsGkAtoms::substate, NS_LITERAL_STRING("before"), PR_TRUE); outer->SetAttr(kNameSpaceID_None, nsGkAtoms::state, NS_LITERAL_STRING("collapsed"), PR_TRUE); } } } } else { // if we are not in a collapsed position and we are not dragging make sure // we are dragging. if (currentState != Dragging) mOuter->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::state, NS_LITERAL_STRING("dragging"), PR_TRUE); AdjustChildren(aPresContext); } mDidDrag = PR_TRUE; } }