• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.hierarchyviewerlib.models;
18 
19 import com.android.hierarchyviewerlib.device.ViewNode;
20 import com.android.hierarchyviewerlib.device.Window;
21 import com.android.hierarchyviewerlib.ui.util.DrawableViewNode;
22 import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Point;
23 import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Rectangle;
24 
25 import java.util.ArrayList;
26 
27 public class TreeViewModel {
28     public static final double MAX_ZOOM = 2;
29 
30     public static final double MIN_ZOOM = 0.2;
31 
32     private Window mWindow;
33 
34     private DrawableViewNode mTree;
35 
36     private DrawableViewNode mSelectedNode;
37 
38     private Rectangle mViewport;
39 
40     private double mZoom;
41 
42     private final ArrayList<ITreeChangeListener> mTreeChangeListeners =
43             new ArrayList<ITreeChangeListener>();
44 
45     private static TreeViewModel sModel;
46 
getModel()47     public static TreeViewModel getModel() {
48         if (sModel == null) {
49             sModel = new TreeViewModel();
50         }
51         return sModel;
52     }
53 
setData(Window window, ViewNode viewNode)54     public void setData(Window window, ViewNode viewNode) {
55         synchronized (this) {
56             if (mTree != null) {
57                 mTree.viewNode.dispose();
58             }
59             this.mWindow = window;
60             if (viewNode == null) {
61                 mTree = null;
62             } else {
63                 mTree = new DrawableViewNode(viewNode);
64                 mTree.setLeft();
65                 mTree.placeRoot();
66             }
67             mViewport = null;
68             mZoom = 1;
69             mSelectedNode = null;
70         }
71         notifyTreeChanged();
72     }
73 
setSelection(DrawableViewNode selectedNode)74     public void setSelection(DrawableViewNode selectedNode) {
75         synchronized (this) {
76             this.mSelectedNode = selectedNode;
77         }
78         notifySelectionChanged();
79     }
80 
setViewport(Rectangle viewport)81     public void setViewport(Rectangle viewport) {
82         synchronized (this) {
83             this.mViewport = viewport;
84         }
85         notifyViewportChanged();
86     }
87 
setZoom(double newZoom)88     public void setZoom(double newZoom) {
89         Point zoomPoint = null;
90         synchronized (this) {
91             if (mTree != null && mViewport != null) {
92                 zoomPoint =
93                         new Point(mViewport.x + mViewport.width / 2, mViewport.y + mViewport.height / 2);
94             }
95         }
96         zoomOnPoint(newZoom, zoomPoint);
97     }
98 
zoomOnPoint(double newZoom, Point zoomPoint)99     public void zoomOnPoint(double newZoom, Point zoomPoint) {
100         synchronized (this) {
101             if (mTree != null && this.mViewport != null) {
102                 if (newZoom < MIN_ZOOM) {
103                     newZoom = MIN_ZOOM;
104                 }
105                 if (newZoom > MAX_ZOOM) {
106                     newZoom = MAX_ZOOM;
107                 }
108                 mViewport.x = zoomPoint.x - (zoomPoint.x - mViewport.x) * mZoom / newZoom;
109                 mViewport.y = zoomPoint.y - (zoomPoint.y - mViewport.y) * mZoom / newZoom;
110                 mViewport.width = mViewport.width * mZoom / newZoom;
111                 mViewport.height = mViewport.height * mZoom / newZoom;
112                 mZoom = newZoom;
113             }
114         }
115         notifyZoomChanged();
116     }
117 
getTree()118     public DrawableViewNode getTree() {
119         synchronized (this) {
120             return mTree;
121         }
122     }
123 
getWindow()124     public Window getWindow() {
125         synchronized (this) {
126             return mWindow;
127         }
128     }
129 
getViewport()130     public Rectangle getViewport() {
131         synchronized (this) {
132             return mViewport;
133         }
134     }
135 
getZoom()136     public double getZoom() {
137         synchronized (this) {
138             return mZoom;
139         }
140     }
141 
getSelection()142     public DrawableViewNode getSelection() {
143         synchronized (this) {
144             return mSelectedNode;
145         }
146     }
147 
148     public static interface ITreeChangeListener {
treeChanged()149         public void treeChanged();
150 
selectionChanged()151         public void selectionChanged();
152 
viewportChanged()153         public void viewportChanged();
154 
zoomChanged()155         public void zoomChanged();
156     }
157 
getTreeChangeListenerList()158     private ITreeChangeListener[] getTreeChangeListenerList() {
159         ITreeChangeListener[] listeners = null;
160         synchronized (mTreeChangeListeners) {
161             if (mTreeChangeListeners.size() == 0) {
162                 return null;
163             }
164             listeners =
165                     mTreeChangeListeners.toArray(new ITreeChangeListener[mTreeChangeListeners.size()]);
166         }
167         return listeners;
168     }
169 
notifyTreeChanged()170     public void notifyTreeChanged() {
171         ITreeChangeListener[] listeners = getTreeChangeListenerList();
172         if (listeners != null) {
173             for (int i = 0; i < listeners.length; i++) {
174                 listeners[i].treeChanged();
175             }
176         }
177     }
178 
notifySelectionChanged()179     public void notifySelectionChanged() {
180         ITreeChangeListener[] listeners = getTreeChangeListenerList();
181         if (listeners != null) {
182             for (int i = 0; i < listeners.length; i++) {
183                 listeners[i].selectionChanged();
184             }
185         }
186     }
187 
notifyViewportChanged()188     public void notifyViewportChanged() {
189         ITreeChangeListener[] listeners = getTreeChangeListenerList();
190         if (listeners != null) {
191             for (int i = 0; i < listeners.length; i++) {
192                 listeners[i].viewportChanged();
193             }
194         }
195     }
196 
notifyZoomChanged()197     public void notifyZoomChanged() {
198         ITreeChangeListener[] listeners = getTreeChangeListenerList();
199         if (listeners != null) {
200             for (int i = 0; i < listeners.length; i++) {
201                 listeners[i].zoomChanged();
202             }
203         }
204     }
205 
addTreeChangeListener(ITreeChangeListener listener)206     public void addTreeChangeListener(ITreeChangeListener listener) {
207         synchronized (mTreeChangeListeners) {
208             mTreeChangeListeners.add(listener);
209         }
210     }
211 
removeTreeChangeListener(ITreeChangeListener listener)212     public void removeTreeChangeListener(ITreeChangeListener listener) {
213         synchronized (mTreeChangeListeners) {
214             mTreeChangeListeners.remove(listener);
215         }
216     }
217 }
218