/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.gui.flow.processrendering.background; import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.awt.RenderingHints; import com.rapidminer.gui.flow.processrendering.draw.ProcessDrawDecorator; import com.rapidminer.gui.flow.processrendering.model.ProcessRendererModel; import com.rapidminer.gui.flow.processrendering.view.ProcessRendererView; import com.rapidminer.gui.flow.processrendering.view.RenderPhase; import com.rapidminer.gui.tools.ProgressThread; import com.rapidminer.gui.tools.ProgressThreadListener; import com.rapidminer.operator.ExecutionUnit; /** * This class handles the draw decorator registered to the {@link ProcessRendererView} for process * background images. * * @author Marco Boeck * @since 7.0.0 * */ public final class ProcessBackgroundImageDecorator { /** minimum alpha value for background images (if zommed in) */ private static final float MIN_OPACITY = 0.15f; /** the process renderer */ private final ProcessRendererView view; /** triggers if the image has been loaded */ private final ProgressThreadListener loadListener; /** draws process (free-flowing) annotations behind operators */ private ProcessDrawDecorator processBackgroundImageDrawer = new ProcessDrawDecorator() { @Override public void draw(final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel) { draw(process, g2, rendererModel, false); } @Override public void print(final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel) { draw(process, g2, rendererModel, true); } /** * Draws the background annotations. */ private void draw(final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel, final boolean printing) { // background annotations ProcessBackgroundImage image = rendererModel.getBackgroundImage(process); if (image != null) { Graphics2D g2D = (Graphics2D) g2.create(); int x = image.getX(); int y = image.getY(); int w = image.getWidth(); int h = image.getHeight(); // center image now if desired if (x == -1) { double processWidth = rendererModel.getProcessWidth(process); x = (int) ((processWidth - w) / 2); } if (y == -1) { double processHeight = rendererModel.getProcessHeight(process); y = (int) ((processHeight - h) / 2); } if (rendererModel.getZoomFactor() > 1.0) { /** fade out background image when zooming in */ float alpha = Math.max(MIN_OPACITY, 2.0f - (float) rendererModel.getZoomFactor()); AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha); g2D.setComposite(ac); } // interpolate scaled background images g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2D.drawImage(image.getImage(loadListener), x, y, w, h, null); g2D.dispose(); } } }; /** * Creates a new process background image decorator * * @param view * the process renderer instance */ public ProcessBackgroundImageDecorator(final ProcessRendererView view) { this.view = view; this.loadListener = new ProgressThreadListener() { @Override public void threadFinished(ProgressThread thread) { // make sure process is rendered again view.getModel().fireMiscChanged(); } }; } /** * Registers the event hooks and draw decorators to the process renderer. */ void registerDecorators() { view.addDrawDecorator(processBackgroundImageDrawer, RenderPhase.BACKGROUND); } /** * Removes the event hooks and draw decorators from the process renderer. */ void unregisterDecorators() { view.removeDrawDecorator(processBackgroundImageDrawer, RenderPhase.BACKGROUND); } }