summaryrefslogtreecommitdiffstats
path: root/layout/xul/nsDeckFrame.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /layout/xul/nsDeckFrame.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'layout/xul/nsDeckFrame.cpp')
-rw-r--r--layout/xul/nsDeckFrame.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/layout/xul/nsDeckFrame.cpp b/layout/xul/nsDeckFrame.cpp
new file mode 100644
index 000000000..b0c0296b2
--- /dev/null
+++ b/layout/xul/nsDeckFrame.cpp
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//
+// Eric Vaughan
+// Netscape Communications
+//
+// See documentation in associated header file
+//
+
+#include "nsDeckFrame.h"
+#include "nsStyleContext.h"
+#include "nsPresContext.h"
+#include "nsIContent.h"
+#include "nsCOMPtr.h"
+#include "nsNameSpaceManager.h"
+#include "nsGkAtoms.h"
+#include "nsHTMLParts.h"
+#include "nsIPresShell.h"
+#include "nsCSSRendering.h"
+#include "nsViewManager.h"
+#include "nsBoxLayoutState.h"
+#include "nsStackLayout.h"
+#include "nsDisplayList.h"
+#include "nsContainerFrame.h"
+#include "nsContentUtils.h"
+
+#ifdef ACCESSIBILITY
+#include "nsAccessibilityService.h"
+#endif
+
+nsIFrame*
+NS_NewDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
+{
+ return new (aPresShell) nsDeckFrame(aContext);
+}
+
+NS_IMPL_FRAMEARENA_HELPERS(nsDeckFrame)
+
+NS_QUERYFRAME_HEAD(nsDeckFrame)
+ NS_QUERYFRAME_ENTRY(nsDeckFrame)
+NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
+
+
+nsDeckFrame::nsDeckFrame(nsStyleContext* aContext)
+ : nsBoxFrame(aContext), mIndex(0)
+{
+ nsCOMPtr<nsBoxLayout> layout;
+ NS_NewStackLayout(layout);
+ SetXULLayoutManager(layout);
+}
+
+nsIAtom*
+nsDeckFrame::GetType() const
+{
+ return nsGkAtoms::deckFrame;
+}
+
+nsresult
+nsDeckFrame::AttributeChanged(int32_t aNameSpaceID,
+ nsIAtom* aAttribute,
+ int32_t aModType)
+{
+ nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute,
+ aModType);
+
+
+ // if the index changed hide the old element and make the new element visible
+ if (aAttribute == nsGkAtoms::selectedIndex) {
+ IndexChanged();
+ }
+
+ return rv;
+}
+
+void
+nsDeckFrame::Init(nsIContent* aContent,
+ nsContainerFrame* aParent,
+ nsIFrame* aPrevInFlow)
+{
+ nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
+
+ mIndex = GetSelectedIndex();
+}
+
+void
+nsDeckFrame::HideBox(nsIFrame* aBox)
+{
+ nsIPresShell::ClearMouseCapture(aBox);
+}
+
+void
+nsDeckFrame::IndexChanged()
+{
+ //did the index change?
+ int32_t index = GetSelectedIndex();
+ if (index == mIndex)
+ return;
+
+ // redraw
+ InvalidateFrame();
+
+ // hide the currently showing box
+ nsIFrame* currentBox = GetSelectedBox();
+ if (currentBox) // only hide if it exists
+ HideBox(currentBox);
+
+ mIndex = index;
+
+#ifdef ACCESSIBILITY
+ nsAccessibilityService* accService = GetAccService();
+ if (accService) {
+ accService->DeckPanelSwitched(PresContext()->GetPresShell(), mContent,
+ currentBox, GetSelectedBox());
+ }
+#endif
+}
+
+int32_t
+nsDeckFrame::GetSelectedIndex()
+{
+ // default index is 0
+ int32_t index = 0;
+
+ // get the index attribute
+ nsAutoString value;
+ if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::selectedIndex, value))
+ {
+ nsresult error;
+
+ // convert it to an integer
+ index = value.ToInteger(&error);
+ }
+
+ return index;
+}
+
+nsIFrame*
+nsDeckFrame::GetSelectedBox()
+{
+ return (mIndex >= 0) ? mFrames.FrameAt(mIndex) : nullptr;
+}
+
+void
+nsDeckFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
+ const nsRect& aDirtyRect,
+ const nsDisplayListSet& aLists)
+{
+ // if a tab is hidden all its children are too.
+ if (!StyleVisibility()->mVisible)
+ return;
+
+ nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
+}
+
+void
+nsDeckFrame::RemoveFrame(ChildListID aListID,
+ nsIFrame* aOldFrame)
+{
+ nsIFrame* currentFrame = GetSelectedBox();
+ if (currentFrame &&
+ aOldFrame &&
+ currentFrame != aOldFrame) {
+ // If the frame we're removing is at an index that's less
+ // than mIndex, that means we're going to be shifting indexes
+ // by 1.
+ //
+ // We attempt to keep the same child displayed by automatically
+ // updating our internal notion of the current index.
+ int32_t removedIndex = mFrames.IndexOf(aOldFrame);
+ MOZ_ASSERT(removedIndex >= 0,
+ "A deck child was removed that was not in mFrames.");
+ if (removedIndex < mIndex) {
+ mIndex--;
+ // This is going to cause us to handle the index change in IndexedChanged,
+ // but since the new index will match mIndex, it's essentially a noop.
+ nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
+ mContent, nsGkAtoms::selectedIndex, mIndex));
+ }
+ }
+ nsBoxFrame::RemoveFrame(aListID, aOldFrame);
+}
+
+void
+nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
+ const nsRect& aDirtyRect,
+ const nsDisplayListSet& aLists)
+{
+ // only paint the selected box
+ nsIFrame* box = GetSelectedBox();
+ if (!box)
+ return;
+
+ // Putting the child in the background list. This is a little weird but
+ // it matches what we were doing before.
+ nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds());
+ BuildDisplayListForChild(aBuilder, box, aDirtyRect, set);
+}
+
+NS_IMETHODIMP
+nsDeckFrame::DoXULLayout(nsBoxLayoutState& aState)
+{
+ // Make sure we tweak the state so it does not resize our children.
+ // We will do that.
+ uint32_t oldFlags = aState.LayoutFlags();
+ aState.SetLayoutFlags(NS_FRAME_NO_SIZE_VIEW | NS_FRAME_NO_VISIBILITY);
+
+ // do a normal layout
+ nsresult rv = nsBoxFrame::DoXULLayout(aState);
+
+ // run though each child. Hide all but the selected one
+ nsIFrame* box = nsBox::GetChildXULBox(this);
+
+ nscoord count = 0;
+ while (box)
+ {
+ // make collapsed children not show up
+ if (count != mIndex)
+ HideBox(box);
+
+ box = GetNextXULBox(box);
+ count++;
+ }
+
+ aState.SetLayoutFlags(oldFlags);
+
+ return rv;
+}
+