/* * Copyright 2006-2012 ICEsoft Technologies Inc. * * 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 org.icepdf.core.views.swing; import org.icepdf.core.util.ColorUtil; import org.icepdf.core.util.Defs; import org.icepdf.core.views.AnnotationComponent; import javax.swing.*; import javax.swing.border.AbstractBorder; import java.awt.*; import java.awt.event.MouseEvent; import java.util.logging.Level; import java.util.logging.Logger; /** * The resizable border is mainly designed to bed used with mutable annotation * in the UI but supect it could be used for ather content manipulation. Like * other Swing Borders the same instance can be used on multiple components. * * @since 4.0 */ public class ResizableBorder extends AbstractBorder { private static final Logger logger = Logger.getLogger(ResizableBorder.class.toString()); private static Color selectColor; private static Color outlineColor; static { // sets annotation selected highlight colour try { String color = Defs.sysProperty( "org.icepdf.core.views.page.annotation.select.color", "#0000FF"); int colorValue = ColorUtil.convertColor(color); selectColor = new Color(colorValue >= 0 ? colorValue : Integer.parseInt("0000FF", 16)); color = Defs.sysProperty( "org.icepdf.core.views.page.annotation.outline.color", "#000000"); colorValue = ColorUtil.convertColor(color); outlineColor = new Color(colorValue >= 0 ? colorValue : Integer.parseInt("000000", 16)); } catch (NumberFormatException e) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Error reading page annotation outline colour"); } } } private static final int locations[] = { SwingConstants.NORTH, SwingConstants.SOUTH, SwingConstants.WEST, SwingConstants.EAST, SwingConstants.NORTH_WEST, SwingConstants.NORTH_EAST, SwingConstants.SOUTH_WEST, SwingConstants.SOUTH_EAST }; private static final int cursors[] = { Cursor.N_RESIZE_CURSOR, Cursor.S_RESIZE_CURSOR, Cursor.W_RESIZE_CURSOR, Cursor.E_RESIZE_CURSOR, Cursor.NW_RESIZE_CURSOR, Cursor.NE_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR, Cursor.SE_RESIZE_CURSOR }; protected int resizeWidgetDim; public ResizableBorder(int resizeBoxSize) { this.resizeWidgetDim = resizeBoxSize; } public Insets getBorderInsets(Component component) { return new Insets(10,10, 10, 10); } public boolean isBorderOpaque() { return false; } public void paintBorder(Component component, Graphics g, int x, int y, int w, int h) { boolean isSelected = false; boolean isEditable = false; boolean isRollover = false; boolean isLinkAnnot = false; boolean isBorderStyle = false; // get render flags from component. if (component instanceof AnnotationComponent){ AnnotationComponent annot = (AnnotationComponent) component; isEditable = annot.isEditable(); isRollover = annot.isRollover(); isLinkAnnot = annot.isLinkAnnot(); isBorderStyle = annot.isBorderStyle(); isSelected = annot.isSelected(); } // if we aren't in the edit mode, then we have nothing to paint. if (!isEditable){ return; } // get paint colour if (isSelected || component.hasFocus() || isRollover){ g.setColor(selectColor); } else{ g.setColor(outlineColor); } // paint border if (isSelected || isRollover || (isLinkAnnot && !isBorderStyle)){ g.drawRect(x, y, w-1, h-1); } // paint resize widgets. if ((isSelected || isRollover) && isLinkAnnot){ for (int location : locations) { Rectangle rect = getRectangle(x, y, w, h, location); // g.setColor(Color.WHITE); g.fillRect(rect.x, rect.y, rect.width - 1, rect.height - 1); // g.setColor(Color.BLACK); g.drawRect(rect.x, rect.y, rect.width - 1, rect.height - 1); } } } private Rectangle getRectangle(int x, int y, int w, int h, int location) { switch (location) { case SwingConstants.NORTH: return new Rectangle(x + w / 2 - resizeWidgetDim / 2, y, resizeWidgetDim, resizeWidgetDim); case SwingConstants.SOUTH: return new Rectangle(x + w / 2 - resizeWidgetDim / 2, y + h - resizeWidgetDim, resizeWidgetDim, resizeWidgetDim); case SwingConstants.WEST: return new Rectangle(x, y + h / 2 - resizeWidgetDim / 2, resizeWidgetDim, resizeWidgetDim); case SwingConstants.EAST: return new Rectangle(x + w - resizeWidgetDim, y + h / 2 - resizeWidgetDim / 2, resizeWidgetDim, resizeWidgetDim); case SwingConstants.NORTH_WEST: return new Rectangle(x, y, resizeWidgetDim, resizeWidgetDim); case SwingConstants.NORTH_EAST: return new Rectangle(x + w - resizeWidgetDim, y, resizeWidgetDim, resizeWidgetDim); case SwingConstants.SOUTH_WEST: return new Rectangle(x, y + h - resizeWidgetDim, resizeWidgetDim, resizeWidgetDim); case SwingConstants.SOUTH_EAST: return new Rectangle(x + w - resizeWidgetDim, y + h - resizeWidgetDim, resizeWidgetDim, resizeWidgetDim); } return null; } public int getCursor(MouseEvent me) { Component c = me.getComponent(); boolean isEditable = false; boolean isLinkAnnot = false; // get render flags from component. if (c instanceof AnnotationComponentImpl){ AnnotationComponentImpl annot = (AnnotationComponentImpl) c; isEditable = annot.isEditable(); isLinkAnnot = annot.isLinkAnnot(); } int w = c.getWidth(); int h = c.getHeight(); // show resize cursors for link annotations if ((isEditable && isLinkAnnot)){ for (int i = 0; i < locations.length; i++) { Rectangle rect = getRectangle(0, 0, w, h, locations[i]); if (rect.contains(me.getPoint())) return cursors[i]; } } // other wise just show the move. return Cursor.MOVE_CURSOR; } }