Line data Source code
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 : #include "nsTreeImageListener.h"
7 : #include "nsITreeBoxObject.h"
8 : #include "imgIRequest.h"
9 : #include "imgIContainer.h"
10 : #include "nsIContent.h"
11 :
12 0 : NS_IMPL_ISUPPORTS(nsTreeImageListener, imgINotificationObserver)
13 :
14 0 : nsTreeImageListener::nsTreeImageListener(nsTreeBodyFrame* aTreeFrame)
15 : : mTreeFrame(aTreeFrame),
16 : mInvalidationSuppressed(true),
17 0 : mInvalidationArea(nullptr)
18 : {
19 0 : }
20 :
21 0 : nsTreeImageListener::~nsTreeImageListener()
22 : {
23 0 : delete mInvalidationArea;
24 0 : }
25 :
26 : NS_IMETHODIMP
27 0 : nsTreeImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
28 : {
29 0 : if (aType == imgINotificationObserver::IS_ANIMATED) {
30 0 : return mTreeFrame ? mTreeFrame->OnImageIsAnimated(aRequest) : NS_OK;
31 : }
32 :
33 0 : if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
34 : // Ensure the animation (if any) is started. Note: There is no
35 : // corresponding call to Decrement for this. This Increment will be
36 : // 'cleaned up' by the Request when it is destroyed, but only then.
37 0 : aRequest->IncrementAnimationConsumers();
38 : }
39 :
40 0 : if (aType == imgINotificationObserver::FRAME_UPDATE) {
41 0 : Invalidate();
42 : }
43 :
44 0 : return NS_OK;
45 : }
46 :
47 : void
48 0 : nsTreeImageListener::AddCell(int32_t aIndex, nsITreeColumn* aCol)
49 : {
50 0 : if (!mInvalidationArea) {
51 0 : mInvalidationArea = new InvalidationArea(aCol);
52 0 : mInvalidationArea->AddRow(aIndex);
53 : }
54 : else {
55 : InvalidationArea* currArea;
56 0 : for (currArea = mInvalidationArea; currArea; currArea = currArea->GetNext()) {
57 0 : if (currArea->GetCol() == aCol) {
58 0 : currArea->AddRow(aIndex);
59 0 : break;
60 : }
61 : }
62 0 : if (!currArea) {
63 0 : currArea = new InvalidationArea(aCol);
64 0 : currArea->SetNext(mInvalidationArea);
65 0 : mInvalidationArea = currArea;
66 0 : mInvalidationArea->AddRow(aIndex);
67 : }
68 : }
69 0 : }
70 :
71 :
72 : void
73 0 : nsTreeImageListener::Invalidate()
74 : {
75 0 : if (!mInvalidationSuppressed) {
76 0 : for (InvalidationArea* currArea = mInvalidationArea; currArea;
77 : currArea = currArea->GetNext()) {
78 : // Loop from min to max, invalidating each cell that was listening for this image.
79 0 : for (int32_t i = currArea->GetMin(); i <= currArea->GetMax(); ++i) {
80 0 : if (mTreeFrame) {
81 0 : nsITreeBoxObject* tree = mTreeFrame->GetTreeBoxObject();
82 0 : if (tree) {
83 0 : tree->InvalidateCell(i, currArea->GetCol());
84 : }
85 : }
86 : }
87 : }
88 : }
89 0 : }
90 :
91 0 : nsTreeImageListener::InvalidationArea::InvalidationArea(nsITreeColumn* aCol)
92 : : mCol(aCol),
93 : mMin(-1), // min should start out "undefined"
94 : mMax(0),
95 0 : mNext(nullptr)
96 : {
97 0 : }
98 :
99 : void
100 0 : nsTreeImageListener::InvalidationArea::AddRow(int32_t aIndex)
101 : {
102 0 : if (mMin == -1)
103 0 : mMin = mMax = aIndex;
104 0 : else if (aIndex < mMin)
105 0 : mMin = aIndex;
106 0 : else if (aIndex > mMax)
107 0 : mMax = aIndex;
108 0 : }
109 :
110 : NS_IMETHODIMP
111 0 : nsTreeImageListener::ClearFrame()
112 : {
113 0 : mTreeFrame = nullptr;
114 0 : return NS_OK;
115 : }
|