!7 sbool showHelpOnStart; static JFrame mainFrame; static LL gridComponents; static JComponent mainGrid; static JCheckBoxMenuItem miShowLocations; static Color lightBlue = colorFromHex("4169e1"); sS locationLetters = charRange('A', 'Z') + "[\\]^_`" + charRange('a', 'z') + charRange(123, 128); sS smartyUnicode = basicUnicodeSmiley(); static int smartyFontSize = 40; sS windowsFontID = #1400468; svoid rearrangeLetters { int iLetter = 0; for (int y = 0; y < state.gridRows; y++) for (int x = 0; x < state.gridCols; x++) { JCell cell = getCell(x, y); if (cell.obstacle()) cell.letter = ' '; else cell.letter = locationLetters.charAt(iLetter++); } } concept State { int gridRows = 8, gridCols = 8; bool showLocations = true; int smartyX, smartyY; Rect selection = rect(1, 1, 1, 1); Pt cursorDirection = pt(1, 0); new BitSet obstacles; void setSelection(Rect r) { if (!cset_trueIfChanged(this, selection := r)) ret; if (selection.h == 1 && selection.w > 1) _setField(cursorDirection := pt(1, 0)); else if (selection.w == 1 && selection.h > 1) _setField(cursorDirection := pt(0, 1)); repaint(mainGrid); } void invertSelection { JCell cell1 = getCell(selection.x, selection.y); bool set = !cell1.obstacle(); for (Pt p : pointsInRect(selection)) getCell(p.x, p.y).setObstacle(set); rearrangeLetters(); moveCursor(); } void moveCursor { setCursor(selection.x+cursorDirection.x, selection.y+cursorDirection.y); } void setCursor(int x, int y) { setSelection(rect(mod(x, gridCols), mod(y, gridRows), 1, 1)); } void moveCursor(int dx, int dy) { _setField(cursorDirection := pt(dx, dy)); setCursor(selection.x+cursorDirection.x, selection.y+cursorDirection.y); } void placeSmarty { getCell(selection.x, selection.y).setObstacle(false); cset(this, smartyX := selection.x, smartyY := selection.y); moveCursor(); } } static State state; sclass JCell > JComponent { int x, y; char letter; *(int *x, int *y) {} public void paint(Graphics _g) { Graphics2D g = cast _g; int w = getWidth(), h = getHeight(); Color color = Color.white; if (state.selection.contains(x, y)) color = lightBlue; else if (obstacle()) color = Color.black; fillRect(g, 0, 0, w, h, color); if (state.showLocations && !obstacle()) { temp tempSetFont(g, loadFont_cached(windowsFontID)); drawTextWithTopLeftCornerAt(g, str(letter), Pt(2, 0), Color.black); } if (state.smartyX == x && state.smartyY == y) { temp tempSetFontSize(g, smartyFontSize); drawCenteredText(g, smartyUnicode, 0, 0, w, h, Color.black); } } int index() { ret y*state.gridCols+x; } bool obstacle() { ret main contains(state.obstacles, index()); } void setObstacle(bool b) { setBit(state.obstacles, index(), b); state.change(); } { addMouseListener(new MouseAdapter { public void mousePressed(MouseEvent e) { if (!isLeftButton(e)) ret; state.setSelection(new Rect(x, y, 1, 1)); } }); addMouseMotionListener(new MouseMotionAdapter { public void mouseDragged(MouseEvent e) { _print("Drag in " + x + "/" + y + ": " + e.getPoint()); Component dest = componentAtScreenLocationInWindow(mainFrame, e); if (dest cast JCell) { _print("Target: " + dest); state.setSelection(rectFromPointsInclusiveSorted(x, y, dest.x, dest.y)); } } }); } toString { ret x + "/" + y; } } static JCell getCell(int x, int y) { ret gridComponents.get(y).get(x); } p { autoRestart(5.0); db(); state = uniq(State); loadLibrary(windowsFontID); mainFrame = showFrame("Smarty"); addMenu(mainFrame, "Worlds", "New... (Ctrl+N)", r {}, "Retrieve... (Ctrl+R)", r {}, "Save... (Ctrl+S)", r {}, "---", "Exit", rThread killVM); registerCtrlKey(mainFrame, KeyEvent.VK_N, "New world", r { print("new") }); registerCtrlKey(mainFrame, KeyEvent.VK_R, "Retrieve world", r {}); registerCtrlKey(mainFrame, KeyEvent.VK_S, "Save world", r {}); addMenu(mainFrame, "View", miShowLocations = jCheckBoxMenuItem("Locations (Ctrl+L)", state.showLocations, b -> { cset(state, showLocations := b); repaint(mainGrid); })); registerCtrlKey(mainFrame, KeyEvent.VK_L, "Locations", r { cset(state, showLocations := !state.showLocations); setChecked(miShowLocations, state.showLocations); repaint(mainGrid); }); JMenuBar menuBar = getMenuBar(mainFrame); JMenuItem helpItem = jMenuItem("Help F1", rThread showHelp); /*print(minSize := getMinimumSize(helpItem)); print(preferredSize := getPreferredSize(helpItem));*/ addMenuItem(menuBar, jPreferredWidthToMaxWidth(helpItem)); addAndRevalidate(menuBar, jHorizontalGlue()); // spacer registerFunctionKey(mainFrame, 1, rThread showHelp); gridComponents = map(iotaZeroList(state.gridRows), y -> map(iotaZeroList(state.gridCols), x -> new JCell(x, y))); //gridComponents = repF_2d(8, 8, lambda0 newSingleComponentPanel); //second(second(gridComponents)).obstacle = true; //first(first(gridComponents)).setComponent(fontSize(50, jcenteredlabel(basicUnicodeSmiley()))); rearrangeLetters(); registerKeyCode(mainFrame, KeyEvent.VK_SPACE, r { state.invertSelection() }); registerKeyCode(mainFrame, KeyEvent.VK_UP, r { state.moveCursor(0, -1) }); registerKeyCode(mainFrame, KeyEvent.VK_LEFT, r { state.moveCursor(-1, 0) }); registerKeyCode(mainFrame, KeyEvent.VK_DOWN, r { state.moveCursor(0, 1) }); registerKeyCode(mainFrame, KeyEvent.VK_RIGHT, r { state.moveCursor(1, 0) }); for (int key = KeyEvent.VK_A; key <= KeyEvent.VK_Z; key++) registerKeyCode(mainFrame, key, r { state.placeSmarty() }); JComponent middleArea = westAndCenterWithMargin( jvstackWithSpacing( withTitle("World size (max=8)", jSpinner(gridCols, 1, 8)), jbutton("Clear Selected Area"), withTitle("Current world", jdisabledtextfield("empty")), fontSizePlus(2, setForeground(Color.ORANGE, jCenteredLabel("Design or Select a body for Smarty"))), jbutton("Design or Select Smarty's Body"), ), vgrid( withTitle("Sensors Values are", jTextArea()), withTitle("Devices Values are", jTextArea()) ) ); JComponent controlArea = northCenterAndSouthWithMargin( fontSizePlus(2, setForeground(Color.blue, jlabel("Design the World - Read the Help F1"))), middleArea, jCenteredSection("Run Smarty", jflow( jbutton("Go / Continue"), jbutton("See History"), jbutton("Reset"), jbutton("EXIT", rThread killVM), jbutton("See Memory"))) ); mainGrid = setBackground(Color.black, hvgrid(gridComponents, 1)); setFrameContents(mainFrame, westAndCenterWithMargins( jvstack(jFixedSize(500, mainGrid)), controlArea)); centerPackFrame(mainFrame); if (showHelpOnStart) showHelp(); //hideConsole(); } svoid showHelp() { S text = loadSnippet(#1031105); S heading = firstLine(text); trim(dropFirstLine(text)); showFrame(heading, fontSizePlus(4, makeUneditableWithTextColor(Color.black, wordWrapTextArea(text)))); }