Changeset 344


Ignore:
Timestamp:
10/05/08 14:30:01 (16 years ago)
Author:
bjn8
Message:

Improve mouse interactions a little with accurate audio placement

Location:
trunk/src_apollo/org/apollo
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src_apollo/org/apollo/ApolloSystem.java

    r331 r344  
    33import java.awt.Image;
    44import java.awt.Toolkit;
    5 import java.awt.event.KeyEvent;
    6 import java.awt.event.KeyListener;
    7 import java.awt.event.MouseEvent;
    8 import java.awt.event.MouseMotionListener;
    95import java.awt.event.WindowEvent;
    106import java.awt.event.WindowListener;
     
    128import java.util.Collection;
    139import java.util.HashSet;
    14 import java.util.List;
    1510import java.util.Set;
    1611
     
    3025import org.apollo.io.SampledAudioFileImporter;
    3126import org.apollo.util.AudioSystemLog;
    32 import org.apollo.widgets.LinkedTrack;
    33 import org.apollo.widgets.SampledTrack;
    3427import org.expeditee.actions.Actions;
    3528import org.expeditee.gui.Browser;
    36 import org.expeditee.gui.DisplayIO;
    37 import org.expeditee.gui.Frame;
    38 import org.expeditee.gui.FrameGraphics;
    3929import org.expeditee.gui.FrameMouseActions;
    40 import org.expeditee.gui.FreeItems;
    4130import org.expeditee.importer.FrameDNDTransferHandler;
    42 import org.expeditee.items.Item;
    43 import org.expeditee.items.widgets.InteractiveWidget;
    4431
    4532/**
     
    5946        public static final String HELP_MELODYSEARCH_FRAMENAME = SYSTEM_FRAMESET_NAME + 3;
    6047       
    61         private static final int COARSE_PLACEMENT_TOLERANCE = 100; // The minium distance from a track widet to auto-align free space items to
    62        
     48
    6349        public static boolean useQualityGraphics = true;
    6450       
    65         /** Would be nice to seperate outside of this class.. */
    66         private static boolean isControlDown = false;
    67         private static boolean isShiftDown = false;
    68 
    6951        private ApolloSystem() {
    7052        }
     
    8567                               
    8668                                 try {
    87 
    8869
    8970                                        URL url = ClassLoader.getSystemResource("org/apollo/icons/mainicon.png");
     
    127108                                });
    128109                               
    129                                 // Refresh frame for graphical helpers that display / hide when the
    130                                 // user presses various keys
    131                                 Browser._theBrowser.getContentPane().addKeyListener(new KeyListener() {
    132 
    133                                         public void keyPressed(KeyEvent e) {
    134                                                 isControlDown = e.isControlDown();
    135                                                 isShiftDown = e.isShiftDown();
    136                                                 if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
    137                                                         FrameGraphics.refresh(false); // For special post effects
    138                                                 }
    139                                                
    140                                         }
    141 
    142                                         public void keyReleased(KeyEvent e) {
    143                                                 isControlDown = e.isControlDown();
    144                                                 isShiftDown = e.isShiftDown();
    145                                                 if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
    146                                                         FrameGraphics.refresh(false); // For special post effects
    147                                                 } else if (e.getKeyCode() == KeyEvent.VK_G && e.isControlDown()) {
    148                                                         useQualityGraphics = !useQualityGraphics;
    149                                                 }
    150                                         }
    151 
    152                                         public void keyTyped(KeyEvent e) {
    153                                         }
    154                                        
    155                                 });
     110                                Browser._theBrowser.getContentPane().addKeyListener(new AudioFrameKeyboardActions());
    156111
    157112                                // Filter out some special mouse move cases
     
    159114                                                FrameMouseActions.getInstance());
    160115                               
    161                                 // The mouse move code below essentially is for auto-alignment of free items
    162                                 // to anchored track widgets while holding the shift button
    163                                 Browser._theBrowser.getMouseEventRouter().addExpediteeMouseMotionListener(new MouseMotionListener() {
    164 
    165                                         public void mouseDragged(MouseEvent e) {
    166                                                 FrameMouseActions.getInstance().mouseDragged(e);
    167                                         }
    168 
    169                                         public void mouseMoved(MouseEvent e) {
    170        
    171                                                 boolean forwareToExpeditee = true;
    172                                                
    173                                                 if (isControlDown != e.isControlDown()) {
    174                                                         isControlDown = e.isControlDown();
    175                                                         FrameGraphics.refresh(false); // For special post effects
    176                                                 }
    177                                                
    178                                                 isShiftDown = e.isShiftDown();
    179                                                
    180                                                 if (e.isShiftDown() &&
    181                                                                 !FreeItems.getInstance().isEmpty()) {
    182                                                        
    183                                                         // Couse movement of free items: Restraining left-most pixel in items
    184                                                         // to the closest anchored track widgets x position.
    185                                                        
    186                                                         Frame currentFrame = DisplayIO.getCurrentFrame();
    187                                                         if (currentFrame != null) {
    188                                                                
    189                                                                 // Search all anchored track x positions for the current frame
    190                                                                 List<InteractiveWidget> widgets = currentFrame.getInteractiveWidgets();
    191                                                                
    192                                                                 int closestXPosition = -1;
    193                                                                 int closestDistance = -1;
    194                                                                
    195                                                                 for (InteractiveWidget iw : widgets) {
    196                                                                         if (iw instanceof SampledTrack || iw instanceof LinkedTrack) {
    197                                                                                 int distance = Math.abs(e.getX() - iw.getX());
    198                                                                                 if (closestDistance < 0 || distance < closestDistance) {
    199                                                                                         closestDistance = distance;
    200                                                                                         closestXPosition = iw.getX();
    201                                                                                 }
    202 
    203                                                                                 distance = Math.abs(e.getX() - (iw.getX() + iw.getWidth()));
    204                                                                                 if (closestDistance < 0 || distance < closestDistance) {
    205                                                                                         closestDistance = distance;
    206                                                                                         closestXPosition = iw.getX() + iw.getWidth();
    207                                                                                 }
    208                                                                                
    209                                                                         }
    210                                                                 }
    211                                                                
    212                                                                 int smallestX = FreeItems.getInstance().get(0).getX();
    213                                                                 int smallestY = FreeItems.getInstance().get(0).getY();
    214 
    215                                                                 for (Item i : FreeItems.getInstance()) {
    216                                                                         if (i.getX() < smallestX) smallestX = i.getX();
    217                                                                         if (i.getY() < smallestY) smallestY = i.getY();
    218                                                                 }
    219                                                                
    220                                                                 // Should auto-adjust free items?
    221                                                                 if (closestDistance > 0 &&
    222                                                                                 closestDistance < COARSE_PLACEMENT_TOLERANCE) { // NB: 0 = do nothing since already there
    223        
    224                                                                         for (Item i : FreeItems.getInstance()) {
    225                                                                                 i.setPosition(
    226                                                                                                 closestXPosition + (i.getX() - smallestX),
    227                                                                                                 e.getY() + (i.getY() - smallestY));
    228                                                                                
    229                                                                         }
    230                                                                        
    231                                                                 } else if (closestDistance > 0) { // keep things set to cursor
    232 
    233                                                                         for (Item i : FreeItems.getInstance()) {
    234                                                                                 i.setPosition(
    235                                                                                                 e.getX() + (i.getX() - smallestX),
    236                                                                                                 e.getY() + (i.getY() - smallestY));
    237                                                                         }
    238                        
    239                                                                 }
    240                                                                
    241                                                                 forwareToExpeditee = false;
    242 
    243                                                         }
    244                                                        
    245                                                 }
    246                                                
    247                                                 // Expeditees frame mouse actions uses an offset and fights over free-item
    248                                                 // movement if it listens to the mouse event router... therefore add an extra
    249                                                 // layer to avoid this... otherwise auto-aligned items jitter like crazy while
    250                                                 // moving the cursus
    251                                                 if (forwareToExpeditee) {
    252                                                         FrameMouseActions.getInstance().mouseMoved(e);
    253                                                 } else {
    254                                                         FrameGraphics.refresh(true);
    255                                                 }
    256                                         }
    257 
    258                                 });
     116                                Browser._theBrowser.getMouseEventRouter().addExpediteeMouseMotionListener(new AudioFrameMouseActions());
    259117                        }
    260118                });
     
    263121                 //Browser._theBrowser.etTitle("Apollo");
    264122
    265                 System.err.println("WARNING: MISSING MAIN ICON"); // TODO
    266                
    267123                AudioSystemLog.println("  Preparing sub-systems...");
    268124               
     
    346202        }
    347203       
    348        
    349         /**
    350          * @return True if control is down.
    351          */
    352         public static boolean isControlDown() {
    353                 return isControlDown;
    354         }
    355        
    356        
    357         /**
    358          * @return True if shift is down.
    359          */
    360         public static boolean isShiftDown() {
    361                 return isShiftDown;
    362         }
    363204
    364205
  • trunk/src_apollo/org/apollo/audio/util/FrameLayoutDaemon.java

    r342 r344  
    587587       
    588588        /**
     589         * @param ms
     590         *              The time to translate the x position from
     591         *
     592         * @param targetFrame
     593         *              The frame to determine the timeline information from
     594         *
     595         * @return
     596         *              Null if the timeline for the target frame could not
     597         *              be determined/inferred or has no timeline. Otherwise the
     598         *              X pixal position at the given time.
     599         */
     600        public NullableLong getXAtMS(long ms, Frame targetFrame) {
     601                assert(targetFrame != null);
     602               
     603                Timeline tl = getTimeline(targetFrame);
     604                if (tl == null) return null;
     605                return new NullableLong(tl.getXAtMSTime(ms));
     606        }
     607       
     608        /**
    589609         * Determines the pixel width from a time range (ms) for a target frame.
    590610         * <b>NOTE</B> Width is clamped to it is never smaller than {@link #MIN_TRACK_WIDGET_WIDTH}
  • trunk/src_apollo/org/apollo/gui/FrameRenderPasses.java

    r333 r344  
    1010import java.util.LinkedList;
    1111
    12 import org.apollo.ApolloSystem;
     12import org.apollo.AudioFrameKeyboardActions;
    1313import org.apollo.audio.util.Timeline;
    1414import org.apollo.items.FramePlaybackLauncher;
     
    171171               
    172172                helperLinesToPaint = null;
    173                 shouldDrawFullscreenHelpers = ApolloSystem.isControlDown() ||
    174                         (ApolloSystem.isShiftDown() && !FreeItems.getInstance().isEmpty());
     173                shouldDrawFullscreenHelpers = AudioFrameKeyboardActions.isControlDown() ||
     174                        (AudioFrameKeyboardActions.isShiftDown() && !FreeItems.getInstance().isEmpty());
    175175
    176176                // Get free tracks and paint line helpers
  • trunk/src_apollo/org/apollo/items/EmulatedTextItem.java

    r315 r344  
    88import java.awt.Graphics;
    99import java.awt.Graphics2D;
     10import java.awt.IllegalComponentStateException;
    1011import java.awt.Point;
    1112import java.awt.Rectangle;
     
    517518               
    518519                // Restore emulated position for consuming mouse movements
     520                try {
    519521                Point pos = this.convertToExpediteeSpace(parentComponant.getLocationOnScreen());
    520522                emulatedSource.setPosition(
    521523                                pos.x + masterOffset.x,
    522524                                pos.y + masterOffset.y);
     525                } catch (IllegalComponentStateException ex) { // Cannot fix this .. this whole class needs revising
     526                        ex.printStackTrace();
     527                }
    523528        }
    524529       
  • trunk/src_apollo/org/apollo/widgets/LinkedTrack.java

    r343 r344  
    3131
    3232import org.apollo.ApolloSystem;
     33import org.apollo.AudioFrameMouseActions;
    3334import org.apollo.audio.ApolloSubjectChangedEvent;
    3435import org.apollo.audio.SampledAudioManager;
     
    5758import org.apollo.util.AudioMath;
    5859import org.apollo.util.AudioSystemLog;
     60import org.apollo.util.NullableLong;
    5961import org.apollo.util.ODFrameHeirarchyFetcher;
    6062import org.apollo.util.PopupReaper;
     
    645647                        String link = getAbsoluteLink();
    646648
    647                         // Determine new initation time according to anchored position
    648                         long initTime = (parent != null) ?
    649                                                 FrameLayoutDaemon.getInstance().getMSAtX(getX(), parent)
    650                                                 : 0;
     649
     650                        // Determine new initation time according to anchored position...
     651                        long initTime = getInitiationTimeFromMeta();
     652                       
     653                        // If the user is restricting-y-axis movement then they might be moving
     654                        // this tracks Y-position only for layout reasons as opposed to repositioning
     655                        // where in the audio timeline the track should be. This must be accurate and
     656                        // avoid loosing the exact initiation time due to pixel-resolutoin issues
     657                        if (parent != null) {
     658                               
     659                                boolean inferInitTime = true;
     660                               
     661                                if (AudioFrameMouseActions.isYAxisRestictionOn()) {
     662                                        Long ms = getInitiationTimeFromMeta();
     663                                        if (ms != null) {
     664                                                NullableLong timex = FrameLayoutDaemon.getInstance().getXAtMS(
     665                                                                ms,
     666                                                                parent);
     667                                                if (timex != null && timex.getLongValue() == getX()) {
     668                                                        initTime = ms;
     669                                                        inferInitTime = false;
     670                                                }
     671                                        }
     672                                }
     673
     674                                if (inferInitTime)
     675                                        initTime = FrameLayoutDaemon.getInstance().getMSAtX(getX(), parent);
     676                        }
    651677
    652678                        if (link != null) {
  • trunk/src_apollo/org/apollo/widgets/SampledTrack.java

    r342 r344  
    2828import javax.swing.SwingUtilities;
    2929
     30import org.apollo.AudioFrameMouseActions;
    3031import org.apollo.audio.ApolloPlaybackMixer;
    3132import org.apollo.audio.ApolloSubjectChangedEvent;
     
    5354import org.apollo.mvc.SubjectChangedEvent;
    5455import org.apollo.util.AudioMath;
     56import org.apollo.util.NullableLong;
    5557import org.apollo.util.PopupReaper;
    5658import org.apollo.util.TrackModelHandler;
     
    13611363                                        parent = getParentFrame();
    13621364
    1363                                         // Determine new initation time according to anchored position
    1364                                         long initTime = (parent != null) ?
    1365                                                         FrameLayoutDaemon.getInstance().getMSAtX(getX(), parent)
    1366                                                         : 0;
    1367                                        
     1365                                        // Determine new initation time according to anchored position...
     1366                                        long initTime = getInitiationTimeFromMeta();
     1367                                       
     1368                                        // If the user is restricting-y-axis movement then they might be moving
     1369                                        // this tracks Y-position only for layout reasons as opposed to repositioning
     1370                                        // where in the audio timeline the track should be. This must be accurate and
     1371                                        // avoid loosing the exact initiation time due to pixel-resolutoin issues
     1372                                        if (parent != null) {
     1373                                               
     1374                                                boolean inferInitTime = true;
     1375                                               
     1376                                                if (AudioFrameMouseActions.isYAxisRestictionOn()) {
     1377                                                        Long ms = getInitiationTimeFromMeta();
     1378                                                        if (ms != null) {
     1379                                                                NullableLong timex = FrameLayoutDaemon.getInstance().getXAtMS(
     1380                                                                                ms,
     1381                                                                                parent);
     1382                                                                if (timex != null && timex.getLongValue() == getX()) {
     1383                                                                        initTime = ms;
     1384                                                                        inferInitTime = false;
     1385                                                                }
     1386                                                        }
     1387                                                }
     1388
     1389                                                if (inferInitTime)
     1390                                                        initTime = FrameLayoutDaemon.getInstance().getMSAtX(getX(), parent);
     1391                                        }
     1392
    13681393                                        // Keep TrackGraphModel consistant
    13691394                                        AudioStructureModel.getInstance().onTrackWidgetAnchored(
Note: See TracChangeset for help on using the changeset viewer.