Slick Forums

Discuss the Slick 2D Library
It is currently Wed Jun 19, 2013 6:34 am

All times are UTC




Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Fri Jun 01, 2007 6:23 pm 
Offline
User avatar

Joined: Fri May 04, 2007 5:58 pm
Posts: 72
Just a simple menu that can be useful for prototiping or minimalistic designs. ;)

Code:
import java.util.Iterator;

import org.newdawn.slick.Color;
import org.newdawn.slick.Font;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.gui.BasicComponent;
import org.newdawn.slick.gui.ComponentListener;
import org.newdawn.slick.gui.GUIContext;

/**
* Simple text menu, with a font and two colors to make the current option look
* apart.
*/
public class Menu extends BasicComponent {
   public static enum Style {
      VERTICAL_LEFT, VERTICAL_CENTER, VERTICAL_RIGHT, HORIZONTAL
   };

   // Menu options
   protected String options[];

   // Size of the options, so I don't have to compute them every cicle
   protected int widthOpt[], heightOpt;

   // Index of the emphasized option
   protected int emphasized;

   // Index of the selected option
   protected int selection;

   // Font for the options
   protected Font font;

   // Text colours
   protected Color clrNormal, clrEmphasized;

   // Sounds
   protected Sound sndEmphasize, sndSelect;

   protected Style style;

   protected float space;

   private int x, y;

   float width, height;

   /**
    * Constructor.
    *
    * @param container
    *            container
    * @param options
    *            menu options
    * @param font
    *            font
    * @throws SlickException
    *             exception when loading resources
    */
   public Menu(GUIContext container, String options[], Font font) throws SlickException {
      super(container);

      setLocation(0, 0);

      clrNormal = Color.white;
      clrEmphasized = Color.red;
      sndEmphasize = sndSelect = null;

      style = Style.VERTICAL_CENTER;
      space = 10;

      // This computes the size
      setFont(font);
      setOptions(options);

      reset();
   }

   /**
    * Moves the component.
    *
    * @param x
    *            X coordinate
    * @param y
    *            Y coordinate
    */
   public void setLocation(int x, int y) {
      this.x = x;
      this.y = y;
   }

   /**
    * Returns the position in the X coordinate
    *
    * @return x
    */
   public int getX() {
      return x;
   }

   /**
    * Returns the position in the Y coordinate
    *
    * @return y
    */
   public int getY() {
      return y;
   }

   /**
    * Set the menu options.
    *
    * @param options options
    */
   public void setOptions(String options[]) {
      if (options == null || options.length == 0) {
         throw new IllegalArgumentException("Null or empty options");
      }

      this.options = options;

      recomputeSize();
   }

   /**
    * Get the menu options.
    *
    * @return options
    */
   public String[] getOptions() {
      return options;
   }

   /**
    * Sets the blank space between options.
    *
    * @param space space in pixels
    */
   public void setSpace(float space) {
      this.space = space;

      recomputeSize();
   }

   /**
    * Gets the blank space between options.
    *
    * @return space in pixels
    */
   public float getSpace() {
      return space;
   }

   /**
    * Sets the font.
    *
    * @param font font
    */
   public void setFont(Font font) {
      if (font == null) {
         throw new IllegalArgumentException("Null font");
      }

      this.font = font;

      recomputeSize();
   }

   /**
    * Gets the font.
    *
    * @return font
    */
   public Font getFont() {
      return font;
   }

   /**
    * Sets the sound to play when emphasizing an option, null if there is none
    *
    * @param sndEmphasize sound, null for none
    */
   public void setSndEmphasize(Sound sndEmphasize) {
      this.sndEmphasize = sndEmphasize;
   }
   
   /**
    * Gets the sound to play when emphasizing an option, null if there is none
    *
    * @return sound
    */
   public Sound getSndEmphasize() {
      return sndEmphasize;
   }

   /**
    * Sets the sound to play when selecting an option, null if there is none
    *
    * @param sndSelect sound, null for none
    */
   public void setSndSelect(Sound sndSelect) {
      this.sndSelect = sndSelect;
   }

   /**
    * Gets the sound to play when selecting an option, null if there is none
    *
    * @return sound
    */
   public Sound getSndSelect() {
      return sndSelect;
   }
   
   /**
    * Sets the style.
    *
    * @param style
    *            style
    */
   public void setStyle(Style style) {
      this.style = style;

      recomputeSize();
   }

   /**
    * Gets the current style.
    *
    * @return style
    */
   public Style getStyle() {
      return style;
   }

   private void recomputeSize() {
      if (font == null || options == null) {
         width = 0;
         height = 0;
      } else {
         widthOpt = new int[options.length];
         width = (float) (widthOpt[0] = font.getWidth(options[0]));
         for (int i = 1; i < options.length; i++) {
            widthOpt[i] = font.getWidth(options[i]);
            heightOpt = Math.max(heightOpt, font.getHeight(options[i]));

            if (style == Style.HORIZONTAL) {
               width += space + widthOpt[i];
            } else {
               width = Math.max(width, widthOpt[i]);
            }
         }

         if (style == Style.HORIZONTAL) {
            height = heightOpt;
         } else {
            height = (float) (heightOpt * options.length + (options.length - 1)
                  * space);
         }
      }
   }

   /**
    * Render the current frame.
    *
    * @param container game container
    * @param g graphic context
    */
   public void render(GUIContext container, Graphics g) {
      float oX = x, oY = y, styleX;

      Font temp = g.getFont();

      // To be able to tint the menu with whatever color is set before render
      Color clr = g.getColor();
      Color clrNormalT = clrNormal.multiply(clr);
      Color clrEmphasizedT = clrEmphasized
            .multiply(clr);

      g.setFont(font);
      g.setColor(clrNormalT);
      for (int i = 0; i < options.length; i++) {
         styleX = oX;
         if (style == Style.VERTICAL_CENTER) {
            styleX = oX + ((width - widthOpt[i]) / 2);
         } else if (style == Style.VERTICAL_RIGHT) {
            styleX = oX + (width - widthOpt[i]);
         }
         
         if (emphasized == i) {
            g.setColor(clrEmphasizedT);
            g.drawString(options[i], (int) styleX, (int) oY);
            g.setColor(clrNormalT);
         } else {
            g.drawString(options[i], (int) styleX, (int) oY);
         }
         
         if (style == Style.HORIZONTAL) {
            oX += space + widthOpt[i];
         } else {
            oY += space + heightOpt;
         }
      }

      g.setColor(clr);
      g.setFont(temp);
   }

   /**
    * Get the width of the component
    *
    * @return The width of the component
    */
   public int getWidth() {
      return (int) width;
   }

   /**
    * Get the height of the component
    *
    * @return The height of the component
    */
   public int getHeight() {
      return (int) height;
   }

   /**
    * Gets the selected option index, must be called after receiving the
    * component event.
    *
    * @return selected option index, -1 if there is no selection yet
    */
   public int getSelection() {
      return selection;
   }

   /**
    * Reset the emphasized and selected index.
    */
   public void reset() {
      selection = -1;
      emphasized = 0;
   }

   // Methods for the listener stuff

   /**
    * Sets the selected index as the emphasized one, if it has not been set
    * previously.
    */
   private void select() {
      if (selection == -1) {
         selection = emphasized;
         if (sndSelect != null) {
            sndSelect.play();
         }
         
         Iterator it = listeners.iterator();
         while (it.hasNext()) {
            ComponentListener listener = (ComponentListener) it.next();
            listener.componentActivated(this);
         }
         container.getInput().consumeEvent();
      }
   }

   /**
    * Sets the emphasized index.
    *
    * @param emphasized emphasized option index
    */
   private void emphasize(int emphasized) {
      if (emphasized != this.emphasized) {
         this.emphasized = emphasized;
         if (sndEmphasize != null) {
            sndEmphasize.play();
         }
      }
      container.getInput().consumeEvent();
   }

   /**
    * Emphasize the previous option.
    */
   private void emphasizePrevious() {
      if (emphasized == 0) {
         emphasize(options.length - 1);
      } else {
         emphasize((emphasized - 1) % options.length);
      }
      container.getInput().consumeEvent();
   }

   /**
    * Emphasize the next option.
    */
   private void emphasizeNext() {
      if (emphasized == options.length - 1) {
         emphasize(0);
      } else {
         emphasize((emphasized + 1) % options.length);
      }

      container.getInput().consumeEvent();
   }

   // Listener

   /*
    * (non-Javadoc)
    *
    * @see org.newdawn.slick.gui.BasicComponent#controllerButtonPressed(int,
    *      int)
    */
   @Override
   public void controllerButtonPressed(int controller, int button) {
      if (selection == -1) {
         select();
      }
   }

   /*
    * (non-Javadoc)
    *
    * @see org.newdawn.slick.gui.BasicComponent#controllerDownPressed(int)
    */
   @Override
   public void controllerDownPressed(int controller) {
      if (selection == -1 && style != Style.HORIZONTAL) {
         emphasizeNext();
      }
   }

   /*
    * (non-Javadoc)
    *
    * @see org.newdawn.slick.gui.BasicComponent#controllerLeftPressed(int)
    */
   @Override
   public void controllerLeftPressed(int controller) {
      if (selection == -1 && style == Style.HORIZONTAL) {
         emphasizePrevious();
      }
   }

   /*
    * (non-Javadoc)
    *
    * @see org.newdawn.slick.gui.BasicComponent#controllerRightPressed(int)
    */
   @Override
   public void controllerRightPressed(int controller) {
      if (selection == -1 && style == Style.HORIZONTAL) {
         emphasizeNext();
      }
   }

   /*
    * (non-Javadoc)
    *
    * @see org.newdawn.slick.gui.BasicComponent#controllerUpPressed(int)
    */
   @Override
   public void controllerUpPressed(int controller) {
      if (selection == -1 && style != Style.HORIZONTAL) {
         emphasizePrevious();
      }
   }

   /*
    * (non-Javadoc)
    *
    * @see org.newdawn.slick.gui.BasicComponent#keyPressed(int, char)
    */
   @Override
   public void keyPressed(int key, char c) {
      if (selection == -1) {
         if (key == Input.KEY_ENTER) {
            select();
         } else if (((style != Style.HORIZONTAL) && (key == Input.KEY_UP))
               || ((style == Style.HORIZONTAL) && (key == Input.KEY_LEFT))) {
            emphasizePrevious();
         } else if (((style != Style.HORIZONTAL) && (key == Input.KEY_DOWN))
               || ((style == Style.HORIZONTAL) && (key == Input.KEY_RIGHT))) {
            emphasizeNext();
         }
      }
   }

   /*
    * (non-Javadoc)
    *
    * @see org.newdawn.slick.gui.BasicComponent#mouseMoved(int, int, int, int)
    */
   @Override
   public void mouseMoved(int oldx, int oldy, int newx, int newy) {
      if (selection == -1) {
         if (Rectangle.contains(newx, newy, x, y, width, height)) {
            int res = 0;
            if (style == Style.HORIZONTAL) {
               float max = x - (space / 2.0f);
               int i = 0;
               while ((newx > max) && (i < options.length)) {
                  max += widthOpt[i] + space;
                  i++;
               }
               res = i - 1;
            } else {
               res = (int) ((newy - y - (space / 2.0f)) / (heightOpt + space));
            }
            emphasize(res);
         }
      }
   }

   /*
    * (non-Javadoc)
    *
    * @see org.newdawn.slick.gui.BasicComponent#mousePressed(int, int, int)
    */
   @Override
   public void mousePressed(int button, int x, int y) {
      if (selection == -1) {
         // Because the emphasized option can be another one
         mouseMoved(x, y, x, y);
         select();
      }
   }
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group