Blimp v.1.1 (2005-04-16)
Christian Heimke

Christian Heimke commited on 2011-07-15 09:17:34
Showing 38 changed files, with 500 additions and 50 deletions.

... ...
@@ -1,5 +1,5 @@
1 1
 /* BlinkenLightsInteractiveMovieProgram
2
- * version 1.0 date 2005-03-24
2
+ * version 1.1 date 2005-04-16
3 3
  * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
  * a blinkenarea.org project
... ...
@@ -36,24 +36,27 @@ public class Blimp extends JApplet
36 36
   JFrame frame; //main window (if running as full application)
37 37
   Component dialogParent; //parent to use for dialogs
38 38
   JMenuBar menubar; //menubar in main window
39
-  JMenu menuFile, menuInfo, menuEdit, menuPlay, menuHelp; //menus
39
+  JMenu menuFile, menuInfo, menuEdit, menuFrameSel, menuPlay, menuHelp; //menus
40 40
   JMenuItem menuFileNew, menuFileLoad, menuFileSave, menuFileSaveAs, menuFileQuit;
41 41
   JMenuItem menuInfoShow, menuInfoAdd, menuInfoDelete;
42 42
   JMenuItem menuEditResize, menuEditScale;
43 43
   JMenuItem menuEditInsertFrame, menuEditDuplicateFrame, menuEditDeleteFrame;
44
-  JMenuItem menuEditImportFrame;
44
+  JMenuItem menuFrameSelNone, menuFrameSelSingle, menuFrameSelStart, menuFrameSelEnd;
45
+  JMenuItem menuFrameSelCopy, menuFrameSelMove, menuFrameSelReverse, menuFrameSelDelete;
46
+  JMenuItem menuEditImportImages, menuEditImportMovie;
45 47
   JMenuItem menuPlayStart, menuPlayStop;
46 48
   JCheckBoxMenuItem menuPlayBegin, menuPlayLoop;
47 49
   JMenuItem menuHelpAbout;
48 50
   JPanel panel, panelStatus, panelMain, panelFrames, panelOuterFrame; //panels of main window
49 51
   JPanel panelMiddleFrame, panelFrame, panelDuration, panelColors;
50
-  JLabel labelStatus, labelFrames, labelFrameInfo, labelDuration;
52
+  JLabel labelStatus, labelFrames, labelSelFrames, labelFrameInfo, labelDuration;
51 53
   JScrollBar scrollFrames;
52 54
   JSlider sliderFrameZoom;
53 55
   BlinkenFrameEditor frameEditor;
54 56
   JScrollPane scrollpaneFrame;
55 57
   JTextField textDuration;
56 58
   JPanel panelOuterTools, panelMiddleTools, panelTools, panelActions;
59
+  JPanel panelOuterEdit, panelMiddleEdit, panelEdit;
57 60
   JToggleButton buttonToolsNone, buttonToolsColorPicker, buttonToolsDot, buttonToolsLine;
58 61
   JToggleButton buttonToolsRect, buttonToolsFilledRect, buttonToolsCircle, buttonToolsFilledCircle;
59 62
   JToggleButton buttonToolsCopy, buttonToolsPaste;
... ...
@@ -62,6 +65,7 @@ public class Blimp extends JApplet
62 65
   JButton buttonActionsMirrorHor, buttonActionsMirrorVer, buttonActionsMirrorDiag, buttonActionsMirrorDiag2;
63 66
   JButton buttonActionsRollLeft, buttonActionsRollRight, buttonActionsRollUp, buttonActionsRollDown;
64 67
   JButton buttonActionsUndo, buttonActionsRedo;
68
+  JButton buttonEditInsertFrame, buttonEditDuplicateFrame, buttonEditDeleteFrame;
65 69
   JPanel panelColorsChoose, panelColorsSettings, panelColorsColor, panelColorsAlpha;
66 70
   JToggleButton buttonsColor[];
67 71
   ButtonGroup groupColor;
... ...
@@ -81,6 +85,7 @@ public class Blimp extends JApplet
81 85
   BlinkenMovie curMovie = null; //current movie
82 86
   boolean curMovieChanged = false; //if changes have been made to current movie
83 87
   BlinkenFrame curFrame = null; //current frame
88
+  int frameSelStart = -1, frameSelEnd = -1; //selected frames (none selected yet)
84 89
 
85 90
   //constructor for applet
86 91
   public Blimp( )
... ...
@@ -145,7 +150,7 @@ public class Blimp extends JApplet
145 150
     labelStatus.setText( "new movie..." );
146 151
     curFile = null;
147 152
     curMovie = new BlinkenMovie( defHeight, defWidth, defChannels, defMaxval );
148
-    curMovie.insertInfo( 0, "creator", "Blimp (version 1.0 date 2005-03-24)" );
153
+    curMovie.insertInfo( 0, "creator", "Blimp (version 1.1 date 2005-04-16)" );
149 154
     curMovie.insertFrame( 0, new BlinkenFrame( defHeight, defWidth, defChannels, defMaxval, defDuration ) );
150 155
     curMovieChanged = false;
151 156
 
... ...
@@ -462,7 +467,7 @@ public class Blimp extends JApplet
462 467
     labelStatus.setText( "movie scaled successfully to " + dim.toString( ) + "..." );
463 468
   }
464 469
 
465
-  //"Edit Insert Frame" was chosen from menu
470
+  //"Edit Insert Frame" was chosen from menu / Insert Frame button was pressed
466 471
   private void actionEditInsertFrame( )
467 472
   {
468 473
     BlinkenFrame frame;
... ...
@@ -472,6 +477,9 @@ public class Blimp extends JApplet
472 477
     frame = new BlinkenFrame( curMovie.getHeight( ), curMovie.getWidth( ),
473 478
                               curMovie.getChannels( ), curMovie.getMaxval( ), defDuration );
474 479
     frame.clear( );
480
+    //copy duration if there is a current frame
481
+    if( curFrame != null )
482
+      frame.setDuration( curFrame.getDuration( ) );
475 483
 
476 484
     //insert frame behind current position
477 485
     frameCnt = curMovie.getFrameCnt( );
... ...
@@ -487,7 +495,7 @@ public class Blimp extends JApplet
487 495
     updateFrames( frameNo );
488 496
   }
489 497
 
490
-  //"Edit Duplicate Frame" was chosen from menu
498
+  //"Edit Duplicate Frame" was chosen from menu / Duplicate Frame button was pressed
491 499
   private void actionEditDuplicateFrame( )
492 500
   {
493 501
     BlinkenFrame frame;
... ...
@@ -514,7 +522,7 @@ public class Blimp extends JApplet
514 522
     updateFrames( frameNo );
515 523
   }
516 524
 
517
-  //"Edit Delete Frame" was chosen from menu
525
+  //"Edit Delete Frame" was chosen from menu / Delete Frame button was pressed
518 526
   private void actionEditDeleteFrame( )
519 527
   {
520 528
     int frameNo;
... ...
@@ -533,19 +541,21 @@ public class Blimp extends JApplet
533 541
     updateFrames( frameNo );
534 542
   }
535 543
 
536
-  //"Edit Import Frame..." was chosen from menu
537
-  private void actionEditImportFrame( )
544
+  //"Edit Import Images..." was chosen from menu
545
+  private void actionEditImportImages( )
538 546
   {
539 547
     JFileChooser fileChooser;
548
+    File files[];
540 549
     ImageIcon icon;
541 550
     Image image;
542 551
     BufferedImage bufferedImage;
543 552
     BlinkenFrame frame;
544
-    int width, height, x, y, frameCnt, frameNo;
553
+    int width, height, x, y, i, frameCnt, frameNo;
545 554
 
546 555
     //show file select dialog
547 556
     fileChooser = new JFileChooser( );
548
-    fileChooser.setDialogTitle( "Blimp - Import Frame..." );
557
+    fileChooser.setDialogTitle( "Blimp - Import Images..." );
558
+    fileChooser.setMultiSelectionEnabled( true );
549 559
     if( curDir != null )
550 560
       fileChooser.setCurrentDirectory( curDir );
551 561
     if( fileChooser.showOpenDialog( dialogParent ) != JFileChooser.APPROVE_OPTION ) //not successful
... ...
@@ -553,20 +563,25 @@ public class Blimp extends JApplet
553 563
     //save current directory
554 564
     curDir = fileChooser.getCurrentDirectory( );
555 565
 
566
+    //get selected files
567
+    files = fileChooser.getSelectedFiles( );
568
+    for( i = 0; i < files.length; i++ )
569
+    {
570
+
556 571
       //load image
557
-    icon = new ImageIcon( fileChooser.getSelectedFile( ).getPath( ) );
572
+      icon = new ImageIcon( files[i].getPath( ) );
558 573
       if( icon == null )
559 574
       {
560
-      labelStatus.setText( "could not import frame from \"" + fileChooser.getSelectedFile( ).getPath( ) +  "\"..." );
561
-      return;
575
+        labelStatus.setText( "could not import image \"" + files[i].getPath( ) +  "\"..." );
576
+        break;
562 577
       }
563 578
       width = icon.getIconWidth( );
564 579
       height = icon.getIconHeight( );
565 580
       image = icon.getImage( );
566 581
       if( width <= 0 || height <= 0 || image == null )
567 582
       {
568
-      labelStatus.setText( "could not import frame from \"" + fileChooser.getSelectedFile( ).getPath( ) +  "\"..." );
569
-      return;
583
+        labelStatus.setText( "could not import image \"" + files[i].getPath( ) +  "\"..." );
584
+        break;
570 585
       }
571 586
       //convert image to a buffered one
572 587
       bufferedImage = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
... ...
@@ -578,6 +593,9 @@ public class Blimp extends JApplet
578 593
       height = frame.getHeight( ); //dimensions might have been invalid and thus been adapted
579 594
       width = frame.getWidth( );
580 595
       frame.clear( );
596
+      //copy duration if there is a current frame
597
+      if( curFrame != null )
598
+        frame.setDuration( curFrame.getDuration( ) );
581 599
     
582 600
       //put pixels of image into frame
583 601
       for( y = 0; y < height; y++ )
... ...
@@ -595,7 +613,252 @@ public class Blimp extends JApplet
595 613
       curMovieChanged = true;
596 614
 
597 615
       //show status message
598
-    labelStatus.setText( "frame was sucessfully imported from \"" + fileChooser.getSelectedFile( ).getPath( ) +  "\"..." );
616
+      labelStatus.setText( "image \"" + files[i].getPath( ) +  "\" was successfully imported..." );
617
+
618
+      //update controls
619
+      updateFrames( frameNo );
620
+    }
621
+  }
622
+
623
+  //"Edit Import Movie..." was chosen from menu
624
+  private void actionEditImportMovie( )
625
+  {
626
+    JFileChooser fileChooser;
627
+    BlinkenMovie movie;
628
+    BlinkenFrame frame;
629
+    int frameCnt, frameNo, cnt, i;
630
+
631
+    //show file select dialog
632
+    fileChooser = new JFileChooser( );
633
+    fileChooser.setDialogTitle( "Blimp - Import Movie..." );
634
+    fileChooser.setFileFilter( new BlinkenFileFilter( ) );
635
+    if( curDir != null )
636
+      fileChooser.setCurrentDirectory( curDir );
637
+    if( fileChooser.showOpenDialog( dialogParent ) != JFileChooser.APPROVE_OPTION ) //not successful
638
+      return;
639
+    //save current directory
640
+    curDir = fileChooser.getCurrentDirectory( );
641
+
642
+    //load movie
643
+    movie = new BlinkenMovie( 0, 0, 0, 0 );
644
+    if( ! movie.load( fileChooser.getSelectedFile( ).getPath( ) ) )
645
+    {
646
+      //some error
647
+      labelStatus.setText( "movie \"" + fileChooser.getSelectedFile( ).getPath( ) +  "\" could not be imported..." );
648
+    }
649
+
650
+    //insert frames of movie behind current position
651
+    frameCnt = curMovie.getFrameCnt( );
652
+    frameNo = scrollFrames.getValue( ) + 1;
653
+    if( frameNo < 0 )
654
+      frameNo = 0;
655
+    if( frameNo > frameCnt )
656
+      frameNo = frameCnt;
657
+    cnt = movie.getFrameCnt( );
658
+    for( i = 0; i < cnt; i++ )
659
+    {
660
+      frame = new BlinkenFrame( movie.getFrame( i ) );
661
+      curMovie.insertFrame( frameNo + i, frame ); //this resizes the frame to fit the movie dimensions
662
+    }
663
+    curMovieChanged = true;
664
+
665
+    //success
666
+    labelStatus.setText( "movie \"" + fileChooser.getSelectedFile( ).getPath( ) +  "\" was successfully imported..." );
667
+
668
+    //update controls
669
+    updateFrames( frameNo );
670
+  }
671
+
672
+  //"Frame-Selection Select None" was chosen from menu
673
+  private void actionFrameSelNone( )
674
+  {
675
+    //remove frame selection
676
+    frameSelStart = -1;
677
+    frameSelEnd = -1;
678
+    stateFrameSel( );
679
+  }
680
+
681
+  //"Frame-Selection Select Single Frame" was chosen from menu
682
+  private void actionFrameSelSingle( )
683
+  {
684
+    //do nothing if there is no current frame
685
+    if( curFrame == null )
686
+      return;
687
+
688
+    //select current frame
689
+    frameSelStart = scrollFrames.getValue( );
690
+    frameSelEnd = frameSelStart;
691
+    stateFrameSel( );
692
+  }
693
+
694
+  //"Frame-Selection Start of Selection" was chosen from menu
695
+  private void actionFrameSelStart( )
696
+  {
697
+    //do nothing if there is no current frame
698
+    if( curFrame == null )
699
+      return;
700
+
701
+    //set start of frame selection to current frame
702
+    frameSelStart = scrollFrames.getValue( );
703
+    if( frameSelEnd >= curMovie.getFrameCnt( ) || frameSelEnd < frameSelStart )
704
+      frameSelEnd = frameSelStart;
705
+    stateFrameSel( );
706
+  }
707
+
708
+  //"Frame-Selection End of Selection" was chosen from menu
709
+  private void actionFrameSelEnd( )
710
+  {
711
+    //do nothing if there is no current frame
712
+    if( curFrame == null )
713
+      return;
714
+
715
+    //set end of frame selection to current frame
716
+    frameSelEnd = scrollFrames.getValue( );
717
+    if( frameSelStart < 0 || frameSelStart > frameSelEnd )
718
+      frameSelStart = frameSelEnd;
719
+    stateFrameSel( );
720
+  }
721
+
722
+  //"Frame-Selection Copy" was chosen from menu
723
+  private void actionFrameSelCopy( )
724
+  {
725
+    int frameCnt, frameNo, cnt, i;
726
+
727
+    //do nothing if selection is invalid
728
+    frameCnt = curMovie.getFrameCnt( );
729
+    if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt )
730
+      return;
731
+
732
+    //get copies of selected frames
733
+    cnt = frameSelEnd - frameSelStart + 1;
734
+    BlinkenFrame frames[] = new BlinkenFrame[cnt];
735
+    for( i = 0; i < cnt; i++ )
736
+      frames[i] = new BlinkenFrame( curMovie.getFrame( frameSelStart + i ) );
737
+
738
+    //insert frames behind current position
739
+    frameNo = scrollFrames.getValue( ) + 1;
740
+    if( frameNo < 0 )
741
+      frameNo = 0;
742
+    if( frameNo > frameCnt )
743
+      frameNo = frameCnt;
744
+    for( i = 0; i < cnt; i++ )
745
+      curMovie.insertFrame( frameNo + i, frames[i] );
746
+    curMovieChanged = true;
747
+
748
+    //update controls
749
+    updateFrames( frameNo );
750
+
751
+    //select newly inserted frames
752
+    frameSelStart = frameNo;
753
+    frameSelEnd = frameSelStart + cnt - 1;
754
+    stateFrameSel( );
755
+  }
756
+
757
+  //"Frame-Selection Move" was chosen from menu
758
+  private void actionFrameSelMove( )
759
+  {
760
+    int frameCnt, frameNo, cnt, i;
761
+
762
+    //do nothing if selection is invalid
763
+    frameCnt = curMovie.getFrameCnt( );
764
+    if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt )
765
+      return;
766
+
767
+    //get selected frames
768
+    cnt = frameSelEnd - frameSelStart + 1;
769
+    BlinkenFrame frames[] = new BlinkenFrame[cnt];
770
+    for( i = 0; i < cnt; i++ )
771
+      frames[i] = curMovie.getFrame( frameSelStart + i );
772
+
773
+    //delete selected frames
774
+    for( i = 0; i < cnt; i++ )
775
+      curMovie.deleteFrame( frameSelStart );
776
+
777
+    //update number of frames and current position
778
+    frameCnt -= cnt; //cnt frames were deleted
779
+    frameNo = scrollFrames.getValue( ); //old position
780
+    if( frameNo > frameSelEnd ) //was behind last frame of selection
781
+      frameNo -= cnt;
782
+    else if( frameNo >= frameSelStart) //was in selection
783
+      frameNo = frameSelStart - 1;
784
+
785
+    //insert frames behind current position
786
+    frameNo++;
787
+    if( frameNo < 0 )
788
+      frameNo = 0;
789
+    if( frameNo > frameCnt )
790
+      frameNo = frameCnt;
791
+    for( i = 0; i < cnt; i++ )
792
+      curMovie.insertFrame( frameNo + i, frames[i] );
793
+    curMovieChanged = true;
794
+
795
+    //update controls
796
+    updateFrames( frameNo );
797
+
798
+    //select moved frames
799
+    frameSelStart = frameNo;
800
+    frameSelEnd = frameSelStart + cnt - 1;
801
+    stateFrameSel( );
802
+  }
803
+
804
+  //"Frame-Selection Reverse" was chosen from menu
805
+  private void actionFrameSelReverse( )
806
+  {
807
+    int frameCnt, frameNo, cnt, i;
808
+
809
+    //do nothing if selection is invalid
810
+    frameCnt = curMovie.getFrameCnt( );
811
+    if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt )
812
+      return;
813
+
814
+    //get selected frames
815
+    cnt = frameSelEnd - frameSelStart + 1;
816
+    BlinkenFrame frames[] = new BlinkenFrame[cnt];
817
+    for( i = 0; i < cnt; i++ )
818
+      frames[i] = curMovie.getFrame( frameSelStart + i );
819
+
820
+    //delete selected frames
821
+    for( i = 0; i < cnt; i++ )
822
+      curMovie.deleteFrame( frameSelStart );
823
+
824
+    //insert selected frames in reverse order
825
+    for( i = 0; i < cnt; i++ )
826
+      curMovie.insertFrame( frameSelStart, frames[i] );
827
+    curMovieChanged = true;
828
+
829
+    //update controls - go to reversed frames
830
+    frameNo = frameSelStart;
831
+    updateFrames( frameNo );
832
+
833
+    //select reversed frames
834
+    frameSelStart = frameNo;
835
+    frameSelEnd = frameSelStart + cnt - 1;
836
+    stateFrameSel( );
837
+  }
838
+
839
+  //"Frame-Selection Delete" was chosen from menu
840
+  private void actionFrameSelDelete( )
841
+  {
842
+    int frameCnt, frameNo, cnt, i;
843
+
844
+    //do nothing if selection is invalid
845
+    frameCnt = curMovie.getFrameCnt( );
846
+    if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt )
847
+      return;
848
+
849
+    //delete selected frames
850
+    cnt = frameSelEnd - frameSelStart + 1;
851
+    for( i = 0; i < cnt; i++ )
852
+      curMovie.deleteFrame( frameSelStart );
853
+    curMovieChanged = true;
854
+
855
+    //update number of frames and current position
856
+    frameCnt -= cnt; //cnt frames were deleted
857
+    frameNo = scrollFrames.getValue( ); //old position
858
+    if( frameNo > frameSelEnd ) //was behind last frame of selection
859
+      frameNo -= cnt;
860
+    else if( frameNo >= frameSelStart) //was in selection
861
+      frameNo = frameSelStart - 1;
599 862
 
600 863
     //update controls
601 864
     updateFrames( frameNo );
... ...
@@ -681,7 +944,7 @@ public class Blimp extends JApplet
681 944
   {
682 945
     JOptionPane.showMessageDialog( dialogParent,
683 946
                                    "BlinkenLightsInteractiveMovieProgram\n" +
684
-                                   "version 1.0 date 2005-03-24\n" +
947
+                                   "version 1.1 date 2005-04-16\n" +
685 948
                                    "Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>\n" +
686 949
                                    "Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html\n" +
687 950
                                    "a blinkenarea.org project\n" +
... ...
@@ -693,14 +956,14 @@ public class Blimp extends JApplet
693 956
   //update frames controls (and go to certaint frame)
694 957
   private void updateFrames( int frameNo )
695 958
   {
696
-    int frameCnt, frameInc;
959
+    int frameCnt;
697 960
 
698 961
     //update frames scrollbar range
699 962
     frameCnt = curMovie.getFrameCnt( );
700 963
     if( frameCnt <= 0 )
701 964
     {
965
+      frameNo = 0;
702 966
       scrollFrames.setValues( 0, 0, 0, 0 );
703
-      scrollFrames.setBlockIncrement( 1 );
704 967
     }
705 968
     else
706 969
     {
... ...
@@ -709,18 +972,21 @@ public class Blimp extends JApplet
709 972
       if( frameNo >= frameCnt )
710 973
         frameNo = frameCnt - 1;
711 974
       scrollFrames.setValues( frameNo, 1, 0, frameCnt );
712
-      frameInc = (int)Math.sqrt( frameCnt );
713
-      if( frameInc < 1 )
714
-        frameInc = 1;
715
-      scrollFrames.setBlockIncrement( frameInc );
716 975
     }
717 976
 
718
-    //simulate frames scrollbar change to propagate update
719
-    stateFrames( );
977
+    //select no frames
978
+    frameSelStart = -1;
979
+    frameSelEnd = -1;
980
+    stateFrameSel( );
720 981
 
721
-    //enable disable some menu commands which need a current frame
982
+    //enable/disable some menu commands and buttons which need a current frame
722 983
     menuEditDuplicateFrame.setEnabled( frameCnt > 0 );
723 984
     menuEditDeleteFrame.setEnabled( frameCnt > 0 );
985
+    buttonEditDuplicateFrame.setEnabled( frameCnt > 0 );
986
+    buttonEditDeleteFrame.setEnabled( frameCnt > 0 );
987
+    menuFrameSelSingle.setEnabled( frameCnt > 0 );
988
+    menuFrameSelStart.setEnabled( frameCnt > 0 );
989
+    menuFrameSelEnd.setEnabled( frameCnt > 0 );
724 990
   }
725 991
 
726 992
   //frames scrollbar changed
... ...
@@ -729,10 +995,10 @@ public class Blimp extends JApplet
729 995
     int frameCnt, frameNo;
730 996
 
731 997
     //update frames scrollbar label
732
-    //get current frame
733 998
     frameCnt = curMovie.getFrameCnt( );
734 999
     if( frameCnt <= 0 )
735 1000
     {
1001
+      frameNo = 0;
736 1002
       labelFrames.setText( "frame: -/0" );
737 1003
       curFrame = null;
738 1004
     }
... ...
@@ -743,6 +1009,16 @@ public class Blimp extends JApplet
743 1009
       curFrame = curMovie.getFrame( frameNo );
744 1010
     }
745 1011
 
1012
+    //update selected frames label
1013
+    if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt )
1014
+      labelSelFrames.setText( "selected: -/-" );
1015
+    else if( frameSelStart > frameNo )
1016
+      labelSelFrames.setText( "selected: -/" + (frameSelEnd - frameSelStart + 1) );
1017
+    else if( frameNo > frameSelEnd )
1018
+      labelSelFrames.setText( "selected: +/" + (frameSelEnd - frameSelStart + 1) );
1019
+    else
1020
+      labelSelFrames.setText( "selected: " + (frameNo - frameSelStart + 1) + "/" + (frameSelEnd - frameSelStart + 1) );
1021
+
746 1022
     //update frame
747 1023
     frameEditor.setFrame( curFrame );
748 1024
 
... ...
@@ -763,6 +1039,26 @@ public class Blimp extends JApplet
763 1039
     }
764 1040
   }
765 1041
   
1042
+  //frame selection changed
1043
+  private void stateFrameSel( )
1044
+  {
1045
+    boolean valid;
1046
+    int frameCnt;
1047
+
1048
+    //simulate frames scrollbar change to propagate update
1049
+    stateFrames( );
1050
+
1051
+    //check if selection is valid
1052
+    frameCnt = curMovie.getFrameCnt( );
1053
+    valid = (0 <= frameSelStart && frameSelStart <= frameSelEnd && frameSelEnd < frameCnt);
1054
+
1055
+    //enable/disable some menu commands which need a selection
1056
+    menuFrameSelCopy.setEnabled( valid );
1057
+    menuFrameSelMove.setEnabled( valid );
1058
+    menuFrameSelReverse.setEnabled( valid );
1059
+    menuFrameSelDelete.setEnabled( valid );
1060
+  }
1061
+
766 1062
   //frame zoom changed
767 1063
   private void stateFrameZoom( )
768 1064
   {
... ...
@@ -1137,8 +1433,26 @@ public class Blimp extends JApplet
1137 1433
       actionEditDuplicateFrame( );
1138 1434
     else if( e.getSource( ) == menuEditDeleteFrame )
1139 1435
       actionEditDeleteFrame( );
1140
-    else if( e.getSource( ) == menuEditImportFrame )
1141
-      actionEditImportFrame( );
1436
+    else if( e.getSource( ) == menuEditImportImages )
1437
+      actionEditImportImages( );
1438
+    else if( e.getSource( ) == menuEditImportMovie )
1439
+      actionEditImportMovie( );
1440
+    else if( e.getSource( ) == menuFrameSelNone )
1441
+      actionFrameSelNone( );
1442
+    else if( e.getSource( ) == menuFrameSelSingle )
1443
+      actionFrameSelSingle( );
1444
+    else if( e.getSource( ) == menuFrameSelStart )
1445
+      actionFrameSelStart( );
1446
+    else if( e.getSource( ) == menuFrameSelEnd )
1447
+      actionFrameSelEnd( );
1448
+    else if( e.getSource( ) == menuFrameSelCopy )
1449
+      actionFrameSelCopy( );
1450
+    else if( e.getSource( ) == menuFrameSelMove )
1451
+      actionFrameSelMove( );
1452
+    else if( e.getSource( ) == menuFrameSelReverse )
1453
+      actionFrameSelReverse( );
1454
+    else if( e.getSource( ) == menuFrameSelDelete )
1455
+      actionFrameSelDelete( );
1142 1456
     else if( e.getSource( ) == menuPlayStart )
1143 1457
       actionPlayStart( );
1144 1458
     else if( e.getSource( ) == menuPlayStop )
... ...
@@ -1197,6 +1511,12 @@ public class Blimp extends JApplet
1197 1511
       frameEditor.actionUndo( );
1198 1512
     else if( e.getSource( ) == buttonActionsRedo )
1199 1513
       frameEditor.actionRedo( );
1514
+    else if( e.getSource( ) == buttonEditInsertFrame )
1515
+      actionEditInsertFrame( );
1516
+    else if( e.getSource( ) == buttonEditDuplicateFrame )
1517
+      actionEditDuplicateFrame( );
1518
+    else if( e.getSource( ) == buttonEditDeleteFrame )
1519
+      actionEditDeleteFrame( );
1200 1520
     else if( e.getSource( ) == buttonColorsColor )
1201 1521
       actionColorsColor( );
1202 1522
     else if( e.getSource( ) == textColorsColor )
... ...
@@ -1317,7 +1637,7 @@ public class Blimp extends JApplet
1317 1637
     //initialize current movie, frame
1318 1638
     curDir = new File( "." );
1319 1639
     curMovie = new BlinkenMovie( defHeight, defWidth, defChannels, defMaxval );
1320
-    curMovie.insertInfo( 0, "creator", "Blimp (version 1.0 date 2005-03-24)" );
1640
+    curMovie.insertInfo( 0, "creator", "Blimp (version 1.1 date 2005-04-16)" );
1321 1641
     curMovie.insertFrame( 0, new BlinkenFrame( defHeight, defWidth, defChannels, defMaxval, defDuration ) );
1322 1642
     curFrame = null;
1323 1643
 
... ...
@@ -1356,83 +1676,175 @@ public class Blimp extends JApplet
1356 1676
     //create menus
1357 1677
     //file menu
1358 1678
     menuFile = new JMenu( "File" );
1679
+    menuFile.setMnemonic( KeyEvent.VK_F );
1359 1680
     menubar.add( menuFile );
1360 1681
     menuFileNew = new JMenuItem( "New" );
1682
+    menuFileNew.setMnemonic( KeyEvent.VK_N );
1683
+    menuFileNew.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, KeyEvent.CTRL_MASK ) );
1361 1684
     menuFileNew.addActionListener( this );
1362 1685
     menuFile.add( menuFileNew );
1363 1686
     menuFileLoad = new JMenuItem( "Load..." );
1687
+    menuFileLoad.setMnemonic( KeyEvent.VK_L );
1688
+    menuFileLoad.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_L, KeyEvent.CTRL_MASK ) );
1364 1689
     menuFileLoad.addActionListener( this );
1365 1690
     menuFile.add( menuFileLoad );
1366 1691
     menuFileSave = new JMenuItem( "Save" );
1692
+    menuFileSave.setMnemonic( KeyEvent.VK_S );
1693
+    menuFileSave.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_S, KeyEvent.CTRL_MASK ) );
1367 1694
     menuFileSave.addActionListener( this );
1368 1695
     menuFile.add( menuFileSave );
1369 1696
     menuFileSaveAs = new JMenuItem( "Save as..." );
1697
+    menuFileSaveAs.setMnemonic( KeyEvent.VK_A );
1698
+    menuFileSaveAs.setDisplayedMnemonicIndex( 5 );
1699
+    menuFileSaveAs.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_A, KeyEvent.CTRL_MASK ) );
1370 1700
     menuFileSaveAs.addActionListener( this );
1371 1701
     menuFile.add( menuFileSaveAs );
1372 1702
     if( isFullApp )
1373 1703
       menuFile.addSeparator( );
1374 1704
     menuFileQuit = new JMenuItem( "Quit" );
1705
+    menuFileQuit.setMnemonic( KeyEvent.VK_Q );
1375 1706
     menuFileQuit.addActionListener( this );
1376 1707
     if( isFullApp )
1377 1708
       menuFile.add( menuFileQuit );
1378 1709
     //information menu
1379 1710
     menuInfo = new JMenu( "Information" );
1711
+    menuInfo.setMnemonic( KeyEvent.VK_I );
1380 1712
     menubar.add( menuInfo );
1381 1713
     menuInfoShow = new JMenuItem( "Show..." );
1714
+    menuInfoShow.setMnemonic( KeyEvent.VK_S );
1382 1715
     menuInfoShow.addActionListener( this );
1383 1716
     menuInfo.add( menuInfoShow );
1384 1717
     menuInfoAdd = new JMenuItem( "Add..." );
1718
+    menuInfoAdd.setMnemonic( KeyEvent.VK_A );
1385 1719
     menuInfoAdd.addActionListener( this );
1386 1720
     menuInfo.add( menuInfoAdd );
1387 1721
     menuInfoDelete = new JMenuItem( "Delete..." );
1722
+    menuInfoDelete.setMnemonic( KeyEvent.VK_D );
1388 1723
     menuInfoDelete.addActionListener( this );
1389 1724
     menuInfo.add( menuInfoDelete );
1390 1725
     //edit menu
1391 1726
     menuEdit = new JMenu( "Edit" );
1727
+    menuEdit.setMnemonic( KeyEvent.VK_E );
1392 1728
     menubar.add( menuEdit );
1393 1729
     menuEditResize = new JMenuItem( "Resize Movie..." );
1730
+    menuEditResize.setMnemonic( KeyEvent.VK_R );
1394 1731
     menuEditResize.addActionListener( this );
1395 1732
     menuEdit.add( menuEditResize );
1396 1733
     menuEditScale = new JMenuItem( "Scale Movie..." );
1734
+    menuEditScale.setMnemonic( KeyEvent.VK_S );
1397 1735
     menuEditScale.addActionListener( this );
1398 1736
     menuEdit.add( menuEditScale );
1399 1737
     menuEdit.addSeparator( );
1400 1738
     menuEditInsertFrame = new JMenuItem( "Insert Frame" );
1739
+    menuEditInsertFrame.setMnemonic( KeyEvent.VK_I );
1740
+    menuEditInsertFrame.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_I, KeyEvent.CTRL_MASK ) );
1401 1741
     menuEditInsertFrame.addActionListener( this );
1402 1742
     menuEdit.add( menuEditInsertFrame );
1403 1743
     menuEditDuplicateFrame = new JMenuItem( "Duplicate Frame" );
1744
+    menuEditDuplicateFrame.setMnemonic( KeyEvent.VK_D );
1745
+    menuEditDuplicateFrame.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_D, KeyEvent.CTRL_MASK ) );
1404 1746
     menuEditDuplicateFrame.setEnabled( false );
1405 1747
     menuEditDuplicateFrame.addActionListener( this );
1406 1748
     menuEdit.add( menuEditDuplicateFrame );
1407 1749
     menuEditDeleteFrame = new JMenuItem( "Delete Frame" );
1750
+    menuEditDeleteFrame.setMnemonic( KeyEvent.VK_L );
1751
+    menuEditDeleteFrame.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_X, KeyEvent.CTRL_MASK ) );
1408 1752
     menuEditDeleteFrame.setEnabled( false );
1409 1753
     menuEditDeleteFrame.addActionListener( this );
1410 1754
     menuEdit.add( menuEditDeleteFrame );
1411 1755
     menuEdit.addSeparator( );
1412
-    menuEditImportFrame = new JMenuItem( "Import Frame..." );
1413
-    menuEditImportFrame.addActionListener( this );
1414
-    menuEdit.add( menuEditImportFrame );
1756
+    menuEditImportImages = new JMenuItem( "Import Images..." );
1757
+    menuEditImportImages.setMnemonic( KeyEvent.VK_P );
1758
+    menuEditImportImages.setDisplayedMnemonicIndex( 7 );
1759
+    menuEditImportImages.addActionListener( this );
1760
+    menuEdit.add( menuEditImportImages );
1761
+    menuEditImportMovie = new JMenuItem( "Import Movie..." );
1762
+    menuEditImportMovie.setMnemonic( KeyEvent.VK_M );
1763
+    menuEditImportMovie.setDisplayedMnemonicIndex( 7 );
1764
+    menuEditImportMovie.addActionListener( this );
1765
+    menuEdit.add( menuEditImportMovie );
1766
+    //frame selection menu
1767
+    menuFrameSel = new JMenu( "Frame-Selection" );
1768
+    menuFrameSel.setMnemonic( KeyEvent.VK_S );
1769
+    menubar.add( menuFrameSel );
1770
+    menuFrameSelNone = new JMenuItem( "Select None" );
1771
+    menuFrameSelNone.setMnemonic( KeyEvent.VK_N );
1772
+    menuFrameSelNone.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) );
1773
+    menuFrameSelNone.addActionListener( this );
1774
+    menuFrameSel.add( menuFrameSelNone );
1775
+    menuFrameSelSingle = new JMenuItem( "Select Single Frame" );
1776
+    menuFrameSelSingle.setMnemonic( KeyEvent.VK_F );
1777
+    menuFrameSelSingle.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_F, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) );
1778
+    menuFrameSelSingle.setEnabled( false );
1779
+    menuFrameSelSingle.addActionListener( this );
1780
+    menuFrameSel.add( menuFrameSelSingle );
1781
+    menuFrameSelStart = new JMenuItem( "Start of Selection" );
1782
+    menuFrameSelStart.setMnemonic( KeyEvent.VK_S );
1783
+    menuFrameSelStart.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_S, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) );
1784
+    menuFrameSelStart.setEnabled( false );
1785
+    menuFrameSelStart.addActionListener( this );
1786
+    menuFrameSel.add( menuFrameSelStart );
1787
+    menuFrameSelEnd = new JMenuItem( "End of Selection" );
1788
+    menuFrameSelEnd.setMnemonic( KeyEvent.VK_E );
1789
+    menuFrameSelEnd.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_E, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) );
1790
+    menuFrameSelEnd.setEnabled( false );
1791
+    menuFrameSelEnd.addActionListener( this );
1792
+    menuFrameSel.add( menuFrameSelEnd );
1793
+    menuFrameSel.addSeparator( );
1794
+    menuFrameSelCopy = new JMenuItem( "Copy" );
1795
+    menuFrameSelCopy.setMnemonic( KeyEvent.VK_C );
1796
+    menuFrameSelCopy.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_C, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) );
1797
+    menuFrameSelCopy.setEnabled( false );
1798
+    menuFrameSelCopy.addActionListener( this );
1799
+    menuFrameSel.add( menuFrameSelCopy );
1800
+    menuFrameSelMove = new JMenuItem( "Move" );
1801
+    menuFrameSelMove.setMnemonic( KeyEvent.VK_M );
1802
+    menuFrameSelMove.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_M, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) );
1803
+    menuFrameSelMove.setEnabled( false );
1804
+    menuFrameSelMove.addActionListener( this );
1805
+    menuFrameSel.add( menuFrameSelMove );
1806
+    menuFrameSelReverse = new JMenuItem( "Reverse" );
1807
+    menuFrameSelReverse.setMnemonic( KeyEvent.VK_R );
1808
+    menuFrameSelReverse.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_R, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) );
1809
+    menuFrameSelReverse.setEnabled( false );
1810
+    menuFrameSelReverse.addActionListener( this );
1811
+    menuFrameSel.add( menuFrameSelReverse );
1812
+    menuFrameSelDelete = new JMenuItem( "Delete" );
1813
+    menuFrameSelDelete.setMnemonic( KeyEvent.VK_L );
1814
+    menuFrameSelDelete.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_X, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) );
1815
+    menuFrameSelDelete.setEnabled( false );
1816
+    menuFrameSelDelete.addActionListener( this );
1817
+    menuFrameSel.add( menuFrameSelDelete );
1415 1818
     //play menu
1416 1819
     menuPlay = new JMenu( "Play" );
1820
+    menuPlay.setMnemonic( KeyEvent.VK_P );
1417 1821
     menubar.add( menuPlay );
1418 1822
     menuPlayStart = new JMenuItem( "Start" );
1823
+    menuPlayStart.setMnemonic( KeyEvent.VK_S );
1824
+    menuPlayStart.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_F11, 0 ) );
1419 1825
     menuPlayStart.addActionListener( this );
1420 1826
     menuPlay.add( menuPlayStart );
1421 1827
     menuPlayStop = new JMenuItem( "Stop" );
1828
+    menuPlayStop.setMnemonic( KeyEvent.VK_P );
1829
+    menuPlayStop.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_F12, 0 ) );
1422 1830
     menuPlayStop.setEnabled( false );
1423 1831
     menuPlayStop.addActionListener( this );
1424 1832
     menuPlay.add( menuPlayStop );
1425 1833
     menuPlay.addSeparator( );
1426 1834
     menuPlayBegin = new JCheckBoxMenuItem( "From Begin", false );
1835
+    menuPlayBegin.setMnemonic( KeyEvent.VK_B );
1427 1836
     menuPlayBegin.addActionListener( this );
1428 1837
     menuPlay.add( menuPlayBegin );
1429 1838
     menuPlayLoop = new JCheckBoxMenuItem( "Looped", false );
1839
+    menuPlayLoop.setMnemonic( KeyEvent.VK_L );
1430 1840
     menuPlayLoop.addActionListener( this );
1431 1841
     menuPlay.add( menuPlayLoop );
1432 1842
     //help menu
1433 1843
     menuHelp = new JMenu( "Help" );
1844
+    menuHelp.setMnemonic( KeyEvent.VK_H );
1434 1845
     menubar.add( menuHelp );
1435 1846
     menuHelpAbout = new JMenuItem( "About..." );
1847
+    menuHelpAbout.setMnemonic( KeyEvent.VK_A );
1436 1848
     menuHelpAbout.addActionListener( this );
1437 1849
     menuHelp.add( menuHelpAbout );
1438 1850
 
... ...
@@ -1452,12 +1864,14 @@ public class Blimp extends JApplet
1452 1864
     panelFrames = new JPanel( new BorderLayout( 5, 5 ) );
1453 1865
     panelMain.add( panelFrames, BorderLayout.SOUTH );
1454 1866
     scrollFrames = new JScrollBar( SwingConstants.HORIZONTAL, 0, 0, 0, 0 );
1455
-    scrollFrames.setBlockIncrement( 1 );
1456 1867
     scrollFrames.addAdjustmentListener( this );
1457 1868
     panelFrames.add( scrollFrames, BorderLayout.CENTER );
1458 1869
     labelFrames = new JLabel( "frame: -/0" );
1459 1870
     labelFrames.setLabelFor( scrollFrames );
1460 1871
     panelFrames.add( labelFrames, BorderLayout.WEST );
1872
+    labelSelFrames = new JLabel( "selected: -/-" );
1873
+    labelSelFrames.setLabelFor( scrollFrames );
1874
+    panelFrames.add( labelSelFrames, BorderLayout.EAST );
1461 1875
     //outer and middle frame panel
1462 1876
     panelOuterFrame = new JPanel( new BorderLayout( 5, 5 ) );
1463 1877
     panelMain.add( panelOuterFrame, BorderLayout.CENTER );
... ...
@@ -1495,9 +1909,11 @@ public class Blimp extends JApplet
1495 1909
     labelDuration.setLabelFor( textDuration );
1496 1910
     panelDuration.add( labelDuration );
1497 1911
     panelDuration.add( textDuration );
1498
-    //tool and action panels
1912
+    //tool, action and edit panels
1913
+    panelOuterEdit = new JPanel( new BorderLayout( 5, 5 ) );
1914
+    panelOuterFrame.add( panelOuterEdit, BorderLayout.WEST );
1499 1915
     panelOuterTools = new JPanel( new GridLayout( 2, 1, 5, 5 ) );
1500
-    panelOuterFrame.add( panelOuterTools, BorderLayout.WEST );
1916
+    panelOuterEdit.add( panelOuterTools, BorderLayout.CENTER );
1501 1917
     panelMiddleTools = new JPanel( new BorderLayout( 5, 5 ) );
1502 1918
     panelOuterTools.add( panelMiddleTools );
1503 1919
     panelTools = new JPanel( new GridLayout( 4, 3, 5, 5 ) );
... ...
@@ -1505,6 +1921,11 @@ public class Blimp extends JApplet
1505 1921
     panelMiddleTools.add( new JSeparator( JSeparator.HORIZONTAL ), BorderLayout.SOUTH );
1506 1922
     panelActions = new JPanel( new GridLayout( 5, 3, 5, 5 ) );
1507 1923
     panelOuterTools.add( panelActions );
1924
+    panelMiddleEdit = new JPanel( new BorderLayout( 5, 5 ) );
1925
+    panelOuterEdit.add( panelMiddleEdit, BorderLayout.SOUTH );
1926
+    panelMiddleEdit.add( new JSeparator( JSeparator.HORIZONTAL ), BorderLayout.NORTH );
1927
+    panelEdit = new JPanel( new GridLayout( 1, 3, 5, 5 ) );
1928
+    panelMiddleEdit.add( panelEdit, BorderLayout.CENTER );
1508 1929
     //tool buttons
1509 1930
     groupTools = new ButtonGroup( );
1510 1931
     buttonToolsNone = new JToggleButton( );
... ...
@@ -1645,6 +2066,22 @@ public class Blimp extends JApplet
1645 2066
     buttonActionsRedo.setEnabled( false );
1646 2067
     buttonActionsRedo.addActionListener( this );
1647 2068
     panelActions.add( buttonActionsRedo );
2069
+    //edit buttons
2070
+    buttonEditInsertFrame = new JButton( loadImageIcon( "InsertFrame.png" ) );
2071
+    buttonEditInsertFrame.setMargin( smallMargin );
2072
+    buttonEditInsertFrame.setToolTipText( "Insert Frame" );
2073
+    buttonEditInsertFrame.addActionListener( this );
2074
+    panelEdit.add( buttonEditInsertFrame );
2075
+    buttonEditDuplicateFrame = new JButton( loadImageIcon( "DuplicateFrame.png" ) );
2076
+    buttonEditDuplicateFrame.setMargin( smallMargin );
2077
+    buttonEditDuplicateFrame.setToolTipText( "Duplicate Frame" );
2078
+    buttonEditDuplicateFrame.addActionListener( this );
2079
+    panelEdit.add( buttonEditDuplicateFrame );
2080
+    buttonEditDeleteFrame = new JButton( loadImageIcon( "DeleteFrame.png" ) );
2081
+    buttonEditDeleteFrame.setMargin( smallMargin );
2082
+    buttonEditDeleteFrame.setToolTipText( "Delete Frame" );
2083
+    buttonEditDeleteFrame.addActionListener( this );
2084
+    panelEdit.add( buttonEditDeleteFrame );
1648 2085
     //color panel
1649 2086
     panelColors = new JPanel( new GridLayout( 2, 1, 5, 5 ) );
1650 2087
     panelOuterFrame.add( panelColors, BorderLayout.EAST );
... ...
@@ -1783,7 +2220,7 @@ public class Blimp extends JApplet
1783 2220
 
1784 2221
     //running as command line tool
1785 2222
     System.out.println( "BlinkenLightsInteractiveMovieProgram\n" +
1786
-                        "version 1.0 date 2005-03-24\n" +
2223
+                        "version 1.1 date 2005-04-16\n" +
1787 2224
                         "Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>\n" +
1788 2225
                         "Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html\n" +
1789 2226
                         "a blinkenarea.org project\n" +
... ...
@@ -1795,7 +2232,7 @@ public class Blimp extends JApplet
1795 2232
 
1796 2233
     //get initial movie
1797 2234
     movie = new BlinkenMovie( defHeight, defWidth, defChannels, defMaxval );
1798
-    movie.insertInfo( 0, "creator", "Blimp (version 1.0 date 2005-03-24)" );
2235
+    movie.insertInfo( 0, "creator", "Blimp (version 1.1 date 2005-04-16)" );
1799 2236
     movie.insertFrame( 0, new BlinkenFrame( defHeight, defWidth, defChannels, defMaxval, defDuration ) );
1800 2237
 
1801 2238
     //process parameters
... ...
@@ -1,5 +1,5 @@
1 1
 /* BlinkenLightsInteractiveMovieProgram
2
- * version 1.0 date 2005-03-24
2
+ * version 1.1 date 2005-04-16
3 3
  * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
  * a blinkenarea.org project
... ...
@@ -1,5 +1,5 @@
1 1
 /* BlinkenLightsInteractiveMovieProgram
2
- * version 1.0 date 2005-03-24
2
+ * version 1.1 date 2005-04-16
3 3
  * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
  * a blinkenarea.org project
... ...
@@ -1,5 +1,5 @@
1 1
 /* BlinkenLightsInteractiveMovieProgram
2
- * version 1.0 date 2005-03-24
2
+ * version 1.1 date 2005-04-16
3 3
  * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
  * a blinkenarea.org project
... ...
@@ -1,5 +1,5 @@
1 1
 /* BlinkenLightsInteractiveMovieProgram
2
- * version 1.0 date 2005-03-24
2
+ * version 1.1 date 2005-04-16
3 3
  * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
  * a blinkenarea.org project
... ...
@@ -1,5 +1,5 @@
1 1
 /* BlinkenLightsInteractiveMovieProgram
2
- * version 1.0 date 2005-03-24
2
+ * version 1.1 date 2005-04-16
3 3
  * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
  * a blinkenarea.org project
... ...
@@ -1,5 +1,5 @@
1 1
 /* BlinkenLightsInteractiveMovieProgram
2
- * version 1.0 date 2005-03-24
2
+ * version 1.1 date 2005-04-16
3 3
  * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
  * a blinkenarea.org project
... ...
@@ -1,5 +1,5 @@
1 1
 /* BlinkenLightsInteractiveMovieProgram
2
- * version 1.0 date 2005-03-24
2
+ * version 1.1 date 2005-04-16
3 3
  * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
  * a blinkenarea.org project
... ...
@@ -1,5 +1,5 @@
1 1
 /* BlinkenLightsInteractiveMovieProgram
2
- * version 1.0 date 2005-03-24
2
+ * version 1.1 date 2005-04-16
3 3
  * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
  * a blinkenarea.org project
... ...
@@ -4,6 +4,18 @@ Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
4 4
 a blinkenarea.org project
5 5
 powered by eventphone.de
6 6
 
7
+version 1.1 date 2005-04-16
8
+---------------------------
9
+ - frame scroll bar now has block increment of 1
10
+ - added buttons to insert, duplicate and delete frames
11
+ - added keyboard shortcuts for menu commands
12
+ - extended image import function for importing multiple images
13
+ - when inserting or importing a frame, duration of current frame is copied
14
+ - added function to import BlinkenLights movies
15
+ - added frame-selection stuff
16
+   - selecting sequences of frames
17
+   - copying, moving, reversing, delting
18
+
7 19
 version 1.0 date 2005-02-24
8 20
 ---------------------------
9 21
  - now considered stable
... ...
@@ -1,5 +1,5 @@
1 1
 # BlinkenLightsInteractiveMovieProgram
2
-# version 1.0 date 2005-03-24
2
+# version 1.1 date 2005-04-16
3 3
 # Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
4 4
 # Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 5
 # a blinkenarea.org project
... ...
@@ -25,7 +25,8 @@ IMAGE_FILES=images/ColorPicker.png images/Dot.png images/Line.png \
25 25
             images/Rotate90.png images/MirrorVer.png images/RollRight.png \
26 26
             images/Rotate180.png images/MirrorDiag.png images/RollUp.png \
27 27
             images/Rotate270.png images/MirrorDiag2.png images/RollDown.png \
28
-            images/Undo.png images/Redo.png
28
+            images/Undo.png images/Redo.png \
29
+            images/InsertFrame.png images/DuplicateFrame.png images/DeleteFrame.png
29 30
 
30 31
 .phony: all clean jar run
31 32