X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=PuzzleApplet.java;h=8455734dd128e734bbb4e16dd81cb6f077a8329e;hb=db313b3948d27244dd7c34c2609c66d6204d8931;hp=ef7ca7e507ae52d5a08daa8ab3dcfba5bfe135ab;hpb=82b6a6fd39fc49ab511b3b4d748b415eb6af704a;p=sgt-puzzles.git diff --git a/PuzzleApplet.java b/PuzzleApplet.java index ef7ca7e..8455734 100644 --- a/PuzzleApplet.java +++ b/PuzzleApplet.java @@ -28,11 +28,15 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { private JFrame mainWindow; private JMenu typeMenu; + private JMenuItem[] typeMenuItems; + private int customMenuItemIndex; + private JMenuItem solveCommand; private Color[] colors; private JLabel statusBar; private PuzzlePanel pp; private Runtime runtime; + private String[] puzzle_args; private Graphics2D gg; private Timer timer; private int xarg1, xarg2, xarg3; @@ -57,19 +61,19 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { JMenuBar menubar = new JMenuBar(); JMenu jm; menubar.add(jm = new JMenu("Game")); - addMenuItemWithKey(jm, "New", 'n'); + addMenuItemCallback(jm, "New", "jcallback_newgame_event"); addMenuItemCallback(jm, "Restart", "jcallback_restart_event"); addMenuItemCallback(jm, "Specific...", "jcallback_config_event", CFG_DESC); addMenuItemCallback(jm, "Random Seed...", "jcallback_config_event", CFG_SEED); jm.addSeparator(); - addMenuItemWithKey(jm, "Undo", 'u'); - addMenuItemWithKey(jm, "Redo", 'r'); + addMenuItemCallback(jm, "Undo", "jcallback_undo_event"); + addMenuItemCallback(jm, "Redo", "jcallback_redo_event"); jm.addSeparator(); solveCommand = addMenuItemCallback(jm, "Solve", "jcallback_solve_event"); solveCommand.setEnabled(false); if (mainWindow != null) { jm.addSeparator(); - addMenuItemWithKey(jm, "Exit", 'q'); + addMenuItemCallback(jm, "Exit", "jcallback_quit_event"); } menubar.add(typeMenu = new JMenu("Type")); typeMenu.setVisible(false); @@ -122,7 +126,12 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { } } public void keyTyped(KeyEvent e) { - runtimeCall("jcallback_key_event", new int[] {0, 0, e.getKeyChar()}); + int key = e.getKeyChar(); + if (key == 26 && e.isShiftDown() && e.isControlDown()) { + runtimeCall("jcallback_redo_event", new int[0]); + return; + } + runtimeCall("jcallback_key_event", new int[] {0, 0, key}); } }); pp.addMouseListener(new MouseAdapter() { @@ -172,9 +181,22 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { runtimeCall("jcallback_timer_func", new int[0]); } }); + String gameid; + try { + gameid = getParameter("game_id"); + } catch (java.lang.NullPointerException ex) { + gameid = null; + } + if (gameid == null) { + puzzle_args = null; + } else { + puzzle_args = new String[2]; + puzzle_args[0] = "puzzle"; + puzzle_args[1] = gameid; + } SwingUtilities.invokeLater(new Runnable() { public void run() { - runtime.start(); + runtime.start(puzzle_args); runtime.execute(); } }); @@ -200,22 +222,18 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { runtimeCall("jcallback_resize", new int[] {pp.getWidth(), pp.getHeight()}); } - private void addMenuItemWithKey(JMenu jm, String name, int key) { - addMenuItemCallback(jm, name, "jcallback_menu_key_event", key); - } - private JMenuItem addMenuItemCallback(JMenu jm, String name, final String callback, final int arg) { - return addMenuItemCallback(jm, name, callback, new int[] {arg}); + return addMenuItemCallback(jm, name, callback, new int[] {arg}, false); } private JMenuItem addMenuItemCallback(JMenu jm, String name, final String callback) { - return addMenuItemCallback(jm, name, callback, new int[0]); + return addMenuItemCallback(jm, name, callback, new int[0], false); } - private JMenuItem addMenuItemCallback(JMenu jm, String name, final String callback, final int[] args) { + private JMenuItem addMenuItemCallback(JMenu jm, String name, final String callback, final int[] args, boolean checkbox) { JMenuItem jmi; - if (jm == typeMenu) - typeMenu.add(jmi = new JCheckBoxMenuItem(name)); + if (checkbox) + jm.add(jmi = new JCheckBoxMenuItem(name)); else jm.add(jmi = new JMenuItem(name)); jmi.addActionListener(new ActionListener() { @@ -247,12 +265,29 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { } else { typeMenu.setVisible(true); } - addMenuItemCallback(typeMenu, "Custom...", "jcallback_config_event", CFG_SETTINGS); + typeMenuItems[customMenuItemIndex] = + addMenuItemCallback(typeMenu, "Custom...", + "jcallback_config_event", + new int[] {CFG_SETTINGS}, true); } - private void addTypeItem(String name, final int ptrGameParams) { + private void addTypeItem + (JMenu targetMenu, String name, int newId, final int ptrGameParams) { + typeMenu.setVisible(true); - addMenuItemCallback(typeMenu, name, "jcallback_preset_event", ptrGameParams); + typeMenuItems[newId] = + addMenuItemCallback(targetMenu, name, + "jcallback_preset_event", + new int[] {ptrGameParams}, true); + } + + private void addTypeSubmenu + (JMenu targetMenu, String name, int newId) { + + JMenu newMenu = new JMenu(name); + newMenu.setVisible(true); + typeMenuItems[newId] = newMenu; + targetMenu.add(newMenu); } public int call(int cmd, int arg1, int arg2, int arg3) { @@ -265,8 +300,20 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { if ((arg2 & 4) != 0) solveCommand.setEnabled(true); colors = new Color[arg3]; return 0; - case 1: // Type menu item - addTypeItem(runtime.cstring(arg1), arg2); + case 1: // configure Type menu + if (arg1 == 0) { + // preliminary setup + typeMenuItems = new JMenuItem[arg2 + 2]; + typeMenuItems[arg2] = typeMenu; + customMenuItemIndex = arg2 + 1; + return arg2; + } else if (xarg1 != 0) { + addTypeItem((JMenu)typeMenuItems[arg2], + runtime.cstring(arg1), arg3, xarg1); + } else { + addTypeSubmenu((JMenu)typeMenuItems[arg2], + runtime.cstring(arg1), arg3); + } return 0; case 2: // MessageBox JOptionPane.showMessageDialog(this, runtime.cstring(arg2), runtime.cstring(arg1), arg3 == 0 ? JOptionPane.INFORMATION_MESSAGE : JOptionPane.ERROR_MESSAGE); @@ -282,24 +329,29 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { case 0: String text = runtime.cstring(arg2); if (text.equals("")) text = " "; - System.out.println("status '" + text + "'"); - statusBar.setText(text); break; + statusBar.setText(text); + break; case 1: gg = pp.backBuffer.createGraphics(); - if (arg2 != 0 || arg3 != 0) { - gg.setColor(Color.black); - gg.fillRect(0, 0, arg2, getHeight()); - gg.fillRect(0, 0, getWidth(), arg3); - gg.fillRect(getWidth() - arg2, 0, arg2, getHeight()); - gg.fillRect(0, getHeight() - arg3, getWidth(), arg3); - gg.setClip(arg2, arg3, getWidth()-2*arg2, getHeight()-2*arg3); + if (arg2 != 0 || arg3 != 0 || + arg2 + xarg2 != getWidth() || + arg3 + xarg3 != getHeight()) { + int left = arg2, right = arg2 + xarg2; + int top = arg3, bottom = arg3 + xarg3; + int width = getWidth(), height = getHeight(); + gg.setColor(colors != null ? colors[0] : Color.black); + gg.fillRect(0, 0, left, height); + gg.fillRect(right, 0, width-right, height); + gg.fillRect(0, 0, width, top); + gg.fillRect(0, bottom, width, height-bottom); + gg.setClip(left, top, right-left, bottom-top); } break; case 2: gg.dispose(); pp.repaint(); break; case 3: gg.setClip(arg2, arg3, xarg1, xarg2); break; case 4: if (arg2 == 0 && arg3 == 0) { - gg.fillRect(0, 0, getWidth(), getHeight()); + gg.setClip(0, 0, getWidth(), getHeight()); } else { gg.setClip(arg2, arg3, getWidth()-2*arg2, getHeight()-2*arg3); } @@ -359,7 +411,7 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { case 7: // string gg.setColor(colors[arg2]); { - String text = runtime.cstring(arg3); + String text = runtime.utfstring(arg3); Font ft = new Font((xarg3 & 0x10) != 0 ? "Monospaced" : "Dialog", Font.PLAIN, 100); int height100 = this.getFontMetrics(ft).getHeight(); @@ -368,8 +420,6 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { int asc = fm.getAscent(), desc = fm.getDescent(); if ((xarg3 & ALIGN_VCENTRE) != 0) xarg2 += asc - (asc+desc)/2; - else - xarg2 += asc; int wid = fm.stringWidth(text); if ((xarg3 & ALIGN_HCENTRE) != 0) xarg1 -= wid / 2; @@ -415,10 +465,11 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { dlg = null; return 0; case 13: // tick a menu item - if (arg1 < 0) arg1 = typeMenu.getItemCount() - 1; - for (int i = 0; i < typeMenu.getItemCount(); i++) { - if (typeMenu.getMenuComponent(i) instanceof JCheckBoxMenuItem) { - ((JCheckBoxMenuItem)typeMenu.getMenuComponent(i)).setSelected(arg1 == i); + if (arg1 < 0) arg1 = customMenuItemIndex; + for (int i = 0; i < typeMenuItems.length; i++) { + if (typeMenuItems[i] instanceof JCheckBoxMenuItem) { + ((JCheckBoxMenuItem)typeMenuItems[i]).setSelected + (arg1 == i); } } return 0; @@ -590,7 +641,7 @@ public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { break; case C_CHOICES: JComboBox jcm = (JComboBox)cc.component; - runtimeCall("jcallback_config_set_boolean", new int[] {cc.configItemPointer, jcm.getSelectedIndex()}); + runtimeCall("jcallback_config_set_choice", new int[] {cc.configItemPointer, jcm.getSelectedIndex()}); break; } }