/* Copyright: Sun Microsystems 1997. All rights reserved. Author: Patrick Chan (www.xeo.com) 7/19/96 Version: 1.1 */ import java.applet.*; import java.awt.*; import java.util.*; import java.net.*; public class XeoMenu extends Canvas { Applet app; // The background image. This had better not be null. Image image; // These two fields are used to do double-buffering. // The dimensions of bbuf is exactly the dimensions of the applet. Image bbuf; Graphics bbufG; // This field is set to true only when the background image has // completely loaded. boolean imageDone; /* Menu data */ Rectangle[] hitArea; Rectangle[] srcRect; Point[] dstPt; boolean[] down; String[] url; /* Submenu data */ String[][] itemUrl; String[][] item; // If >= 0, this fields holds the index of the current menu. // If -1, no menu is current. int curMenu; // If >= 0, this fields holds the index of the current menu item. // If -1, no menu item is current. int curMenuItem; // This is an array of rectangles - one rectangle for each menu item. // Each rectangle specifies the // location (relative to the left-corner of the applet) of a menu item. // // menuItemRect is null when curMenu is -1. // It becomes non-null when curMenu >= 0. // // Note: it would have been better programming to define classes for // the menu and menu items. However, I decided for this little applet // to keep the number of class files to a minimum to minimize the download // time. Rectangle[] menuItemRect; // This is the color to paint "behind" the image. Color bgColor; // [0] is the text color of a menu item; [1] is the text color of a highlighted // menu item. Color fgMenuColor[] = new Color[2]; // This is the background of a menu item; [1] is the background color of a // highlighted menu item. Color bgMenuColor[] = new Color[2]; // marginH is the number of pixels on the left and right edges of the menu. // marginV is the number of pixels on the top and bottom edges of the menu. int marginH, marginV; // This is the font used to display the menu item labels. Font f; // This is the font metrics of 'f'. FontMetrics fm; public XeoMenu(Applet a) { resize(396,36); app = a; } public void initialize() { int[] ints; // Grab applet parameters. image = app.getImage(app.getCodeBase(), app.getParameter("image")); System.out.println("image"); marginH = Integer.parseInt(app.getParameter("marginh")); marginV = Integer.parseInt(app.getParameter("marginv")); // Get color parameters. ints = parseInt(app.getParameter("bg-color"), " "); bgColor = new Color(ints[0], ints[1], ints[2]); ints = parseInt(app.getParameter("fg-menu-color"), " "); fgMenuColor[0] = new Color(ints[0], ints[1], ints[2]); ints = parseInt(app.getParameter("fg-hi-menu-color"), " "); fgMenuColor[1] = new Color(ints[0], ints[1], ints[2]); ints = parseInt(app.getParameter("bg-menu-color"), " "); bgMenuColor[0] = new Color(ints[0], ints[1], ints[2]); ints = parseInt(app.getParameter("bg-hi-menu-color"), " "); bgMenuColor[1] = new Color(ints[0], ints[1], ints[2]); // Create back buffer for double-buffering. bbuf = createImage(size().width, size().height); bbufG = bbuf.getGraphics(); // Determine the font from the font-height. int fh = Integer.parseInt(app.getParameter("font-height")); int i = fh; while (i > 10) { f = new Font(app.getParameter("font"), Font.PLAIN, i); fm = getFontMetrics(f); if (fm.getHeight() <= fh) { break; } i--; } // Get the menu parameters. for (i=0; ; i++) { if (app.getParameter("menu"+i) == null) { hitArea = new Rectangle[i]; srcRect = new Rectangle[i]; dstPt = new Point[i]; url = new String[i]; down = new boolean[i]; itemUrl = new String[i][]; item = new String[i][]; break; } } for (i=0; i= 0) { g2 = bbuf.getGraphics(); // Paint the overlay image g2.clipRect(dstPt[curMenu].x, dstPt[curMenu].y, srcRect[curMenu].width, srcRect[curMenu].height); g2.drawImage(image, dstPt[curMenu].x-srcRect[curMenu].x, dstPt[curMenu].y-srcRect[curMenu].y, this); g2.dispose(); g2 = bbuf.getGraphics(); for (int i=0; i= 0 && itemUrl[curMenu].length > 0) { u = itemUrl[curMenu][curMenuItem]; } else if (curMenu >= 0) { u = url[curMenu]; } if (u != null) { URL url = new URL (app.getDocumentBase(), u); if (app.getParameter("target") != null) { app.getAppletContext().showDocument(url, app.getParameter("target")); } else { app.getAppletContext().showDocument(url); } } } catch (Exception e) { e.printStackTrace(); } return true; } public boolean mouseMove(Event evt, int x, int y) { if (curMenu >= 0) { int sm = inMenu(menuItemRect, x, y); if (curMenuItem != sm) { curMenuItem = sm; repaint(); } if (sm >= 0) { return true; } curMenu = -1; } int m = inMenu(hitArea, x, y); if (m != curMenu) { curMenu = m; // A new menu is now active so compute menuItemRect. if (m >= 0) { // Minimum width int maxWidth = 50; int maxHeight = 0; menuItemRect = new Rectangle[item[curMenu].length]; for (int i=0; i maxWidth) { maxWidth = w; } } menuItemRect[i] = new Rectangle(); menuItemRect[i].height = parse(item[curMenu][i], app.getParameter("newline")).length * fm.getHeight() + 2 * marginV; maxHeight += menuItemRect[i].height; } // Add one extra pixel for the left edge. maxWidth += 2 * marginH + 1; if (down[m]) { y = Math.max(0, Math.min(size().height-maxHeight-1, dstPt[curMenu].y + srcRect[curMenu].height-1)); } else { y = Math.max(0, Math.min(size().height-maxHeight-1, dstPt[curMenu].y - maxHeight)); } x = dstPt[curMenu].x + srcRect[curMenu].width-maxWidth-1; for (int i=0; i