org.dawnsci.plotting.tools.EllipseFittingTool.java Source code

Java tutorial

Introduction

Here is the source code for org.dawnsci.plotting.tools.EllipseFittingTool.java

Source

/*
 * Copyright (c) 2012 Diamond Light Source Ltd.
 *
 * 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
 */
/*
 * Copyright 2012 Diamond Light Source Ltd.
 * 
 * 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.dawnsci.plotting.tools;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.dawnsci.analysis.api.roi.IROI;
import org.eclipse.dawnsci.analysis.dataset.roi.EllipticalFitROI;
import org.eclipse.dawnsci.analysis.dataset.roi.EllipticalROI;
import org.eclipse.dawnsci.plotting.api.IPlottingSystem;
import org.eclipse.dawnsci.plotting.api.PlottingFactory;
import org.eclipse.dawnsci.plotting.api.region.IEllipseFitSelection;
import org.eclipse.dawnsci.plotting.api.region.IROIListener;
import org.eclipse.dawnsci.plotting.api.region.IRegion;
import org.eclipse.dawnsci.plotting.api.region.IRegionListener;
import org.eclipse.dawnsci.plotting.api.region.ROIEvent;
import org.eclipse.dawnsci.plotting.api.region.RegionEvent;
import org.eclipse.dawnsci.plotting.api.region.RegionUtils;
import org.eclipse.dawnsci.plotting.api.region.IRegion.RegionType;
import org.eclipse.dawnsci.plotting.api.tool.AbstractToolPage;
import org.eclipse.dawnsci.plotting.api.trace.ITraceListener;
import org.eclipse.dawnsci.plotting.api.trace.TraceEvent;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EllipseFittingTool extends AbstractToolPage {
    private final static Logger logger = LoggerFactory.getLogger(EllipseFittingTool.class);

    private Composite composite;
    private IRegionListener ellipseRegionListener;
    private ITraceListener traceListener;
    private IROIListener ellipseROIListener;

    private TableViewer viewer;
    private List<IRegion> ellipses;

    private IEllipseFitSelection cRegion;

    protected boolean circleOnly;

    public EllipseFittingTool() {
        ellipses = new ArrayList<IRegion>(5);

        ellipseRegionListener = new IRegionListener.Stub() {
            @Override
            public void regionsRemoved(RegionEvent evt) {
                updateEllipses(true);
            }

            @Override
            public void regionRemoved(RegionEvent evt) {
                removeEllipse(evt.getRegion());
            }

            @Override
            public void regionAdded(RegionEvent evt) {
                updateEllipse(evt.getRegion());
            }

            @Override
            public void regionCreated(RegionEvent evt) {
                IRegion r = evt.getRegion();
                if (r instanceof IEllipseFitSelection) {
                    ((IEllipseFitSelection) r).setFitCircle(circleOnly);
                }
            }
        };

        ellipseROIListener = new IROIListener.Stub() {
            @Override
            public void roiChanged(ROIEvent evt) {
                updateEllipses(false);
            }
        };

        try {
            setPlottingSystem(PlottingFactory.createPlottingSystem());
            traceListener = new ITraceListener.Stub() {
                @Override
                public void tracesAdded(TraceEvent evt) {

                    if (!(evt.getSource() instanceof List<?>)) {
                        return;
                    }

                }
            };

        } catch (Exception e) {
            logger.error("Cannot get plotting system!", e);
        }
    }

    protected void updateEllipse(IRegion region) {
        if (region == null)
            return;

        if (ellipses.contains(region)) {
            viewer.setSelection(new StructuredSelection(region));
            return;
        }

        if (region.getRegionType() != RegionType.ELLIPSEFIT)
            return;

        region.addROIListener(ellipseROIListener);
        cRegion = (IEllipseFitSelection) region;
        ellipses.add(region);
        viewer.refresh();
        viewer.setSelection(new StructuredSelection(region));
    }

    protected void removeEllipse(IRegion region) {
        if (region == null)
            return;

        if (region.getRegionType() != RegionType.ELLIPSEFIT)
            return;

        if (ellipses.contains(region))
            ellipses.remove(region);

        region.removeROIListener(ellipseROIListener);
        viewer.refresh();
    }

    protected void updateEllipses(boolean removeROIListener) {
        IPlottingSystem plotter = getPlottingSystem();
        if (plotter == null)
            return;

        if (removeROIListener) {
            for (IRegion r : ellipses) {
                r.removeROIListener(ellipseROIListener);
            }
        }
        ellipses.clear();

        Collection<IRegion> regions = plotter.getRegions(RegionType.ELLIPSEFIT);
        if (regions != null && regions.size() > 0) {
            IRegion r = null;
            Iterator<IRegion> it = regions.iterator();
            while (it.hasNext()) {
                r = it.next();
                ellipses.add(r);
                if (removeROIListener) {
                    r.addROIListener(ellipseROIListener);
                }
            }
        }
        if (viewer != null) // can be null during activation
            viewer.refresh();
    }

    @Override
    public ToolPageRole getToolPageRole() {
        return ToolPageRole.ROLE_2D;
    }

    @Override
    public void createControl(Composite parent) {
        composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new FillLayout());

        viewer = new TableViewer(composite,
                SWT.FULL_SELECTION | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);

        createColumns(viewer);
        Table t = viewer.getTable();
        t.setLinesVisible(true);
        t.setHeaderVisible(true);

        createActions();

        getSite().setSelectionProvider(viewer);

        viewer.setContentProvider(new IStructuredContentProvider() {
            @Override
            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            }

            @Override
            public void dispose() {
            }

            @Override
            public Object[] getElements(Object inputElement) {
                return ellipses.toArray();
            }
        });

        viewer.setInput(ellipses);
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                IStructuredSelection s = (IStructuredSelection) event.getSelection();
                IRegion r = (IRegion) s.getFirstElement();
                if (r instanceof IEllipseFitSelection) {
                    cRegion = (IEllipseFitSelection) r;
                    cRegion.setFitCircle(circleOnly);
                }
            }
        });
        parent.layout();
    }

    private void createColumns(final TableViewer viewer) {
        ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.NO_RECREATE);

        int i = 0;
        TableViewerColumn col;
        TableColumn c;

        col = new TableViewerColumn(viewer, SWT.CENTER, i);
        col.setLabelProvider(new EllipseROILabelProvider(i++));
        c = col.getColumn();
        c.setText("ID");
        c.setWidth(100);

        col = new TableViewerColumn(viewer, SWT.CENTER, i);
        col.setLabelProvider(new EllipseROILabelProvider(i++));
        c = col.getColumn();
        c.setText("Major semi-axis");
        c.setWidth(120);

        col = new TableViewerColumn(viewer, SWT.CENTER, i);
        col.setLabelProvider(new EllipseROILabelProvider(i++));
        c = col.getColumn();
        c.setText("Minor semi-axis");
        c.setWidth(120);

        col = new TableViewerColumn(viewer, SWT.CENTER, i);
        col.setLabelProvider(new EllipseROILabelProvider(i++));
        c = col.getColumn();
        c.setText("Angle");
        c.setWidth(75);

        col = new TableViewerColumn(viewer, SWT.CENTER, i);
        col.setLabelProvider(new EllipseROILabelProvider(i++));
        c = col.getColumn();
        c.setText("Centre x");
        c.setWidth(75);

        col = new TableViewerColumn(viewer, SWT.CENTER, i);
        col.setLabelProvider(new EllipseROILabelProvider(i++));
        c = col.getColumn();
        c.setText("Centre y");
        c.setWidth(75);

        col = new TableViewerColumn(viewer, SWT.CENTER, i);
        col.setLabelProvider(new EllipseROILabelProvider(i++));
        c = col.getColumn();
        c.setText("Points");
        c.setWidth(20);
    }

    private void createActions() {
        final Action delete = new Action("Delete selected region",
                Activator.getImageDescriptor("icons/plot-tool-measure-delete.png")) {
            @Override
            public void run() {
                if (!isActive())
                    return;
                final IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();

                if (sel != null && sel.getFirstElement() != null) {
                    final IRegion region = (IRegion) sel.getFirstElement();
                    getPlottingSystem().removeRegion(region);
                    if (region == cRegion)
                        cRegion = null;
                    viewer.refresh();
                }
            }
        };
        delete.setToolTipText("Delete selected region, if there is one.");

        final Action circle = new Action("Use circle for fit", IAction.AS_CHECK_BOX) {
            @Override
            public void run() {
                circleOnly = isChecked();
                logger.debug("Circle fit clicked: {}", circleOnly);

                if (cRegion != null) {
                    cRegion.setFitCircle(circleOnly);

                }
            }
        };
        circle.setImageDescriptor(Activator.getImageDescriptor("icons/fitocircle.png"));
        circle.setToolTipText("Restrict fit to a circle");

        IToolBarManager tbm = getSite().getActionBars().getToolBarManager();
        tbm.add(circle);
        tbm.add(delete);
        IMenuManager mm = getSite().getActionBars().getMenuManager();
        mm.add(circle);
        mm.add(delete);
    }

    class EllipseROILabelProvider extends ColumnLabelProvider {
        private final int column;

        public EllipseROILabelProvider(int i) {
            column = i;
        }

        @Override
        public String getText(Object element) {

            IROI rb = ((IRegion) element).getROI();

            if (!(rb instanceof EllipticalROI)) {
                return null;
            }
            EllipticalROI eroi = (EllipticalROI) rb;

            switch (column) {
            case 0:
                return ((IRegion) element).getName();
            case 1:
                return String.format("%.2f", eroi.getSemiAxis(0));
            case 2:
                return String.format("%.2f", eroi.getSemiAxis(1));
            case 3:
                return String.format("%.2f", eroi.getAngleDegrees());
            case 4:
                return String.format("%.2f", eroi.getPointX());
            case 5:
                return String.format("%.2f", eroi.getPointY());
            case 6:
                if (eroi instanceof EllipticalFitROI) {
                    EllipticalFitROI froi = (EllipticalFitROI) eroi;
                    return Integer.toString(froi.getPoints().getNumberOfPoints());
                }
                return "--";
            }
            return null;
        }
    }

    @Override
    public void activate() {
        super.activate();
        IPlottingSystem plotter = getPlottingSystem();
        if (plotter == null)
            return;

        if (traceListener != null)
            plotter.addTraceListener(traceListener);
        if (ellipseRegionListener != null)
            plotter.addRegionListener(ellipseRegionListener);

        updateEllipses(true);

        // Start with a selection of the right type
        try {
            cRegion = (IEllipseFitSelection) plotter.createRegion(RegionUtils.getUniqueName("Ellipse fit", plotter),
                    RegionType.ELLIPSEFIT);
        } catch (Exception e) {
            logger.error("Cannot create region for ellipse fitting tool!");
        }
    }

    @Override
    public void deactivate() {
        IPlottingSystem plotter = getPlottingSystem();
        if (plotter != null) {
            plotter.removeTraceListener(traceListener);
            plotter.removeRegionListener(ellipseRegionListener);
        }

        super.deactivate();
    }

    @Override
    public Control getControl() {
        return composite;
    }

    @Override
    public void setFocus() {
    }
}