/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.hierarchyviewerlib.models; import com.android.hierarchyviewerlib.device.ViewNode; import com.android.hierarchyviewerlib.device.Window; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Point; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Rectangle; import java.util.ArrayList; public class TreeViewModel { public static final double MAX_ZOOM = 2; public static final double MIN_ZOOM = 0.2; private Window mWindow; private DrawableViewNode mTree; private DrawableViewNode mSelectedNode; private Rectangle mViewport; private double mZoom; private final ArrayList<ITreeChangeListener> mTreeChangeListeners = new ArrayList<ITreeChangeListener>(); private static TreeViewModel sModel; public static TreeViewModel getModel() { if (sModel == null) { sModel = new TreeViewModel(); } return sModel; } public void setData(Window window, ViewNode viewNode) { synchronized (this) { if (mTree != null) { mTree.viewNode.dispose(); } this.mWindow = window; if (viewNode == null) { mTree = null; } else { mTree = new DrawableViewNode(viewNode); mTree.setLeft(); mTree.placeRoot(); } mViewport = null; mZoom = 1; mSelectedNode = null; } notifyTreeChanged(); } public void setSelection(DrawableViewNode selectedNode) { synchronized (this) { this.mSelectedNode = selectedNode; } notifySelectionChanged(); } public void setViewport(Rectangle viewport) { synchronized (this) { this.mViewport = viewport; } notifyViewportChanged(); } public void setZoom(double newZoom) { Point zoomPoint = null; synchronized (this) { if (mTree != null && mViewport != null) { zoomPoint = new Point(mViewport.x + mViewport.width / 2, mViewport.y + mViewport.height / 2); } } zoomOnPoint(newZoom, zoomPoint); } public void zoomOnPoint(double newZoom, Point zoomPoint) { synchronized (this) { if (mTree != null && this.mViewport != null) { if (newZoom < MIN_ZOOM) { newZoom = MIN_ZOOM; } if (newZoom > MAX_ZOOM) { newZoom = MAX_ZOOM; } mViewport.x = zoomPoint.x - (zoomPoint.x - mViewport.x) * mZoom / newZoom; mViewport.y = zoomPoint.y - (zoomPoint.y - mViewport.y) * mZoom / newZoom; mViewport.width = mViewport.width * mZoom / newZoom; mViewport.height = mViewport.height * mZoom / newZoom; mZoom = newZoom; } } notifyZoomChanged(); } public DrawableViewNode getTree() { synchronized (this) { return mTree; } } public Window getWindow() { synchronized (this) { return mWindow; } } public Rectangle getViewport() { synchronized (this) { return mViewport; } } public double getZoom() { synchronized (this) { return mZoom; } } public DrawableViewNode getSelection() { synchronized (this) { return mSelectedNode; } } public static interface ITreeChangeListener { public void treeChanged(); public void selectionChanged(); public void viewportChanged(); public void zoomChanged(); } private ITreeChangeListener[] getTreeChangeListenerList() { ITreeChangeListener[] listeners = null; synchronized (mTreeChangeListeners) { if (mTreeChangeListeners.size() == 0) { return null; } listeners = mTreeChangeListeners.toArray(new ITreeChangeListener[mTreeChangeListeners.size()]); } return listeners; } public void notifyTreeChanged() { ITreeChangeListener[] listeners = getTreeChangeListenerList(); if (listeners != null) { for (int i = 0; i < listeners.length; i++) { listeners[i].treeChanged(); } } } public void notifySelectionChanged() { ITreeChangeListener[] listeners = getTreeChangeListenerList(); if (listeners != null) { for (int i = 0; i < listeners.length; i++) { listeners[i].selectionChanged(); } } } public void notifyViewportChanged() { ITreeChangeListener[] listeners = getTreeChangeListenerList(); if (listeners != null) { for (int i = 0; i < listeners.length; i++) { listeners[i].viewportChanged(); } } } public void notifyZoomChanged() { ITreeChangeListener[] listeners = getTreeChangeListenerList(); if (listeners != null) { for (int i = 0; i < listeners.length; i++) { listeners[i].zoomChanged(); } } } public void addTreeChangeListener(ITreeChangeListener listener) { synchronized (mTreeChangeListeners) { mTreeChangeListeners.add(listener); } } public void removeTreeChangeListener(ITreeChangeListener listener) { synchronized (mTreeChangeListeners) { mTreeChangeListeners.remove(listener); } } }