layout/xul/nsScrollbarFrame.cpp

branch
TOR_BUG_9701
changeset 14
925c144e1f1f
equal deleted inserted replaced
-1:000000000000 0:795f934214ae
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 //
7 // Eric Vaughan
8 // Netscape Communications
9 //
10 // See documentation in associated header file
11 //
12
13 #include "nsScrollbarFrame.h"
14 #include "nsScrollbarButtonFrame.h"
15 #include "nsGkAtoms.h"
16 #include "nsIScrollableFrame.h"
17 #include "nsIScrollbarMediator.h"
18 #include "mozilla/LookAndFeel.h"
19 #include "nsThemeConstants.h"
20 #include "nsRenderingContext.h"
21 #include "nsIContent.h"
22
23 using namespace mozilla;
24
25 //
26 // NS_NewScrollbarFrame
27 //
28 // Creates a new scrollbar frame and returns it
29 //
30 nsIFrame*
31 NS_NewScrollbarFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
32 {
33 return new (aPresShell) nsScrollbarFrame (aPresShell, aContext);
34 }
35
36 NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarFrame)
37
38 NS_QUERYFRAME_HEAD(nsScrollbarFrame)
39 NS_QUERYFRAME_ENTRY(nsScrollbarFrame)
40 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
41
42 void
43 nsScrollbarFrame::Init(nsIContent* aContent,
44 nsIFrame* aParent,
45 nsIFrame* aPrevInFlow)
46 {
47 nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
48
49 // We want to be a reflow root since we use reflows to move the
50 // slider. Any reflow inside the scrollbar frame will be a reflow to
51 // move the slider and will thus not change anything outside of the
52 // scrollbar or change the size of the scrollbar frame.
53 mState |= NS_FRAME_REFLOW_ROOT;
54 }
55
56 nsresult
57 nsScrollbarFrame::Reflow(nsPresContext* aPresContext,
58 nsHTMLReflowMetrics& aDesiredSize,
59 const nsHTMLReflowState& aReflowState,
60 nsReflowStatus& aStatus)
61 {
62 nsresult rv = nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
63 NS_ENSURE_SUCCESS(rv, rv);
64
65 // nsGfxScrollFrame may have told us to shrink to nothing. If so, make sure our
66 // desired size agrees.
67 if (aReflowState.AvailableWidth() == 0) {
68 aDesiredSize.Width() = 0;
69 }
70 if (aReflowState.AvailableHeight() == 0) {
71 aDesiredSize.Height() = 0;
72 }
73
74 return NS_OK;
75 }
76
77 nsIAtom*
78 nsScrollbarFrame::GetType() const
79 {
80 return nsGkAtoms::scrollbarFrame;
81 }
82
83 nsresult
84 nsScrollbarFrame::AttributeChanged(int32_t aNameSpaceID,
85 nsIAtom* aAttribute,
86 int32_t aModType)
87 {
88 nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute,
89 aModType);
90
91 // if the current position changes, notify any nsGfxScrollFrame
92 // parent we may have
93 if (aAttribute != nsGkAtoms::curpos)
94 return rv;
95
96 nsIScrollableFrame* scrollable = do_QueryFrame(GetParent());
97 if (!scrollable)
98 return rv;
99
100 nsCOMPtr<nsIContent> kungFuDeathGrip(mContent);
101 scrollable->CurPosAttributeChanged(mContent);
102 return rv;
103 }
104
105 NS_IMETHODIMP
106 nsScrollbarFrame::HandlePress(nsPresContext* aPresContext,
107 WidgetGUIEvent* aEvent,
108 nsEventStatus* aEventStatus)
109 {
110 return NS_OK;
111 }
112
113 NS_IMETHODIMP
114 nsScrollbarFrame::HandleMultiplePress(nsPresContext* aPresContext,
115 WidgetGUIEvent* aEvent,
116 nsEventStatus* aEventStatus,
117 bool aControlHeld)
118 {
119 return NS_OK;
120 }
121
122 NS_IMETHODIMP
123 nsScrollbarFrame::HandleDrag(nsPresContext* aPresContext,
124 WidgetGUIEvent* aEvent,
125 nsEventStatus* aEventStatus)
126 {
127 return NS_OK;
128 }
129
130 NS_IMETHODIMP
131 nsScrollbarFrame::HandleRelease(nsPresContext* aPresContext,
132 WidgetGUIEvent* aEvent,
133 nsEventStatus* aEventStatus)
134 {
135 return NS_OK;
136 }
137
138 void
139 nsScrollbarFrame::SetScrollbarMediatorContent(nsIContent* aMediator)
140 {
141 mScrollbarMediator = aMediator;
142 }
143
144 nsIScrollbarMediator*
145 nsScrollbarFrame::GetScrollbarMediator()
146 {
147 if (!mScrollbarMediator)
148 return nullptr;
149 nsIFrame* f = mScrollbarMediator->GetPrimaryFrame();
150
151 // check if the frame is a scroll frame. If so, get the scrollable frame
152 // inside it.
153 nsIScrollableFrame* scrollFrame = do_QueryFrame(f);
154 if (scrollFrame) {
155 f = scrollFrame->GetScrolledFrame();
156 }
157
158 nsIScrollbarMediator* sbm = do_QueryFrame(f);
159 return sbm;
160 }
161
162 nsresult
163 nsScrollbarFrame::GetMargin(nsMargin& aMargin)
164 {
165 aMargin.SizeTo(0,0,0,0);
166
167 if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
168 nsPresContext* presContext = PresContext();
169 nsITheme* theme = presContext->GetTheme();
170 if (theme) {
171 nsIntSize size;
172 bool isOverridable;
173 nsRefPtr<nsRenderingContext> rc =
174 presContext->PresShell()->CreateReferenceRenderingContext();
175 theme->GetMinimumWidgetSize(rc, this, NS_THEME_SCROLLBAR, &size,
176 &isOverridable);
177 if (IsHorizontal()) {
178 aMargin.top = -presContext->DevPixelsToAppUnits(size.height);
179 }
180 else {
181 if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
182 aMargin.right = -presContext->DevPixelsToAppUnits(size.width);
183 }
184 else {
185 aMargin.left = -presContext->DevPixelsToAppUnits(size.width);
186 }
187 }
188 return NS_OK;
189 }
190 }
191
192 return nsBox::GetMargin(aMargin);
193 }

mercurial