Changeset 1047 for trunk


Ignore:
Timestamp:
04/28/16 19:37:35 (8 years ago)
Author:
davidb
Message:

Anchor top and left added as minus options to an @i item. Relocation of ParseArgsApache(). Addition of getData type function for Bool. Some typos fixed in comments. Left click on image refinement: it check the pixel clicked on in the image, and if the same as the background, it does a back() operation rather than forming a new link

Location:
trunk/src/org/expeditee
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/gui/FrameMouseActions.java

    r998 r1047  
    1919package org.expeditee.gui;
    2020
     21import java.awt.Color;
    2122import java.awt.Image;
    2223import java.awt.Point;
     
    911912
    912913                /*
    913                  * This makes it so clicking repeatedly on the frameName doesnt add the
     914                 * This makes it so clicking repeatedly on the frameName doesn't add the
    914915                 * frames to the backup stack. Only the first frame is added to the
    915916                 * backup stack.
     
    945946
    946947                // Mike says...
    947                 // For somereason the modifiers for e are different from modifiersEx
     948                // For some reason the modifiers for e are different from modifiersEx
    948949                // The SwingUtilities.convertMouseEvent method changes the modifiers
    949950                _lastMouseClick = e;
     
    10601061                // Auto-hide popups when user clicks into expeditee world
    10611062                // If the user clicks into empty space and a popup-is showing, then
    1062                 // the user porbably wants to click away the popup - therefore ignore
     1063                // the user probably wants to click away the popup - therefore ignore
    10631064                // the event
    10641065                boolean shouldConsume = PopupManager.getInstance()
     
    14011402                if (clicked instanceof Text) {
    14021403                        Text text = (Text) clicked;
    1403                         /* Dont follow link when just highlighting text with the left button */
     1404                        /* Don't follow link when just highlighting text with the left button */
    14041405                        if (text.getText().length() == 0)
    14051406                                clicked = null;
     
    14571458                }
    14581459
     1460               
     1461                if (clicked instanceof Picture) {
     1462                        int mouseX = DisplayIO.getMouseX();
     1463                        int mouseY = FrameMouseActions.getY();
     1464                        Picture clickedOnPicture = (Picture)clicked;
     1465                        Frame current_frame = DisplayIO.getCurrentFrame();
     1466                        Color bg_col = current_frame.getBackgroundColor();
     1467                        if (clickedOnPicture.MouseOverBackgroundPixel(mouseX,mouseY,bg_col)) {
     1468                                // Make 'clicked' null, effectively causing a back() operation
     1469                                clicked = null;
     1470                        }
     1471                }
     1472               
    14591473                if (clicked != null) {
    14601474                        // check item permissions
     
    15001514
    15011515                } else {
     1516                       
    15021517                        IndirectMouseActions.getInstance().getBackAction().exec(new MouseInfo(clicked, clickedIn, isShiftDown, isControlDown));
    15031518                }
  • trunk/src/org/expeditee/items/Picture.java

    r919 r1047  
    3636import java.awt.image.FilteredImageSource;
    3737import java.awt.image.ImageObserver;
     38import java.awt.image.PixelGrabber;
    3839import java.io.File;
    3940import java.io.IOException;
     
    4344import javax.swing.ImageIcon;
    4445
     46import org.apache.commons.cli.CommandLine;
     47import org.apache.commons.cli.CommandLineParser;
     48import org.apache.commons.cli.GnuParser;
     49import org.apache.commons.cli.Options;
     50import org.apache.commons.cli.ParseException;
     51import org.expeditee.gui.DisplayIO;
    4552import org.expeditee.gui.FrameGraphics;
    4653import org.expeditee.gui.FrameIO;
    4754import org.expeditee.gui.FrameMouseActions;
    4855import org.expeditee.gui.FrameUtils;
     56import org.expeditee.items.widgets.InteractiveWidget;
    4957import org.expeditee.stats.Logger;
    5058
     
    97105        private boolean _showCropping = false;
    98106
     107        protected Integer _anchorLeft   = null;
     108        protected Integer _anchorTop    = null;
     109       
    99110        private String _path = "";
    100111
     
    113124                refresh();
    114125
    115                 if (_image != null)
     126                if (_image != null) {
     127                        // Should parsing for minus options also be done?
     128                        // To be honest, looking at the code, can't really see how _size can be anything but
     129                        // the empty string at this stage of calling the constructor, although it does have
     130                        // the 'side' effect of setting other things (such as _start, _end, and _scale)
    116131                        parseSize();
     132                }
    117133        }
    118134
     
    140156                _fileName = fileName;
    141157                _path = path;
    142                 _size = size;
     158               
     159                String size_without_options = parseMinusOptions(size);
     160                _size = size_without_options;
    143161
    144162                refresh();
     
    150168        }
    151169
     170        protected String parseMinusOptions(String cmd_line) {
     171               
     172                String[] tokens = Text.parseArgsApache(cmd_line);
     173
     174                // make anything starting with a '-' lowercase
     175                for (int i=0; i<tokens.length; i++) {
     176                        if (tokens[i].startsWith("-")) {
     177                                tokens[i] = tokens[i].toLowerCase();
     178                        }
     179                }
     180               
     181                // create the command line parser
     182                CommandLineParser parser = new GnuParser();
     183
     184                // create the Options
     185                Options options = new Options();
     186                options.addOption( "al", "anchorleft",   true, "Anchor the vertical left-hand edge of the interactive widget to the value provided " );
     187                options.addOption( "at", "anchortop",    true, "Anchor the vertical top edge of the interactive widget to the value provided " );
     188       
     189                CommandLine core_line;
     190                try {
     191                    // parse the command line arguments
     192                    core_line = parser.parse( options, tokens );
     193                   
     194                    // Update tokens to be version with the options removed
     195                    tokens = core_line.getArgs();
     196                   
     197                }
     198                catch( ParseException exp ) {
     199                    System.err.println( "Unexpected exception:" + exp.getMessage() );
     200                    core_line = null;
     201                   
     202                }
     203               
     204                // Apply any anchor values supplied
     205               
     206            if(core_line.hasOption( "anchorleft" ) ) {
     207                String al_str = core_line.getOptionValue( "anchorleft" );
     208               
     209                _anchorLeft = Integer.parseInt(al_str);
     210            }
     211           
     212            if(core_line.hasOption( "anchortop" ) ) {
     213                String at_str = core_line.getOptionValue( "anchortop" );
     214               
     215                _anchorTop = Integer.parseInt(at_str);
     216            }
     217           
     218           
     219           return String.join(" ", tokens);
     220        }
    152221        protected void parseSize() {
    153222                String size = getImageSize();
     
    294363                Point centre = new Point();
    295364
     365                int base_x = (_anchorLeft!=null) ? _anchorLeft : _source.getX();
     366                int base_y = (_anchorTop!=null) ? _anchorTop : _source.getY();
     367               
    296368                if (_cropStart == null || _cropEnd == null) {
    297369                        int width = getWidth();
    298370                        int height = getHeight();
    299371                       
    300                         centre.x = _source.getX() + width / 2;
    301                         centre.y = _source.getY() + height / 2;
     372                        centre.x = base_x + width / 2;
     373                        centre.y = base_y + height / 2;
    302374
    303375                        int xdiff = -MARGIN_RIGHT; // -getLeftMargin();
     
    309381//                      _poly.addPoint(_source.getX() + 1 + xdiff, _source.getY() + height);
    310382                       
    311                         ori[0] = new Point(_source.getX() + 1 + xdiff, _source.getY() - 1);
    312                         ori[1] = new Point(_source.getX() + width, _source.getY() - 1);
    313                         ori[2] = new Point(_source.getX() + width, _source.getY() + height);
    314                         ori[3] = new Point(_source.getX() + 1 + xdiff, _source.getY() + height);
     383                        ori[0] = new Point(base_x + 1 + xdiff, base_y - 1);
     384                        ori[1] = new Point(base_x + width,  base_y - 1);
     385                        ori[2] = new Point(base_x + width,  base_y + height);
     386                        ori[3] = new Point(base_x + 1 + xdiff, base_y + height);
    315387                       
    316388                } else {
     
    318390                        Point bottomRight = getBottomRightCrop();
    319391                       
    320                         centre.x = _source.getX() + (bottomRight.x - topLeft.x) / 2;
    321                         centre.y = _source.getY() + (bottomRight.y - topLeft.y) / 2;
    322                        
    323                         Rectangle clip = new Rectangle(topLeft.x + _source.getX(),
    324                                         topLeft.y + _source.getY(), bottomRight.x - topLeft.x,
     392                        centre.x = base_x + (bottomRight.x - topLeft.x) / 2;
     393                        centre.y = base_y + (bottomRight.y - topLeft.y) / 2;
     394                       
     395                        Rectangle clip = new Rectangle(topLeft.x + base_x,
     396                                        topLeft.y + base_y, bottomRight.x - topLeft.x,
    325397                                        bottomRight.y - topLeft.y).getBounds();
    326398//                      _poly.addPoint((int) clip.getMinX() - 1, (int) clip.getMinY() - 1);
     
    399471                }
    400472               
    401                 int dX1 = _source.getX();
    402                 int dY1 = _source.getY();
    403                 int dX2 = _source.getX() + getWidth();
    404                 int dY2 = _source.getY() + getHeight();
     473                int base_x = (_anchorLeft!=null) ? _anchorLeft : _source.getX();
     474                int base_y = (_anchorTop!=null) ? _anchorTop : _source.getY();
     475               
     476                int dX1 = base_x;
     477                int dY1 = base_y;
     478                int dX2 = base_x + getWidth();
     479                int dY2 = base_y + getHeight();
    405480               
    406481                BufferedImage tmp = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
     
    485560                        Point topLeft = getTopLeftCrop();
    486561                        Point bottomRight = getBottomRightCrop();
    487                         Shape clip = new Rectangle(_source.getX() + topLeft.x, _source.getY() + topLeft.y,
     562                        int base_x = (_anchorLeft!=null) ? _anchorLeft : _source.getX();
     563                        int base_y = (_anchorTop!=null) ? _anchorTop : _source.getY();
     564                       
     565                        Shape clip = new Rectangle(base_x + topLeft.x, base_y + topLeft.y,
    488566                                        bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
    489567                        g.setColor(getPaintHighlightColor());
     
    572650                        p._start = new Point(startX, startY);
    573651                        p._end = new Point(endX, endY);
    574                         p._source.setPosition(topLeft.x + _source.getX(), topLeft.y
    575                                         + _source.getY());
     652                        int base_x = (_anchorLeft!=null) ? _anchorLeft : _source.getX();
     653                        int base_y = (_anchorTop!=null) ? _anchorTop : _source.getY();
     654                        p._source.setPosition(topLeft.x + base_x, topLeft.y + base_y);
    576655                } else {
    577656                        p._start = new Point(_start);
     
    891970        }
    892971
     972        public boolean MouseOverBackgroundPixel(int mouseX, int mouseY, Color bg_col)
     973        {
     974                int[] pixels = new int[1];
     975                 
     976                int base_x = (_anchorLeft!=null) ? _anchorLeft : _source.getX();
     977                int base_y = (_anchorTop!=null) ? _anchorTop : _source.getY();
     978                int x = mouseX - base_x;
     979                int y = mouseY - base_y;
     980               
     981                // Consider making this a slightly larger area to check, say 3 x 3?
     982                // Back op if all are the same sought after color?
     983                PixelGrabber grabber = new PixelGrabber(_image, x,y, 1, 1, pixels, 0, 1);
     984               
     985                // The following might be a better approach, as it sets the color model
     986                // when getPixels() is called, however, it might return an int[] or byte[]
     987                // array (handled as Object), as so some extra complexity would exist in
     988                // handling the returned result
     989               
     990                //PixelGrabber pg = new PixelGrabber(_image, mouseX, mouseY, 1, 1, true);
     991               
     992                try {
     993                        grabber.grabPixels(0);
     994                }
     995                catch (Exception e) {
     996                        e.printStackTrace();
     997                }
     998               
     999       
     1000                int c = pixels[0];
     1001                int c_red    = (c & 0x00ff0000) >> 16;
     1002                int c_green  = (c & 0x0000ff00) >> 8;
     1003                int c_blue   =  c & 0x000000ff;
     1004               
     1005                int bg_red   = (bg_col!=null) ? bg_col.getRed()   : 0xff;
     1006                int bg_green = (bg_col!=null) ? bg_col.getGreen() : 0xff;
     1007                int bg_blue  = (bg_col!=null) ? bg_col.getBlue()  : 0xff;
     1008               
     1009                int red_diff   = Math.abs(c_red   - bg_red);
     1010                int green_diff = Math.abs(c_green - bg_green);
     1011                int blue_diff  = Math.abs(c_blue  - bg_blue);
     1012               
     1013                return ((red_diff<=2) && (green_diff<=2) && (blue_diff<=2));
     1014       
     1015        }
    8931016}
  • trunk/src/org/expeditee/items/Text.java

    r983 r1047  
    4444
    4545import java.text.AttributedString;
     46import java.util.ArrayList;
    4647import java.util.Collection;
    4748import java.util.HashMap;
     
    4950import java.util.LinkedList;
    5051import java.util.List;
     52import java.util.StringTokenizer;
    5153
    5254import org.expeditee.gui.AttributeValuePair;
     
    251253        }
    252254
    253        
     255        /**
     256     * Similar to parseArgs() in InteractiveWidget. 
     257     * Code based on routine used in Apache Ant:
     258     *   org.apache.tools.ant.types.Commandline::translateCommandline()
     259     * @param toProcess the command line to process.
     260     * @return the command line broken into strings.
     261     * An empty or null toProcess parameter results in a zero sized array.
     262     */
     263    public static String[] parseArgsApache(String toProcess) {
     264        if (toProcess == null || toProcess.length() == 0) {
     265            //no command? no string
     266            return new String[0];
     267        }
     268        // parse with a simple finite state machine
     269
     270        final int normal = 0;
     271        final int inQuote = 1;
     272        final int inDoubleQuote = 2;
     273        int state = normal;
     274        final StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true);
     275        final ArrayList<String> result = new ArrayList<String>();
     276        final StringBuilder current = new StringBuilder();
     277        boolean lastTokenHasBeenQuoted = false;
     278
     279        while (tok.hasMoreTokens()) {
     280            String nextTok = tok.nextToken();
     281            switch (state) {
     282            case inQuote:
     283                if ("\'".equals(nextTok)) {
     284                    lastTokenHasBeenQuoted = true;
     285                    state = normal;
     286                } else {
     287                    current.append(nextTok);
     288                }
     289                break;
     290            case inDoubleQuote:
     291                if ("\"".equals(nextTok)) {
     292                    lastTokenHasBeenQuoted = true;
     293                    state = normal;
     294                } else {
     295                    current.append(nextTok);
     296                }
     297                break;
     298            default:
     299                if ("\'".equals(nextTok)) {
     300                    state = inQuote;
     301                } else if ("\"".equals(nextTok)) {
     302                    state = inDoubleQuote;
     303                } else if (" ".equals(nextTok)) {
     304                    if (lastTokenHasBeenQuoted || current.length() != 0) {
     305                        result.add(current.toString());
     306                        current.setLength(0);
     307                    }
     308                } else {
     309                    current.append(nextTok);
     310                }
     311                lastTokenHasBeenQuoted = false;
     312                break;
     313            }
     314        }
     315        if (lastTokenHasBeenQuoted || current.length() != 0) {
     316            result.add(current.toString());
     317        }
     318        if (state == inQuote || state == inDoubleQuote) {
     319            System.err.println("Error: Unbalanced quotes -- failed to parse '" + toProcess + "'");
     320            return null;
     321        }
     322
     323        return result.toArray(new String[result.size()]);
     324    }
     325
    254326
    255327        /**
  • trunk/src/org/expeditee/items/widgets/InteractiveWidget.java

    r919 r1047  
    197197                //     @iw: <class name> [options] width height : <rest...>
    198198                //
    199                 //   Parse the 'core' part of the X-rayable text item
     199                //    the 'core' part of the X-rayable text item
    200200                //   i.e, the text between the first ':' and the second ':'
    201201                // 
     
    204204                String tokens_str = (index == -1) ? text : text.substring(0, index);
    205205
    206                 String[] tokens = parseArgsApache(tokens_str);
     206                String[] tokens = Text.parseArgsApache(tokens_str);
    207207
    208208                // make anything starting with a '-' lowercase
     
    342342                                String args_str = text.substring(index + 1);
    343343                               
    344                                  args = parseArgsApache(args_str);
     344                                 args = Text.parseArgsApache(args_str);
    345345               
    346346                        }       
     
    559559
    560560
    561     /**
    562      * Similar to parseArgs() above. 
    563      * Code based on routine used in Apache Ant:
    564      *   org.apache.tools.ant.types.Commandline::translateCommandline()
    565      * @param toProcess the command line to process.
    566      * @return the command line broken into strings.
    567      * An empty or null toProcess parameter results in a zero sized array.
    568      */
    569     public static String[] parseArgsApache(String toProcess) {
    570         if (toProcess == null || toProcess.length() == 0) {
    571             //no command? no string
    572             return new String[0];
    573         }
    574         // parse with a simple finite state machine
    575 
    576         final int normal = 0;
    577         final int inQuote = 1;
    578         final int inDoubleQuote = 2;
    579         int state = normal;
    580         final StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true);
    581         final ArrayList<String> result = new ArrayList<String>();
    582         final StringBuilder current = new StringBuilder();
    583         boolean lastTokenHasBeenQuoted = false;
    584 
    585         while (tok.hasMoreTokens()) {
    586             String nextTok = tok.nextToken();
    587             switch (state) {
    588             case inQuote:
    589                 if ("\'".equals(nextTok)) {
    590                     lastTokenHasBeenQuoted = true;
    591                     state = normal;
    592                 } else {
    593                     current.append(nextTok);
    594                 }
    595                 break;
    596             case inDoubleQuote:
    597                 if ("\"".equals(nextTok)) {
    598                     lastTokenHasBeenQuoted = true;
    599                     state = normal;
    600                 } else {
    601                     current.append(nextTok);
    602                 }
    603                 break;
    604             default:
    605                 if ("\'".equals(nextTok)) {
    606                     state = inQuote;
    607                 } else if ("\"".equals(nextTok)) {
    608                     state = inDoubleQuote;
    609                 } else if (" ".equals(nextTok)) {
    610                     if (lastTokenHasBeenQuoted || current.length() != 0) {
    611                         result.add(current.toString());
    612                         current.setLength(0);
    613                     }
    614                 } else {
    615                     current.append(nextTok);
    616                 }
    617                 lastTokenHasBeenQuoted = false;
    618                 break;
    619             }
    620         }
    621         if (lastTokenHasBeenQuoted || current.length() != 0) {
    622             result.add(current.toString());
    623         }
    624         if (state == inQuote || state == inDoubleQuote) {
    625             System.err.println("Error: Unbalanced quotes -- failed to parse '" + toProcess + "'");
    626             return null;
    627         }
    628 
    629         return result.toArray(new String[result.size()]);
    630     }
    631 
     561   
    632562
    633563
     
    17161646                return defaultValue;
    17171647        }
    1718 
    1719         /**
    1720          * Looks fors a dataline in the current representation of the widget.
     1648       
     1649       
     1650
     1651        /**
     1652         * Looks for a dataline in the current representation of the widget.
    17211653         *
    17221654         * @see #getCurrentRepresentation
     
    17591691        }
    17601692
     1693        /**
     1694         * Looks for a data-line in the current representation of the widget.
     1695         *
     1696         * @see #getCurrentRepresentation
     1697         * @see #getStrippedDataString(String)
     1698         * @see #getStrippedDataLong(String, long)
     1699         *
     1700         * @param tag
     1701         *            The prefix of a data-line that will be matched. Must be larger
     1702         *            the zero and not null.
     1703         *
     1704         * @param defaultValue
     1705         *            The default value if the tag does not exist or contains
     1706         *            invalid data.
     1707         *
     1708         * @return The <i>first</i> data-line that matched the prefix - if
     1709         *         case insensitive match is 'true' then return true, otherwise
     1710         *         false. defaultValue if their was no data that
     1711         *         matched the given prefix or the data was invalid.
     1712         *         
     1713         * @throws IllegalArgumentException
     1714         *             If tag is null.
     1715         *
     1716         * @throws NullPointerException
     1717         *             If tag is empty.
     1718         *
     1719         */
     1720        protected Boolean getStrippedDataBool(String tag, Boolean defaultValue) {
     1721
     1722                String strippedStr = getStrippedDataString(tag);
     1723
     1724                if (strippedStr != null) {
     1725                        strippedStr = strippedStr.trim();
     1726                        if (strippedStr.length() > 0) {
     1727                                return strippedStr.equalsIgnoreCase("true") ? true : false;
     1728                        }
     1729                }
     1730
     1731                return defaultValue;
     1732        }
     1733       
     1734       
    17611735        /**
    17621736         * All data is removed that is prefixed with the given tag.
Note: See TracChangeset for help on using the changeset viewer.