/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.core.ui.editor.image; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.util.ArrayList; import java.util.List; import java.util.Optional; import javax.swing.AbstractButton; import javax.swing.Box; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JPopupMenu; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.event.ListDataEvent; import org.weasis.core.api.gui.util.ActionW; import org.weasis.core.api.gui.util.ComboItemListener; import org.weasis.core.api.gui.util.DropButtonIcon; import org.weasis.core.api.gui.util.DropDownButton; import org.weasis.core.api.gui.util.GroupRadioMenu; import org.weasis.core.api.gui.util.RadioMenuItem; import org.weasis.core.api.service.BundleTools; import org.weasis.core.api.service.WProperties; import org.weasis.core.ui.Messages; import org.weasis.core.ui.editor.image.dockable.MeasureTool; import org.weasis.core.ui.model.GraphicModel; import org.weasis.core.ui.model.graphic.DragGraphic; import org.weasis.core.ui.model.graphic.Graphic; import org.weasis.core.ui.model.graphic.imp.AnnotationGraphic; import org.weasis.core.ui.model.graphic.imp.PixelInfoGraphic; import org.weasis.core.ui.model.graphic.imp.angle.AngleToolGraphic; import org.weasis.core.ui.model.graphic.imp.angle.CobbAngleToolGraphic; import org.weasis.core.ui.model.graphic.imp.angle.FourPointsAngleToolGraphic; import org.weasis.core.ui.model.graphic.imp.angle.OpenAngleToolGraphic; import org.weasis.core.ui.model.graphic.imp.area.EllipseGraphic; import org.weasis.core.ui.model.graphic.imp.area.PolygonGraphic; import org.weasis.core.ui.model.graphic.imp.area.RectangleGraphic; import org.weasis.core.ui.model.graphic.imp.area.SelectGraphic; import org.weasis.core.ui.model.graphic.imp.area.ThreePointsCircleGraphic; import org.weasis.core.ui.model.graphic.imp.line.LineGraphic; import org.weasis.core.ui.model.graphic.imp.line.ParallelLineGraphic; import org.weasis.core.ui.model.graphic.imp.line.PerpendicularLineGraphic; import org.weasis.core.ui.model.graphic.imp.line.PolylineGraphic; import org.weasis.core.ui.model.layer.LayerType; import org.weasis.core.ui.pref.ViewSetting; import org.weasis.core.ui.util.WtoolBar; @SuppressWarnings("serial") public class MeasureToolBar extends WtoolBar { private static final long serialVersionUID = -6672565963157176685L; public static final SelectGraphic selectionGraphic = new SelectGraphic(); public static final Icon MeasureIcon = new ImageIcon(MouseActions.class.getResource("/icon/32x32/measure.png")); //$NON-NLS-1$ public static final Icon drawIcon = new ImageIcon(MouseActions.class.getResource("/icon/32x32/draw.png")); //$NON-NLS-1$ public static final List<Graphic> measureGraphicList = new ArrayList<>(); public static final List<Graphic> drawGraphicList = new ArrayList<>(); static { WProperties p = BundleTools.SYSTEM_PREFERENCES; if (p.getBooleanProperty("weasis.measure.selection", true)) { //$NON-NLS-1$ measureGraphicList.add(selectionGraphic); } if (p.getBooleanProperty("weasis.measure.line", true)) { //$NON-NLS-1$ measureGraphicList.add(new LineGraphic()); } if (p.getBooleanProperty("weasis.measure.polyline", true)) { //$NON-NLS-1$ measureGraphicList.add(new PolylineGraphic()); } if (p.getBooleanProperty("weasis.measure.rectangle", true)) { //$NON-NLS-1$ measureGraphicList.add(new RectangleGraphic()); } if (p.getBooleanProperty("weasis.measure.ellipse", true)) { //$NON-NLS-1$ measureGraphicList.add(new EllipseGraphic()); } if (p.getBooleanProperty("weasis.measure.threeptcircle", true)) { //$NON-NLS-1$ measureGraphicList.add(new ThreePointsCircleGraphic()); } if (p.getBooleanProperty("weasis.measure.polygon", true)) { //$NON-NLS-1$ measureGraphicList.add(new PolygonGraphic()); } if (p.getBooleanProperty("weasis.measure.perpendicular", true)) { //$NON-NLS-1$ measureGraphicList.add(new PerpendicularLineGraphic()); } if (p.getBooleanProperty("weasis.measure.parallele", true)) { //$NON-NLS-1$ measureGraphicList.add(new ParallelLineGraphic()); } if (p.getBooleanProperty("weasis.measure.angle", true)) { //$NON-NLS-1$ measureGraphicList.add(new AngleToolGraphic()); } if (p.getBooleanProperty("weasis.measure.openangle", true)) { //$NON-NLS-1$ measureGraphicList.add(new OpenAngleToolGraphic()); } if (p.getBooleanProperty("weasis.measure.fourptangle", true)) { //$NON-NLS-1$ measureGraphicList.add(new FourPointsAngleToolGraphic()); } if (p.getBooleanProperty("weasis.measure.cobbangle", true)) { //$NON-NLS-1$ measureGraphicList.add(new CobbAngleToolGraphic()); } if (p.getBooleanProperty("weasis.measure.pixelinfo", true)) { //$NON-NLS-1$ measureGraphicList.add(new PixelInfoGraphic()); } measureGraphicList.forEach(g -> g.setLayerType(LayerType.MEASURE)); if (p.getBooleanProperty("weasis.draw.selection", true)) { //$NON-NLS-1$ drawGraphicList.add(selectionGraphic); } if (p.getBooleanProperty("weasis.draw.line", true)) { //$NON-NLS-1$ drawGraphicList.add(new LineGraphic() { @Override public int getKeyCode() { return 0; } }); } if (p.getBooleanProperty("weasis.draw.polyline", true)) { //$NON-NLS-1$ drawGraphicList.add(new PolylineGraphic()); } if (p.getBooleanProperty("weasis.draw.rectangle", true)) { //$NON-NLS-1$ drawGraphicList.add(new RectangleGraphic()); } if (p.getBooleanProperty("weasis.draw.ellipse", true)) { //$NON-NLS-1$ drawGraphicList.add(new EllipseGraphic()); } if (p.getBooleanProperty("weasis.draw.threeptcircle", true)) { //$NON-NLS-1$ drawGraphicList.add(new ThreePointsCircleGraphic()); } if (p.getBooleanProperty("weasis.draw.polygon", true)) { //$NON-NLS-1$ drawGraphicList.add(new PolygonGraphic() { @Override public int getKeyCode() { return 0; } }); } drawGraphicList.forEach(g -> { g.setLayerType(LayerType.DRAW); g.setLabelVisible(false); }); if (p.getBooleanProperty("weasis.draw.textGrahic", true)) { //$NON-NLS-1$ Graphic graphic = new AnnotationGraphic(); graphic.setLayerType(LayerType.ANNOTATION); drawGraphicList.add(graphic); } selectionGraphic.setLayerType(LayerType.TEMP_DRAW); } protected final JButton jButtondelete = new JButton(); protected final JButton jButtonText = new JButton(); protected final Component measureButtonGap = Box.createRigidArea(new Dimension(10, 0)); protected final ImageViewerEventManager<?> eventManager; @SuppressWarnings("rawtypes") public MeasureToolBar(final ImageViewerEventManager<?> eventManager, int index) { super(Messages.getString("MeasureToolBar.title"), index); //$NON-NLS-1$ if (eventManager == null) { throw new IllegalArgumentException("EventManager cannot be null"); //$NON-NLS-1$ } this.eventManager = eventManager; MeasureToolBar.measureGraphicList.forEach(g -> MeasureToolBar.applyDefaultSetting(MeasureTool.viewSetting, g)); MeasureToolBar.drawGraphicList.forEach(g -> MeasureToolBar.applyDefaultSetting(MeasureTool.viewSetting, g)); Optional<ComboItemListener> measure = eventManager.getAction(ActionW.DRAW_MEASURE, ComboItemListener.class); Optional<ComboItemListener> draw = eventManager.getAction(ActionW.DRAW_GRAPHICS, ComboItemListener.class); if (measure.isPresent()) { add(buildButton(measure.get())); } if (draw.isPresent()) { add(buildButton(draw.get())); } if (measure.isPresent() || draw.isPresent()) { jButtondelete.setToolTipText(Messages.getString("MeasureToolBar.del")); //$NON-NLS-1$ jButtondelete.setIcon(new ImageIcon(MouseActions.class.getResource("/icon/32x32/draw-delete.png"))); //$NON-NLS-1$ jButtondelete.addActionListener(e -> { GraphicModel gm = eventManager.getSelectedViewPane().getGraphicManager(); if (gm.getSelectedGraphics().isEmpty()) { gm.setSelectedAllGraphics(); } gm.deleteSelectedGraphics(eventManager.getSelectedViewPane(), Boolean.TRUE); }); if (measure.isPresent()) { measure.get().registerActionState(jButtondelete); } else if (draw.isPresent()) { draw.get().registerActionState(jButtondelete); } add(jButtondelete); } } public static void applyDefaultSetting(ViewSetting setting, Graphic graphic) { if (graphic instanceof DragGraphic) { DragGraphic g = (DragGraphic) graphic; g.setLineThickness((float) setting.getLineWidth()); g.setPaint(setting.getLineColor()); } } private DropDownButton buildButton(ComboItemListener<?> action) { boolean draw = action.getActionW() == ActionW.DRAW_GRAPHICS; MeasureGroupMenu menu = new MeasureGroupMenu(action.getActionW()); action.registerActionState(menu); for (Component mitem : menu.getRadioMenuItemListCopy()) { RadioMenuItem ritem = (RadioMenuItem) mitem; if (ritem.getUserObject() instanceof Graphic) { Graphic g = (Graphic) ritem.getUserObject(); if (g.getKeyCode() != 0) { ritem.setAccelerator(KeyStroke.getKeyStroke(g.getKeyCode(), g.getModifier())); } } } DropDownButton dropDownButton = new DropDownButton(action.getActionW().cmd(), buildIcon(selectionGraphic, draw ? drawIcon : MeasureIcon), menu) { @Override protected JPopupMenu getPopupMenu() { JPopupMenu m = (getMenuModel() == null) ? new JPopupMenu() : getMenuModel().createJPopupMenu(); m.setInvoker(this); return m; } }; menu.setButton(dropDownButton); action.registerActionState(dropDownButton); dropDownButton.setToolTipText(draw ? Messages.getString("MeasureToolBar.drawing_tools") : Messages.getString("MeasureToolBar.tools")); //$NON-NLS-1$//$NON-NLS-2$ // when user press the measure icon, set the action to measure dropDownButton.addActionListener(e -> { ImageViewerPlugin<?> view = eventManager.getSelectedView2dContainer(); if (view != null) { @SuppressWarnings("rawtypes") final ViewerToolBar toolBar = view.getViewerToolBar(); if (toolBar != null) { String cmd = draw ? ActionW.DRAW.cmd() : ActionW.MEASURE.cmd(); if (!toolBar.isCommandActive(cmd)) { MouseActions mouseActions = eventManager.getMouseActions(); mouseActions.setAction(MouseActions.LEFT, cmd); view.setMouseActions(mouseActions); toolBar.changeButtonState(MouseActions.LEFT, cmd); } } } }); return dropDownButton; } public static Icon buildIcon(final Graphic graphic, Icon bckIcon) { return new DropButtonIcon(new Icon() { @Override public void paintIcon(Component c, Graphics g, int x, int y) { if (c instanceof AbstractButton) { AbstractButton model = (AbstractButton) c; Icon icon = null; if (!model.isEnabled()) { icon = UIManager.getLookAndFeel().getDisabledIcon(model, bckIcon); } if (icon == null) { icon = bckIcon; } icon.paintIcon(c, g, x, y); if (graphic != null) { Icon smallIcon = null; if (!model.isEnabled()) { smallIcon = UIManager.getLookAndFeel().getDisabledIcon(model, graphic.getIcon()); } if (smallIcon == null) { smallIcon = graphic.getIcon(); } if (smallIcon != null) { int offsetx = bckIcon.getIconWidth() - smallIcon.getIconWidth() - 1; int offsety = bckIcon.getIconHeight() - smallIcon.getIconHeight() - 1; smallIcon.paintIcon(c, g, x + offsetx, y + offsety); } } } } @Override public int getIconWidth() { return bckIcon.getIconWidth(); } @Override public int getIconHeight() { return bckIcon.getIconHeight(); } }); } static class MeasureGroupMenu extends GroupRadioMenu<Graphic> { private ActionW action; private JButton button; public MeasureGroupMenu(ActionW action) { super(); this.action = action; } @Override public void contentsChanged(ListDataEvent e) { super.contentsChanged(e); changeButtonState(); } public void changeButtonState() { Object sel = dataModel.getSelectedItem(); if (sel instanceof Graphic && button != null) { Icon icon = buildIcon((Graphic) sel, action == ActionW.DRAW_GRAPHICS ? drawIcon : MeasureIcon); button.setIcon(icon); button.setActionCommand(sel.toString()); } } public JButton getButton() { return button; } public void setButton(JButton button) { this.button = button; } } }