michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // michael@0: // Eric Vaughan michael@0: // Netscape Communications michael@0: // michael@0: // See documentation in associated header file michael@0: // michael@0: michael@0: #include "nsScrollbarFrame.h" michael@0: #include "nsScrollbarButtonFrame.h" michael@0: #include "nsGkAtoms.h" michael@0: #include "nsIScrollableFrame.h" michael@0: #include "nsIScrollbarMediator.h" michael@0: #include "mozilla/LookAndFeel.h" michael@0: #include "nsThemeConstants.h" michael@0: #include "nsRenderingContext.h" michael@0: #include "nsIContent.h" michael@0: michael@0: using namespace mozilla; michael@0: michael@0: // michael@0: // NS_NewScrollbarFrame michael@0: // michael@0: // Creates a new scrollbar frame and returns it michael@0: // michael@0: nsIFrame* michael@0: NS_NewScrollbarFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) michael@0: { michael@0: return new (aPresShell) nsScrollbarFrame (aPresShell, aContext); michael@0: } michael@0: michael@0: NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarFrame) michael@0: michael@0: NS_QUERYFRAME_HEAD(nsScrollbarFrame) michael@0: NS_QUERYFRAME_ENTRY(nsScrollbarFrame) michael@0: NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) michael@0: michael@0: void michael@0: nsScrollbarFrame::Init(nsIContent* aContent, michael@0: nsIFrame* aParent, michael@0: nsIFrame* aPrevInFlow) michael@0: { michael@0: nsBoxFrame::Init(aContent, aParent, aPrevInFlow); michael@0: michael@0: // We want to be a reflow root since we use reflows to move the michael@0: // slider. Any reflow inside the scrollbar frame will be a reflow to michael@0: // move the slider and will thus not change anything outside of the michael@0: // scrollbar or change the size of the scrollbar frame. michael@0: mState |= NS_FRAME_REFLOW_ROOT; michael@0: } michael@0: michael@0: nsresult michael@0: nsScrollbarFrame::Reflow(nsPresContext* aPresContext, michael@0: nsHTMLReflowMetrics& aDesiredSize, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aStatus) michael@0: { michael@0: nsresult rv = nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // nsGfxScrollFrame may have told us to shrink to nothing. If so, make sure our michael@0: // desired size agrees. michael@0: if (aReflowState.AvailableWidth() == 0) { michael@0: aDesiredSize.Width() = 0; michael@0: } michael@0: if (aReflowState.AvailableHeight() == 0) { michael@0: aDesiredSize.Height() = 0; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsIAtom* michael@0: nsScrollbarFrame::GetType() const michael@0: { michael@0: return nsGkAtoms::scrollbarFrame; michael@0: } michael@0: michael@0: nsresult michael@0: nsScrollbarFrame::AttributeChanged(int32_t aNameSpaceID, michael@0: nsIAtom* aAttribute, michael@0: int32_t aModType) michael@0: { michael@0: nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, michael@0: aModType); michael@0: michael@0: // if the current position changes, notify any nsGfxScrollFrame michael@0: // parent we may have michael@0: if (aAttribute != nsGkAtoms::curpos) michael@0: return rv; michael@0: michael@0: nsIScrollableFrame* scrollable = do_QueryFrame(GetParent()); michael@0: if (!scrollable) michael@0: return rv; michael@0: michael@0: nsCOMPtr kungFuDeathGrip(mContent); michael@0: scrollable->CurPosAttributeChanged(mContent); michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScrollbarFrame::HandlePress(nsPresContext* aPresContext, michael@0: WidgetGUIEvent* aEvent, michael@0: nsEventStatus* aEventStatus) michael@0: { michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScrollbarFrame::HandleMultiplePress(nsPresContext* aPresContext, michael@0: WidgetGUIEvent* aEvent, michael@0: nsEventStatus* aEventStatus, michael@0: bool aControlHeld) michael@0: { michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScrollbarFrame::HandleDrag(nsPresContext* aPresContext, michael@0: WidgetGUIEvent* aEvent, michael@0: nsEventStatus* aEventStatus) michael@0: { michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsScrollbarFrame::HandleRelease(nsPresContext* aPresContext, michael@0: WidgetGUIEvent* aEvent, michael@0: nsEventStatus* aEventStatus) michael@0: { michael@0: return NS_OK; michael@0: } michael@0: michael@0: void michael@0: nsScrollbarFrame::SetScrollbarMediatorContent(nsIContent* aMediator) michael@0: { michael@0: mScrollbarMediator = aMediator; michael@0: } michael@0: michael@0: nsIScrollbarMediator* michael@0: nsScrollbarFrame::GetScrollbarMediator() michael@0: { michael@0: if (!mScrollbarMediator) michael@0: return nullptr; michael@0: nsIFrame* f = mScrollbarMediator->GetPrimaryFrame(); michael@0: michael@0: // check if the frame is a scroll frame. If so, get the scrollable frame michael@0: // inside it. michael@0: nsIScrollableFrame* scrollFrame = do_QueryFrame(f); michael@0: if (scrollFrame) { michael@0: f = scrollFrame->GetScrolledFrame(); michael@0: } michael@0: michael@0: nsIScrollbarMediator* sbm = do_QueryFrame(f); michael@0: return sbm; michael@0: } michael@0: michael@0: nsresult michael@0: nsScrollbarFrame::GetMargin(nsMargin& aMargin) michael@0: { michael@0: aMargin.SizeTo(0,0,0,0); michael@0: michael@0: if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) { michael@0: nsPresContext* presContext = PresContext(); michael@0: nsITheme* theme = presContext->GetTheme(); michael@0: if (theme) { michael@0: nsIntSize size; michael@0: bool isOverridable; michael@0: nsRefPtr rc = michael@0: presContext->PresShell()->CreateReferenceRenderingContext(); michael@0: theme->GetMinimumWidgetSize(rc, this, NS_THEME_SCROLLBAR, &size, michael@0: &isOverridable); michael@0: if (IsHorizontal()) { michael@0: aMargin.top = -presContext->DevPixelsToAppUnits(size.height); michael@0: } michael@0: else { michael@0: if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { michael@0: aMargin.right = -presContext->DevPixelsToAppUnits(size.width); michael@0: } michael@0: else { michael@0: aMargin.left = -presContext->DevPixelsToAppUnits(size.width); michael@0: } michael@0: } michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: return nsBox::GetMargin(aMargin); michael@0: }