001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.vtk;
020
021import java.awt.event.KeyEvent;
022import java.awt.event.MouseEvent;
023import java.awt.event.MouseWheelEvent;
024import java.util.Timer;
025import java.util.TimerTask;
026
027import icy.preferences.CanvasPreferences;
028import icy.util.EventUtil;
029import vtk.vtkActor;
030import vtk.vtkPanel;
031import vtk.vtkPropPicker;
032
033/**
034 * @deprecated Use {@link IcyVtkPanel} instead
035 * @author stephane
036 */
037public class IcyVtkPanelOld extends vtkPanel
038{
039    /**
040     * 
041     */
042    private static final long serialVersionUID = -8455671369400627703L;
043
044    protected Timer timer;
045    final protected vtkPropPicker picker;
046
047    public IcyVtkPanelOld()
048    {
049        super();
050
051        // used for restore quality rendering after mouse wheel
052        timer = new Timer("Timer - vtkPanel");
053        // picker
054        picker = new vtkPropPicker();
055        // set ambient color to white
056        lgt.SetAmbientColor(1d, 1d, 1d);
057    }
058
059    @Override
060    public void Delete()
061    {
062        super.Delete();
063
064        // important to release timer here
065        timer.cancel();
066    }
067
068    @Override
069    public void removeNotify()
070    {
071        super.removeNotify();
072
073        // important to release timer here
074        timer.cancel();
075    }
076
077    @Override
078    public void setBounds(int x, int y, int width, int height)
079    {
080        super.setBounds(x, y, width, height);
081
082        if (windowset == 1)
083        {
084            Lock();
085            rw.SetSize(width, height);
086            UnLock();
087        }
088    }
089
090    @SuppressWarnings("deprecation")
091    @Override
092    public void setSize(int w, int h)
093    {
094        // have to use this to by-pass the wrong vtkPanel implementation
095        resize(w, h);
096    }
097
098    @Override
099    public void mouseEntered(MouseEvent e)
100    {
101        // nothing to do here
102    }
103
104    @Override
105    public void mouseExited(MouseEvent e)
106    {
107        // nothing to do here
108    }
109
110    @Override
111    public void mouseClicked(MouseEvent e)
112    {
113        if (e.isConsumed())
114            return;
115
116        // nothing to do here
117    }
118
119    @Override
120    public void mouseMoved(MouseEvent e)
121    {
122        // just save mouse position
123        lastX = e.getX();
124        lastY = e.getY();
125    }
126
127    @Override
128    public void mouseDragged(MouseEvent e)
129    {
130        // camera not yet defined --> exit
131        if (cam == null)
132            return;
133
134        if (e.isConsumed())
135            return;
136        if (ren.VisibleActorCount() == 0)
137            return;
138
139        // cancel pending task
140        timer.cancel();
141
142        // get current mouse position
143        final int x = e.getX();
144        final int y = e.getY();
145        int deltaX = (lastX - x);
146        int deltaY = (lastY - y);
147
148        // faster movement with control modifier
149        if (EventUtil.isControlDown(e))
150        {
151            deltaX *= 3;
152            deltaY *= 3;
153        }
154
155        if (EventUtil.isRightMouseButton(e) || (EventUtil.isLeftMouseButton(e) && EventUtil.isShiftDown(e)))
156            // translation mode
157            translateView(-deltaX, deltaY);
158        else if (EventUtil.isLeftMouseButton(e))
159            // rotation mode
160            rotateView(deltaX, -deltaY);
161        else
162            // zoom mode
163            zoomView(Math.pow(1.02, -deltaY));
164
165        // save mouse position
166        lastX = x;
167        lastY = y;
168        // request repaint
169        repaint();
170    }
171
172    @Override
173    public void mousePressed(MouseEvent e)
174    {
175        if (e.isConsumed())
176            return;
177        if (ren.VisibleActorCount() == 0)
178            return;
179
180        // want fast update
181        setCoarseRendering(0);
182    }
183
184    @Override
185    public void mouseReleased(MouseEvent e)
186    {
187        // restore quality rendering
188        setFineRendering(1000);
189    }
190
191    @Override
192    public void mouseWheelMoved(MouseWheelEvent e)
193    {
194        // camera not yet defined --> exit
195        if (cam == null)
196            return;
197
198        // want fast update
199        setCoarseRendering(0);
200
201        // get delta
202        double delta = e.getWheelRotation() * CanvasPreferences.getMouseWheelSensitivity();
203        if (CanvasPreferences.getInvertMouseWheelAxis())
204            delta = -delta;
205
206        // faster movement with control modifier
207        if (EventUtil.isControlDown(e))
208            delta *= 3d;
209
210        zoomView(Math.pow(1.02, delta));
211
212        // request repaint
213        repaint();
214
215        // restore quality rendering
216        setFineRendering(1000);
217    }
218
219    @Override
220    public void keyPressed(KeyEvent e)
221    {
222        if (!e.isConsumed())
223            super.keyPressed(e);
224    }
225
226    @Override
227    public void keyReleased(KeyEvent e)
228    {
229        if (!e.isConsumed())
230            super.keyReleased(e);
231    }
232
233    @Override
234    public void lock()
235    {
236        if (windowset == 0)
237            return;
238
239        super.lock();
240    }
241
242    @Override
243    public void unlock()
244    {
245        if (windowset == 0)
246            return;
247
248        super.unlock();
249    }
250
251    /**
252     * return true if currently rendering
253     */
254    public boolean isRendering()
255    {
256        return rendering;
257    }
258
259    /**
260     * Return picker object.
261     */
262    public vtkPropPicker getPicker()
263    {
264        return picker;
265    }
266
267    /**
268     * Pick object at specified position and return it.
269     */
270    public vtkActor pick(int x, int y)
271    {
272        Lock();
273        picker.PickProp(x, rw.GetSize()[1] - y, ren);
274        UnLock();
275
276        return picker.GetActor();
277    }
278
279    /**
280     * Translate current camera view
281     */
282    public void translateView(double dx, double dy)
283    {
284        // translation mode
285        double FPoint[];
286        double PPoint[];
287        double APoint[] = new double[3];
288        double RPoint[];
289        double focalDepth;
290
291        // get the current focal point and position
292        FPoint = cam.GetFocalPoint();
293        PPoint = cam.GetPosition();
294
295        // calculate the focal depth since we'll be using it a lot
296        ren.SetWorldPoint(FPoint[0], FPoint[1], FPoint[2], 1.0);
297        ren.WorldToDisplay();
298        focalDepth = ren.GetDisplayPoint()[2];
299
300        APoint[0] = rw.GetSize()[0] / 2.0 + dx;
301        APoint[1] = rw.GetSize()[1] / 2.0 + dy;
302        APoint[2] = focalDepth;
303        ren.SetDisplayPoint(APoint);
304        ren.DisplayToWorld();
305        RPoint = ren.GetWorldPoint();
306        if (RPoint[3] != 0.0)
307        {
308            RPoint[0] = RPoint[0] / RPoint[3];
309            RPoint[1] = RPoint[1] / RPoint[3];
310            RPoint[2] = RPoint[2] / RPoint[3];
311        }
312
313        /*
314         * Compute a translation vector, moving everything 1/2 the distance
315         * to the cursor. (Arbitrary scale factor)
316         */
317        cam.SetFocalPoint((FPoint[0] - RPoint[0]) / 2.0 + FPoint[0], (FPoint[1] - RPoint[1]) / 2.0 + FPoint[1],
318                (FPoint[2] - RPoint[2]) / 2.0 + FPoint[2]);
319        cam.SetPosition((FPoint[0] - RPoint[0]) / 2.0 + PPoint[0], (FPoint[1] - RPoint[1]) / 2.0 + PPoint[1],
320                (FPoint[2] - RPoint[2]) / 2.0 + PPoint[2]);
321        resetCameraClippingRange();
322    }
323
324    /**
325     * Rotate current camera view
326     */
327    public void rotateView(int dx, int dy)
328    {
329        // rotation mode
330        cam.Azimuth(dx);
331        cam.Elevation(dy);
332        cam.OrthogonalizeViewUp();
333        resetCameraClippingRange();
334
335        if (LightFollowCamera == 1)
336        {
337            lgt.SetPosition(cam.GetPosition());
338            lgt.SetFocalPoint(cam.GetFocalPoint());
339        }
340    }
341
342    /**
343     * Zoom current view by specified factor (negative value means unzoom)
344     */
345    public void zoomView(double factor)
346    {
347        if (cam.GetParallelProjection() == 1)
348            cam.SetParallelScale(cam.GetParallelScale() / factor);
349        else
350        {
351            cam.Dolly(factor);
352            resetCameraClippingRange();
353        }
354    }
355
356    /**
357     * Set coarse and fast rendering mode immediately
358     * 
359     * @see #setCoarseRendering(long)
360     */
361    public void setCoarseRendering()
362    {
363        // set fast rendering
364        rw.SetDesiredUpdateRate(10.0);
365    }
366
367    /**
368     * Set fine (and possibly slow) rendering immediately
369     * 
370     * @see #setFineRendering(long)
371     */
372    public void setFineRendering()
373    {
374        // set quality rendering
375        rw.SetDesiredUpdateRate(0.01);
376    }
377
378    /**
379     * Set coarse and fast rendering for the specified amount of time (in ms, always when set to 0)
380     */
381    public void setCoarseRendering(long time)
382    {
383        // cancel pending task
384        timer.cancel();
385        // want fast update
386        rw.SetDesiredUpdateRate(10.0);
387
388        if (time > 0)
389            setFineRendering(time);
390    }
391
392    /**
393     * Set fine (and possibly slow) rendering after specified time delay (in ms)
394     */
395    public void setFineRendering(long delay)
396    {
397        // cancel pending task
398        timer.cancel();
399
400        if (delay > 0)
401        {
402            // schedule quality restoration
403            timer = new Timer();
404            timer.schedule(new TimerTask()
405            {
406                @Override
407                public void run()
408                {
409                    // no parent --> exit
410                    if (getParent() == null)
411                        return;
412
413                    // set back quality rendering
414                    GetRenderWindow().SetDesiredUpdateRate(0.01);
415                    // request repaint
416                    repaint();
417                }
418            }, delay);
419        }
420        else
421            // set back quality rendering
422            rw.SetDesiredUpdateRate(0.01);
423    }
424}