layout/xul/nsDeckFrame.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 //
michael@0 7 // Eric Vaughan
michael@0 8 // Netscape Communications
michael@0 9 //
michael@0 10 // See documentation in associated header file
michael@0 11 //
michael@0 12
michael@0 13 #include "nsDeckFrame.h"
michael@0 14 #include "nsStyleContext.h"
michael@0 15 #include "nsPresContext.h"
michael@0 16 #include "nsIContent.h"
michael@0 17 #include "nsCOMPtr.h"
michael@0 18 #include "nsNameSpaceManager.h"
michael@0 19 #include "nsGkAtoms.h"
michael@0 20 #include "nsHTMLParts.h"
michael@0 21 #include "nsIPresShell.h"
michael@0 22 #include "nsCSSRendering.h"
michael@0 23 #include "nsViewManager.h"
michael@0 24 #include "nsBoxLayoutState.h"
michael@0 25 #include "nsStackLayout.h"
michael@0 26 #include "nsDisplayList.h"
michael@0 27 #include "nsContainerFrame.h"
michael@0 28
michael@0 29 #ifdef ACCESSIBILITY
michael@0 30 #include "nsAccessibilityService.h"
michael@0 31 #endif
michael@0 32
michael@0 33 nsIFrame*
michael@0 34 NS_NewDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
michael@0 35 {
michael@0 36 return new (aPresShell) nsDeckFrame(aPresShell, aContext);
michael@0 37 }
michael@0 38
michael@0 39 NS_IMPL_FRAMEARENA_HELPERS(nsDeckFrame)
michael@0 40
michael@0 41 NS_QUERYFRAME_HEAD(nsDeckFrame)
michael@0 42 NS_QUERYFRAME_ENTRY(nsDeckFrame)
michael@0 43 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
michael@0 44
michael@0 45
michael@0 46 nsDeckFrame::nsDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
michael@0 47 : nsBoxFrame(aPresShell, aContext), mIndex(0)
michael@0 48 {
michael@0 49 nsCOMPtr<nsBoxLayout> layout;
michael@0 50 NS_NewStackLayout(aPresShell, layout);
michael@0 51 SetLayoutManager(layout);
michael@0 52 }
michael@0 53
michael@0 54 nsIAtom*
michael@0 55 nsDeckFrame::GetType() const
michael@0 56 {
michael@0 57 return nsGkAtoms::deckFrame;
michael@0 58 }
michael@0 59
michael@0 60 nsresult
michael@0 61 nsDeckFrame::AttributeChanged(int32_t aNameSpaceID,
michael@0 62 nsIAtom* aAttribute,
michael@0 63 int32_t aModType)
michael@0 64 {
michael@0 65 nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute,
michael@0 66 aModType);
michael@0 67
michael@0 68
michael@0 69 // if the index changed hide the old element and make the new element visible
michael@0 70 if (aAttribute == nsGkAtoms::selectedIndex) {
michael@0 71 IndexChanged();
michael@0 72 }
michael@0 73
michael@0 74 return rv;
michael@0 75 }
michael@0 76
michael@0 77 void
michael@0 78 nsDeckFrame::Init(nsIContent* aContent,
michael@0 79 nsIFrame* aParent,
michael@0 80 nsIFrame* aPrevInFlow)
michael@0 81 {
michael@0 82 nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
michael@0 83
michael@0 84 mIndex = GetSelectedIndex();
michael@0 85 }
michael@0 86
michael@0 87 void
michael@0 88 nsDeckFrame::HideBox(nsIFrame* aBox)
michael@0 89 {
michael@0 90 nsIPresShell::ClearMouseCapture(aBox);
michael@0 91 }
michael@0 92
michael@0 93 void
michael@0 94 nsDeckFrame::IndexChanged()
michael@0 95 {
michael@0 96 //did the index change?
michael@0 97 int32_t index = GetSelectedIndex();
michael@0 98 if (index == mIndex)
michael@0 99 return;
michael@0 100
michael@0 101 // redraw
michael@0 102 InvalidateFrame();
michael@0 103
michael@0 104 // hide the currently showing box
michael@0 105 nsIFrame* currentBox = GetSelectedBox();
michael@0 106 if (currentBox) // only hide if it exists
michael@0 107 HideBox(currentBox);
michael@0 108
michael@0 109 mIndex = index;
michael@0 110
michael@0 111 #ifdef ACCESSIBILITY
michael@0 112 nsAccessibilityService* accService = GetAccService();
michael@0 113 if (accService) {
michael@0 114 accService->DeckPanelSwitched(PresContext()->GetPresShell(), mContent,
michael@0 115 currentBox, GetSelectedBox());
michael@0 116 }
michael@0 117 #endif
michael@0 118 }
michael@0 119
michael@0 120 int32_t
michael@0 121 nsDeckFrame::GetSelectedIndex()
michael@0 122 {
michael@0 123 // default index is 0
michael@0 124 int32_t index = 0;
michael@0 125
michael@0 126 // get the index attribute
michael@0 127 nsAutoString value;
michael@0 128 if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::selectedIndex, value))
michael@0 129 {
michael@0 130 nsresult error;
michael@0 131
michael@0 132 // convert it to an integer
michael@0 133 index = value.ToInteger(&error);
michael@0 134 }
michael@0 135
michael@0 136 return index;
michael@0 137 }
michael@0 138
michael@0 139 nsIFrame*
michael@0 140 nsDeckFrame::GetSelectedBox()
michael@0 141 {
michael@0 142 return (mIndex >= 0) ? mFrames.FrameAt(mIndex) : nullptr;
michael@0 143 }
michael@0 144
michael@0 145 void
michael@0 146 nsDeckFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
michael@0 147 const nsRect& aDirtyRect,
michael@0 148 const nsDisplayListSet& aLists)
michael@0 149 {
michael@0 150 // if a tab is hidden all its children are too.
michael@0 151 if (!StyleVisibility()->mVisible)
michael@0 152 return;
michael@0 153
michael@0 154 nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
michael@0 155 }
michael@0 156
michael@0 157 void
michael@0 158 nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
michael@0 159 const nsRect& aDirtyRect,
michael@0 160 const nsDisplayListSet& aLists)
michael@0 161 {
michael@0 162 // only paint the selected box
michael@0 163 nsIFrame* box = GetSelectedBox();
michael@0 164 if (!box)
michael@0 165 return;
michael@0 166
michael@0 167 // Putting the child in the background list. This is a little weird but
michael@0 168 // it matches what we were doing before.
michael@0 169 nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds());
michael@0 170 BuildDisplayListForChild(aBuilder, box, aDirtyRect, set);
michael@0 171 }
michael@0 172
michael@0 173 NS_IMETHODIMP
michael@0 174 nsDeckFrame::DoLayout(nsBoxLayoutState& aState)
michael@0 175 {
michael@0 176 // Make sure we tweak the state so it does not resize our children.
michael@0 177 // We will do that.
michael@0 178 uint32_t oldFlags = aState.LayoutFlags();
michael@0 179 aState.SetLayoutFlags(NS_FRAME_NO_SIZE_VIEW | NS_FRAME_NO_VISIBILITY);
michael@0 180
michael@0 181 // do a normal layout
michael@0 182 nsresult rv = nsBoxFrame::DoLayout(aState);
michael@0 183
michael@0 184 // run though each child. Hide all but the selected one
michael@0 185 nsIFrame* box = GetChildBox();
michael@0 186
michael@0 187 nscoord count = 0;
michael@0 188 while (box)
michael@0 189 {
michael@0 190 // make collapsed children not show up
michael@0 191 if (count != mIndex)
michael@0 192 HideBox(box);
michael@0 193
michael@0 194 box = box->GetNextBox();
michael@0 195 count++;
michael@0 196 }
michael@0 197
michael@0 198 aState.SetLayoutFlags(oldFlags);
michael@0 199
michael@0 200 return rv;
michael@0 201 }
michael@0 202

mercurial