blob: 08dc39590ec468f9898948694eb913b6683a094a [file] [log] [blame]
/*
* Copyright (C) 2008 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.hierarchyviewer.scene;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import org.netbeans.api.visual.action.ActionFactory;
import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.anchor.AnchorFactory;
import org.netbeans.api.visual.border.BorderFactory;
import org.netbeans.api.visual.graph.GraphScene;
import org.netbeans.api.visual.layout.LayoutFactory;
import org.netbeans.api.visual.model.ObjectState;
import org.netbeans.api.visual.widget.ConnectionWidget;
import org.netbeans.api.visual.widget.LabelWidget;
import org.netbeans.api.visual.widget.LayerWidget;
import org.netbeans.api.visual.widget.Widget;
public class ViewHierarchyScene extends GraphScene<ViewNode, String> {
private ViewNode root;
private LayerWidget widgetLayer;
private LayerWidget connectionLayer;
private WidgetAction moveAction = ActionFactory.createMoveAction();
public ViewHierarchyScene() {
widgetLayer = new LayerWidget(this);
connectionLayer = new LayerWidget(this);
addChild(widgetLayer);
addChild(connectionLayer);
}
public ViewNode getRoot() {
return root;
}
void setRoot(ViewNode root) {
this.root = root;
}
@Override
protected Widget attachNodeWidget(ViewNode node) {
Widget widget = createBox(node, node.name, node.id);
widget.getActions().addAction(createSelectAction());
widget.getActions().addAction(moveAction);
widgetLayer.addChild(widget);
return widget;
}
private Widget createBox(ViewNode node, String nodeName, String id) {
final String shortName = getShortName(nodeName);
node.setShortName(shortName);
GradientWidget box = new GradientWidget(this, node);
box.setLayout(LayoutFactory.createVerticalFlowLayout());
box.setBorder(BorderFactory.createLineBorder(2, Color.BLACK));
box.setOpaque(true);
LabelWidget label = new LabelWidget(this);
label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 12.0f));
label.setLabel(shortName);
label.setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 6));
label.setAlignment(LabelWidget.Alignment.CENTER);
box.addChild(label);
label = new LabelWidget(this);
label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f));
label.setLabel(getAddress(nodeName));
label.setBorder(BorderFactory.createEmptyBorder(3, 6, 0, 6));
label.setAlignment(LabelWidget.Alignment.CENTER);
box.addressWidget = label;
box.addChild(label);
label = new LabelWidget(this);
label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f));
label.setLabel(id);
label.setBorder(BorderFactory.createEmptyBorder(3, 6, 6, 6));
label.setAlignment(LabelWidget.Alignment.CENTER);
box.addChild(label);
return box;
}
private static String getAddress(String name) {
String[] nameAndHashcode = name.split("@");
return "@" + nameAndHashcode[1];
}
private static String getShortName(String name) {
String[] nameAndHashcode = name.split("@");
String[] packages = nameAndHashcode[0].split("\\.");
return packages[packages.length - 1];
}
@Override
protected Widget attachEdgeWidget(String edge) {
ConnectionWidget connectionWidget = new ConnectionWidget(this);
connectionLayer.addChild(connectionWidget);
return connectionWidget;
}
@Override
protected void attachEdgeSourceAnchor(String edge, ViewNode oldSourceNode, ViewNode sourceNode) {
final ConnectionWidget connection = (ConnectionWidget) findWidget(edge);
final Widget source = findWidget(sourceNode);
connection.bringToBack();
source.bringToFront();
connection.setSourceAnchor(AnchorFactory.createRectangularAnchor(source));
}
@Override
protected void attachEdgeTargetAnchor(String edge, ViewNode oldTargetNode, ViewNode targetNode) {
final ConnectionWidget connection = (ConnectionWidget) findWidget(edge);
final Widget target = findWidget(targetNode);
connection.bringToBack();
target.bringToFront();
connection.setTargetAnchor(AnchorFactory.createRectangularAnchor(target));
}
private static class GradientWidget extends Widget implements ViewNode.StateListener {
public static final GradientPaint BLUE_EXPERIENCE = new GradientPaint(
new Point2D.Double(0, 0),
new Color(168, 204, 241),
new Point2D.Double(0, 1),
new Color(44, 61, 146));
public static final GradientPaint MAC_OSX_SELECTED = new GradientPaint(
new Point2D.Double(0, 0),
new Color(81, 141, 236),
new Point2D.Double(0, 1),
new Color(36, 96, 192));
public static final GradientPaint MAC_OSX = new GradientPaint(
new Point2D.Double(0, 0),
new Color(167, 210, 250),
new Point2D.Double(0, 1),
new Color(99, 147, 206));
public static final GradientPaint AERITH = new GradientPaint(
new Point2D.Double(0, 0),
Color.WHITE,
new Point2D.Double(0, 1),
new Color(64, 110, 161));
public static final GradientPaint GRAY = new GradientPaint(
new Point2D.Double(0, 0),
new Color(226, 226, 226),
new Point2D.Double(0, 1),
new Color(250, 248, 248));
public static final GradientPaint RED_XP = new GradientPaint(
new Point2D.Double(0, 0),
new Color(236, 81, 81),
new Point2D.Double(0, 1),
new Color(192, 36, 36));
public static final GradientPaint NIGHT_GRAY = new GradientPaint(
new Point2D.Double(0, 0),
new Color(102, 111, 127),
new Point2D.Double(0, 1),
new Color(38, 45, 61));
public static final GradientPaint NIGHT_GRAY_LIGHT = new GradientPaint(
new Point2D.Double(0, 0),
new Color(129, 138, 155),
new Point2D.Double(0, 1),
new Color(58, 66, 82));
public static final GradientPaint NIGHT_GRAY_VERY_LIGHT = new GradientPaint(
new Point2D.Double(0, 0),
new Color(129, 138, 155, 60),
new Point2D.Double(0, 1),
new Color(58, 66, 82, 60));
private static Color UNSELECTED = Color.BLACK;
private static Color SELECTED = Color.WHITE;
private final ViewNode node;
private LabelWidget addressWidget;
private boolean isSelected = false;
private final GradientPaint selectedGradient = MAC_OSX_SELECTED;
private final GradientPaint filteredGradient = RED_XP;
private final GradientPaint focusGradient = NIGHT_GRAY_VERY_LIGHT;
public GradientWidget(ViewHierarchyScene scene, ViewNode node) {
super(scene);
this.node = node;
node.setStateListener(this);
}
@Override
protected void notifyStateChanged(ObjectState previous, ObjectState state) {
super.notifyStateChanged(previous, state);
isSelected = state.isSelected() || state.isFocused() || state.isWidgetFocused();
pickChildrenColor();
}
private void pickChildrenColor() {
for (Widget child : getChildren()) {
child.setForeground(isSelected || node.filtered ? SELECTED : UNSELECTED);
}
repaint();
}
@Override
protected void paintBackground() {
super.paintBackground();
Graphics2D g2 = getGraphics();
Rectangle bounds = getBounds();
if (!isSelected) {
if (!node.filtered) {
if (!node.hasFocus) {
g2.setColor(Color.WHITE);
} else {
g2.setPaint(new GradientPaint(bounds.x, bounds.y,
focusGradient.getColor1(), bounds.x, bounds.x + bounds.height,
focusGradient.getColor2()));
}
} else {
g2.setPaint(new GradientPaint(bounds.x, bounds.y, filteredGradient.getColor1(),
bounds.x, bounds.x + bounds.height, filteredGradient.getColor2()));
}
} else {
g2.setPaint(new GradientPaint(bounds.x, bounds.y, selectedGradient.getColor1(),
bounds.x, bounds.x + bounds.height, selectedGradient.getColor2()));
}
g2.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
public void nodeStateChanged(ViewNode node) {
pickChildrenColor();
}
public void nodeIndexChanged(ViewNode node) {
if (addressWidget != null) {
addressWidget.setLabel("#" + node.index + addressWidget.getLabel());
}
}
}
}