changelog shortlog tags manifest raw

changeset: Show current frame in ScanStripView. Highlight frame under mouse.

changeset 40: fe800bd3ed70
parent 39:d3945341b28c
child 41:b77d3ae2544e
author: Harri Kaimio <harri@kaimio.fi>
date: Mon Mar 24 08:13:07 2008 +0200 (4 years ago)
files: build.xml src/main/pcapp/fi/kaimio/moviescan/FrameDescriptor.java src/main/pcapp/fi/kaimio/moviescan/FrameIterator.java src/main/pcapp/fi/kaimio/moviescan/FrameRange.java src/main/pcapp/fi/kaimio/moviescan/ScanStrip.java src/main/pcapp/fi/kaimio/moviescan/Scene.java src/main/pcapp/fi/kaimio/moviescan/ui/FrameView.java src/main/pcapp/fi/kaimio/moviescan/ui/MainWindow.java src/main/pcapp/fi/kaimio/moviescan/ui/ScanStripView.form src/main/pcapp/fi/kaimio/moviescan/ui/ScanStripView.java
description: Show current frame in ScanStripView. Highlight frame under mouse.
--- a/build.xml	Sun Mar 23 18:19:58 2008 +0200
+++ b/build.xml	Mon Mar 24 08:13:07 2008 +0200
@@ -325,7 +325,7 @@
         <sourcepath refid="debug.sourcepath"/> 
     </nbjpdastart>
 
-    <java fork="true" classname="fi.kaimio.moviescan.ui.MainWindow">
+    <java fork="true" classname="fi.kaimio.moviescan.ui.Moviescan">
         <jvmarg value="-Xmx${heap.max_size}M"/>
         <jvmarg value="-Djava.library.path=${jlibnxt.path}"/>
         <!--<jvmarg value="-XX:+PrintGCDetails"/>-->
--- a/src/main/pcapp/fi/kaimio/moviescan/FrameDescriptor.java	Sun Mar 23 18:19:58 2008 +0200
+++ b/src/main/pcapp/fi/kaimio/moviescan/FrameDescriptor.java	Mon Mar 24 08:13:07 2008 +0200
@@ -44,5 +44,13 @@ public class FrameDescriptor {
     public RenderedImage getFrame() {
         return strip.getFrame( frameNum );
     }
+    
+    /**
+     Get the perforation matching to this frame
+     @return
+     */
+    public Perforation getPerforation() {
+        return strip.getPerforation( frameNum );
+    }
             
 }
--- a/src/main/pcapp/fi/kaimio/moviescan/FrameIterator.java	Sun Mar 23 18:19:58 2008 +0200
+++ b/src/main/pcapp/fi/kaimio/moviescan/FrameIterator.java	Mon Mar 24 08:13:07 2008 +0200
@@ -70,6 +70,7 @@ public class FrameIterator implements It
             currentStrip = nextStrip;
         }
         FrameDescriptor d = new FrameDescriptor( currentStrip, currentScene.getStripFrameNum( sceneFrame ) );
+        System.err.printf( "Frame %d, strip %s[%d]\n", sceneFrame, d.getStrip().getName(), d.getStripFrameNum() );
         return d;
     }
 
--- a/src/main/pcapp/fi/kaimio/moviescan/FrameRange.java	Sun Mar 23 18:19:58 2008 +0200
+++ b/src/main/pcapp/fi/kaimio/moviescan/FrameRange.java	Mon Mar 24 08:13:07 2008 +0200
@@ -47,7 +47,7 @@ class FrameRange implements ScanStripLis
         this.strip = strip;
         this.stripFirst = stripFirst;
         this.sceneFirst = sceneFirst;
-        this.frameCount = frameCount;
+        this.frameCount = Math.min(frameCount, strip.getFrameCount() );
         stripFirstActive = Math.max(stripFirst, strip.getFirstUsable() );
         stripLastActive = Math.min( stripFirst+frameCount-1, strip.getLastUsable() );
         strip.addScanStripListener( this );
--- a/src/main/pcapp/fi/kaimio/moviescan/ScanStrip.java	Sun Mar 23 18:19:58 2008 +0200
+++ b/src/main/pcapp/fi/kaimio/moviescan/ScanStrip.java	Mon Mar 24 08:13:07 2008 +0200
@@ -147,10 +147,13 @@ public class ScanStrip {
      */
     List<Perforation> perforations;
     
+    
     /**
-     Order number of the first usable frame in the strip
+     Order number of the first usable frame in the strip. Negative value indicates 
+     that the value has not been set; in that case it willb e initialized to the 
+     first full frame in the strip.
      */
-    int firstUsableFrame = 0;
+    int firstUsableFrame = -1;
     
     /**
      Order number of the last usable frame in the strip
@@ -189,7 +192,7 @@ public class ScanStrip {
     public void removeScanStripListener( ScanStripListener l ) {
         listeners.remove( l );
     }
-    
+
     /**
      Notify all registered listeners about changes
      */
@@ -233,7 +236,8 @@ public class ScanStrip {
         if ( perforations == null ) {
             findPerforations();
         }
-        return perforations.size()-2;
+        // For now, assume that the last frame is not complete
+        return perforations.size()-1;
     }
     
     /**
@@ -241,6 +245,10 @@ public class ScanStrip {
      @return Order number of the last usable frame
      */
     public int getFirstUsable() {
+        if ( firstUsableFrame < 0 ) {
+            firstUsableFrame =  
+                    ( perforations.get(0).y > FRAME_HEIGHT/2 + 10 ) ? 0 : 1;
+        }
         return firstUsableFrame;
     }
 
@@ -273,7 +281,26 @@ public class ScanStrip {
         notifyListeners();
     }
     
+    /**
+     Depending on the exact alignment of this strip, the frame that corresponds 
+     to the first perforation can be either full or partial. This function 
+     calculates the order number of the preforation that corresponds to the first 
+     <b>full</b> frame.
+     @return Offset of the first frame
+     */
+    private int getFrameOffset() {
+        return 0;
+    }
 
+    /**
+     Check whether the frame that corresponds to the last perforation in this 
+     strip is full
+     @return
+     */
+    private boolean hasLastPerfFullFrame() {
+        return false;
+    }
+    
     /**
      Get the nth frame of the scan
      @param n frame to get
@@ -307,6 +334,7 @@ public class ScanStrip {
 
         return frame;
     }
+    
     
     /**
      Get image of the whole scan strip. Note that this method is not guaranteed 
@@ -384,6 +412,7 @@ public class ScanStrip {
         /**
          Estimate film rotation from max 5 perforations
          */ 
+        
          int f1 = frame-1;
          int f2 = frame+1;
          int x1 = (f1 >= 0) ? perforations.get( f1 ).x : perforations.get(0).x;
@@ -398,9 +427,9 @@ public class ScanStrip {
          AffineTransform xform = new AffineTransform();
          xform.translate( 0, FRAME_HEIGHT/2 );
          xform.rotate( rot );
-         xform.translate(-perforations.get(frame).x, -perforations.get(frame).y);
-         System.out.println( String.format( "frame %d: (%d, %d), rot %f", 
-                 frame,perforations.get(frame).x, -perforations.get(frame).y, rot ));         
+         xform.translate(-perforations.get(framePerf).x, -perforations.get(framePerf).y);
+//         System.out.println( String.format( "frame %d: (%d, %d), rot %f", 
+//                 frame,perforations.get(frame).x, -perforations.get(frame).y, rot ));         
          return xform;
     }
 
--- a/src/main/pcapp/fi/kaimio/moviescan/Scene.java	Sun Mar 23 18:19:58 2008 +0200
+++ b/src/main/pcapp/fi/kaimio/moviescan/Scene.java	Mon Mar 24 08:13:07 2008 +0200
@@ -47,7 +47,7 @@ public class Scene implements FrameRange
      */
     public int getFrameCount() {
         FrameRange lastRange = getLastRange();
-        return lastRange != null ? lastRange.getSceneFirst() + lastRange.getFrameCount() : 0;
+        return lastRange != null ? lastRange.getSceneFirst() + lastRange.getActiveFrameCount() : 0;
     }
 
     /**
@@ -156,7 +156,7 @@ public class Scene implements FrameRange
         while ( low < high ) {
             int n = (low + high) /2;
             r = frames.get( n );
-            if ( r.getSceneFirst() <= frame && r.getSceneFirst()+r.getFrameCount() > frame ) {
+            if ( r.getSceneFirst() <= frame && r.getSceneFirst()+r.getActiveFrameCount() > frame ) {
                 break;
             }
             if ( frame > r.getSceneFirst() ) {
--- a/src/main/pcapp/fi/kaimio/moviescan/ui/FrameView.java	Sun Mar 23 18:19:58 2008 +0200
+++ b/src/main/pcapp/fi/kaimio/moviescan/ui/FrameView.java	Mon Mar 24 08:13:07 2008 +0200
@@ -208,8 +208,7 @@ public class FrameView extends javax.swi
             return;
         }
         RenderedImage stripImage = currentFrame.getStrip().getStripImage();
-        int perfNum = currentFrame.getStripFrameNum();
-        Perforation p = currentFrame.getStrip().getPerforation( perfNum );
+        Perforation p = currentFrame.getPerforation();
         int perfX = p.x;
         int perfY = p.y;
         
--- a/src/main/pcapp/fi/kaimio/moviescan/ui/MainWindow.java	Sun Mar 23 18:19:58 2008 +0200
+++ b/src/main/pcapp/fi/kaimio/moviescan/ui/MainWindow.java	Mon Mar 24 08:13:07 2008 +0200
@@ -281,6 +281,7 @@ public class MainWindow extends javax.sw
             frameNumField.setText( Integer.toString( projectIter.getCurrentFrameNum() ));
             ((FrameView)framePane).setFrame( d );
             stripViewer.setStrip( d.getStrip() );
+            stripViewer.setSelectedFrame( d.getStripFrameNum() );
         }
 }//GEN-LAST:event_nextFrameBtnActionPerformed
 
--- a/src/main/pcapp/fi/kaimio/moviescan/ui/ScanStripView.form	Sun Mar 23 18:19:58 2008 +0200
+++ b/src/main/pcapp/fi/kaimio/moviescan/ui/ScanStripView.form	Mon Mar 24 08:13:07 2008 +0200
@@ -1,6 +1,10 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 
 <Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <Events>
+    <EventHandler event="mouseExited" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="formMouseExited"/>
+    <EventHandler event="mouseMoved" listener="java.awt.event.MouseMotionListener" parameters="java.awt.event.MouseEvent" handler="formMouseMoved"/>
+  </Events>
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
--- a/src/main/pcapp/fi/kaimio/moviescan/ui/ScanStripView.java	Sun Mar 23 18:19:58 2008 +0200
+++ b/src/main/pcapp/fi/kaimio/moviescan/ui/ScanStripView.java	Mon Mar 24 08:13:07 2008 +0200
@@ -33,6 +33,17 @@ public class ScanStripView extends javax
     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
     private void initComponents() {
 
+        addMouseListener(new java.awt.event.MouseAdapter() {
+            public void mouseExited(java.awt.event.MouseEvent evt) {
+                formMouseExited(evt);
+            }
+        });
+        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
+            public void mouseMoved(java.awt.event.MouseEvent evt) {
+                formMouseMoved(evt);
+            }
+        });
+
         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
         this.setLayout(layout);
         layout.setHorizontalGroup(
@@ -45,6 +56,18 @@ public class ScanStripView extends javax
         );
     }// </editor-fold>//GEN-END:initComponents
 
+    private void formMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseMoved
+        mouseOverPerf = getFrameAt( evt.getX(), evt.getY() );
+        repaint();
+    }//GEN-LAST:event_formMouseMoved
+
+    private void formMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseExited
+        mouseOverPerf = -1;
+        repaint();
+    }//GEN-LAST:event_formMouseExited
+
+    
+    
     /**
      Get the strip currently shown
      @return The current strip
@@ -63,6 +86,53 @@ public class ScanStripView extends javax
         }
         repaint();
     }
+    
+    public void setSelectedFrame( int n ) {
+        selectedFrame = n;
+        selectedPerf = -1;
+    }
+    
+    public int getSelectedFrame() {
+        return selectedFrame;
+    }
+    
+    public void setSelectedPerforation( int n ) {
+        selectedPerf = n;
+        selectedFrame = -1;
+    }
+    
+    public int getSelectedPerforation() {
+        return selectedPerf;
+    }
+    
+    private int getFrameAt( int x, int y ) {
+        if ( x > stripDrawWidth ) {
+            return -1;
+        }
+        int closestDist = Integer.MAX_VALUE;
+        int perf = -1;
+        for ( int n = 0 ; n < perfCoordY.length && perfCoordY[n] >= 0 ; n++ ) {
+            int d = Math.abs( y-perfCoordY[n] );
+            if (d < closestDist) {
+                perf = n;
+                closestDist = d;
+            }
+        }
+        return perf;
+    }
+    
+    /**
+     Width of the strip drawn
+     */
+    int stripDrawWidth = 0;
+    
+    int[] perfCoordY = new int[50];
+    
+    int selectedPerf = -1;
+    
+    int selectedFrame = -1;
+    
+    int mouseOverPerf = -1;
     
     /**
      Paint the strip.
@@ -84,7 +154,9 @@ public class ScanStripView extends javax
         double scaleH = ((double) compWidth) / ((double) stripWidth);
         double scaleV = ((double) compHeight) / ((double) stripHeight);
         double scale = Math.min( scaleH, scaleV );
-
+        stripDrawWidth = (int) (scale * stripWidth);
+        int stripDrawHeight = (int) (scale * stripHeight);
+        
         Graphics2D g2 = (Graphics2D) ((Graphics2D) g).create();
         g2.setPaint( Color.BLACK );
         g2.fillRect( 0, 0, (int) (scale * stripWidth), (int) (scale * stripHeight) );
@@ -94,13 +166,48 @@ public class ScanStripView extends javax
         // Dimensions of S8 perforation
         int perfHeight = (int) (200 * scale);
         int perfWidth = (int) (160 * scale);
-
+        int frameHeight = (int)(800.0 * scale );
+        
         for ( int n = 0; n < strip.getPerforationCount(); n++ ) {
             Perforation p = strip.getPerforation( n );
             int perfX = (int) ((p.x - 140) * scale);
             int perfY = (int) ((p.y - 100) * scale);
-            g2.setPaint( Color.WHITE );
+            perfCoordY[n] = perfY;
+            g2.setPaint( selectedPerf == n ? Color.RED : Color.WHITE );
             g2.fillRect( perfX, perfY, perfWidth, perfHeight );
+            
+            // Decorate the frame if needed
+
+            
+            int frame = n;
+            int fx = perfX + 2;
+            int fy = perfY - frameHeight / 2;
+            int fw = Math.min( stripDrawWidth - fx - 2, stripDrawWidth * 4 / 3 );
+            int fh = frameHeight;
+            if ( frame >= 0 && selectedFrame == frame ) {
+                // This frame is selected
+                g2.setColor( new Color( 192, 64, 64, 128 ) );
+                g2.fillRect( fx, fy, fw, fh );
+            }
+            if ( strip.getFirstUsable() > frame || strip.getLastUsable() < frame ) {
+                // This frame is not usable (either set as such or incomplete)
+                g2.setColor( Color.RED );
+                g2.drawLine( fx, fy, fx + fw, fy + fh );
+                g2.drawLine( fx+fw, fy, fx, fy + fh );
+            }
+        }
+        perfCoordY[strip.getPerforationCount()] = -1;
+        
+        if ( mouseOverPerf >= 0 ) {
+            // Highlight the area where mouse is
+            int top = (mouseOverPerf == 0) ? 
+                0 : 
+                (perfCoordY[mouseOverPerf] + perfCoordY[mouseOverPerf - 1]) / 2;
+            int bot = perfCoordY[mouseOverPerf + 1] < 0 ? 
+                stripDrawHeight : 
+                (perfCoordY[mouseOverPerf + 1] + perfCoordY[mouseOverPerf]) / 2;
+            g2.setPaint( new Color( 128, 128, 128, 128 ) );
+            g2.fillRect( 0, top, stripDrawWidth, bot - top );
         }
 
     }