#include #include "InputMenuBar.h" extern void bringRectangleInteriorOntoScreen(int *x, int *y, int width, int height); bool InputMenuBar::getBarMenuIsUp() { return barMenuIsUp; } void InputMenuBar::decide() { killBarMenu(); erase(); draw(); barMenuFunction[content.getValue()][barMenu.getValue()](); if (blocking) commit(true); } void InputMenuBar::bringUpMenu(int index) { content.setValue(index); spawnBarMenu(); } InputMenu InputMenuBar::spawnBarMenu() { showContentSelection = true; barMenuIsUp = true; barMenuX = content.getX()[content.getValue()]; barMenuY = above ? content.getY()[content.getValue()] - barMenuLength[content.getValue()] * charHeight - 1 : content.getY()[content.getValue()] + charHeight + 1; bringRectangleInteriorOntoScreen(&barMenuX, &barMenuY, barMenuCommandCharCount[content.getValue()] * charWidth, barMenuLength[content.getValue()] * charHeight); return barMenu = InputMenu(canvas, barMenuX, barMenuY, barMenuLength[content.getValue()], barMenuCommand[content.getValue()], barMenuAcceleratorKey[content.getValue()], true, true); } void InputMenuBar::killBarMenu() { showContentSelection = false; barMenuIsUp = false; } bool InputMenuBar::getValue() { return false; } bool InputMenuBar::acknowledgeKeyStroke(int keyStroke) { const int scanCode = keyStroke >> 8; const int accelerated = barMenu.accelerate(scancode_to_ascii(scanCode)); switch (scanCode) { case KEY_2_PAD: case KEY_DOWN: barMenu.next(); return true; case KEY_4_PAD: case KEY_LEFT: content.previous(); spawnBarMenu(); return true; case KEY_6_PAD: case KEY_RIGHT: content.next(); spawnBarMenu(); return true; case KEY_8_PAD: case KEY_UP: barMenu.previous(); return true; case KEY_ESC: killBarMenu(); if (blocking) commit(false); return true; case KEY_ENTER: case KEY_ENTER_PAD: decide(); return true; default: if (accelerated != -1) { barMenu.setValue(accelerated); decide(); return true; } } return false; } bool InputMenuBar::acknowledgeMouse() { const int mousePosition = mouse_pos; const int mouseButtons = mouse_b; bool somethingHappened = false; bool decided = false; if (barMenuIsUp) { if (barMenu.acknowledgeMouse()) somethingHappened = true; if (barMenu.getCommitted()) { decide(); decided = true; somethingHappened = true; } else if (((mouseButtons & 0x1) && !(oldMouseB & 0x1) || (mouseButtons & 0x2) && !(oldMouseB & 0x2)) && !within(mousePosition >> 16, mousePosition & 0xffff)) { killBarMenu(); if (blocking) commit(false); somethingHappened = true; } } const int oldContentSelection = content.getValue(); if (content.acknowledgeMouse()) somethingHappened = true; if (content.getCommitted() || barMenuIsUp && content.getValue() != oldContentSelection) { if (!decided) spawnBarMenu(); content.uncommit(); somethingHappened = true; } const bool oldShowContentSelection = showContentSelection; showContentSelection = barMenuIsUp || content.within(mousePosition >> 16, mousePosition & 0xffff); if (showContentSelection != oldShowContentSelection) somethingHappened = true; oldMouseB = mouseButtons; return somethingHappened; } void InputMenuBar::shift(int xOffset, int yOffset) { content.shift(xOffset, yOffset); barMenuX += xOffset; barMenuY += yOffset; barMenu.shift(xOffset, yOffset); } bool InputMenuBar::within(int xTarget, int yTarget) { return content.within(xTarget, yTarget) || barMenuIsUp && xTarget >= barMenuX - 1 && xTarget <= barMenuX + barMenuCommandCharCount[content.getValue()] * charWidth && yTarget >= barMenuY - 1 && yTarget <= barMenuY + barMenuLength[content.getValue()] * charHeight; } void InputMenuBar::draw() { content.drawCommands(); if (showContentSelection) content.drawSelect(); if (barMenuIsUp) { rect(canvas, barMenuX - 1, barMenuY - 1, barMenuX + barMenuCommandCharCount[content.getValue()] * charWidth, barMenuY + barMenuLength[content.getValue()] * charHeight, 15); barMenu.draw(); } } void InputMenuBar::erase() { content.erase(); clear_bitmap(canvas); }