blob: 99a74bdeee24a55e28dd95c32326f4f4bec64498 [file] [log] [blame]
/*
* Copyright (C) 2015 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.tools.idea.uibuilder.surface;
import com.android.annotations.NonNull;
import com.android.tools.idea.rendering.RenderResult;
import com.android.tools.idea.uibuilder.api.ViewHandler;
import com.android.tools.idea.uibuilder.handlers.ViewHandlerManager;
import com.android.tools.idea.uibuilder.model.NlComponent;
import com.android.tools.idea.uibuilder.model.NlModel;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import static com.android.tools.idea.uibuilder.graphics.NlConstants.*;
import static com.android.tools.idea.uibuilder.model.Coordinates.*;
public class BlueprintLayer extends Layer {
private final ScreenView myScreenView;
public BlueprintLayer(@NonNull ScreenView screenView) {
myScreenView = screenView;
}
@Override
public void paint(@NonNull Graphics2D gc) {
int tlx = myScreenView.getX();
int tly = myScreenView.getY();
NlModel myModel = myScreenView.getModel();
ViewHandlerManager viewHandlerManager = ViewHandlerManager.get(myModel.getFacet());
RenderResult renderResult = myModel.getRenderResult();
if (renderResult == null || renderResult.getImage() == null) {
return;
}
BufferedImage originalImage = renderResult.getImage().getOriginalImage();
gc.setColor(BLUEPRINT_BG_COLOR);
double scale = myScreenView.getScale();
int width = (int)(originalImage.getWidth() * scale);
int height = (int)(originalImage.getHeight() * scale);
gc.fillRect(tlx, tly, width, height);
gc.setColor(BLUEPRINT_GRID_COLOR);
int gridSize = 16;
for (int x = gridSize; x < width - 1; x += gridSize) {
gc.drawLine(tlx + x, tly, tlx + x, tly + height - 1);
}
for (int y = gridSize; y < height - 1; y += gridSize) {
gc.drawLine(tlx, tly + y, tlx + width - 1, tly + y);
}
for (NlComponent component : myScreenView.getModel().getComponents()) {
drawComponent(gc, component, viewHandlerManager);
}
}
private void drawComponent(@NonNull Graphics2D gc, @NonNull NlComponent component, @NonNull ViewHandlerManager viewHandlerManager) {
if (component.viewInfo != null) {
String className = component.viewInfo.getClassName();
int x = getSwingX(myScreenView, component.x);
int y = getSwingY(myScreenView, component.y);
int w = getSwingDimension(myScreenView, component.w);
int h = getSwingDimension(myScreenView, component.h);
gc.setColor(BLUEPRINT_FG_COLOR);
Stroke prevStroke = gc.getStroke();
gc.setStroke(BLUEPRINT_COMPONENT_STROKE);
gc.drawRect(x, y, w - 1, h - 1);
gc.setStroke(prevStroke);
className = className.substring(className.lastIndexOf('.') + 1);
if (className.equals("FloatingActionButton")) {
className = "FAB";
}
Font font = BLUEPRINT_TEXT_FONT;
gc.setFont(font);
String id = component.getId();
int lineHeight = gc.getFontMetrics().getHeight();
FontRenderContext fontRenderContext = gc.getFontRenderContext();
if (id != null && h > lineHeight * 2) {
// Can fit both
Rectangle2D classBounds = font.getStringBounds(className, fontRenderContext);
Rectangle2D idBounds = font.getStringBounds(id, fontRenderContext);
int textY = y + h / 2;
int textX = x + w / 2 - ((int)classBounds.getWidth()) / 2;
gc.drawString(className, textX, textY);
textX = x + w / 2 - ((int)idBounds.getWidth()) / 2;
textY += (int)(idBounds.getHeight());
gc.drawString(id, textX, textY);
}
else {
// Only room for a single line: prioritize the id if it's available, otherwise the class name
String text = id != null ? id : className;
Rectangle2D stringBounds = font.getStringBounds(text, fontRenderContext);
int textX = x + w / 2 - ((int)stringBounds.getWidth()) / 2;
int textY = y + h / 2 + ((int)stringBounds.getHeight()) / 2;
gc.drawString(text, textX, textY);
}
ViewHandler handler = viewHandlerManager.getHandler(className);
if (handler != null) {
if (handler.paintConstraints(myScreenView, gc, component)) {
return;
}
}
}
for (NlComponent child : component.getChildren()) {
drawComponent(gc, child, viewHandlerManager);
}
}
}