X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTApplication.java;h=1b928dd8442dae3e851a64e91bc8bbd8ee115b4f;hb=a043164fd1cc1b38f03bb104f8b5240cdf5705c6;hp=2b8f47e47cbf80b84cdd5bb83ce90c7bdfa2846f;hpb=a4406f4ed7f163b7ab0adce2e710b74d1175b1f3;p=fanfix.git diff --git a/src/jexer/TApplication.java b/src/jexer/TApplication.java index 2b8f47e..1b928dd 100644 --- a/src/jexer/TApplication.java +++ b/src/jexer/TApplication.java @@ -31,6 +31,7 @@ package jexer; import java.io.InputStream; +import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Collections; @@ -174,6 +175,11 @@ public class TApplication implements Runnable { } } + // Wait for drawAll() or doIdle() to be done, then handle the + // events. + boolean oldLock = lockHandleEvent(); + assert (oldLock == false); + // Pull all events off the queue for (;;) { TInputEvent event = null; @@ -183,10 +189,6 @@ public class TApplication implements Runnable { } event = application.drainEventQueue.remove(0); } - // Wait for drawAll() or doIdle() to be done, then handle - // the event. - boolean oldLock = lockHandleEvent(); - assert (oldLock == false); application.repaint = true; if (primary) { primaryHandleEvent(event); @@ -210,14 +212,14 @@ public class TApplication implements Runnable { // All done! return; - } else { - // Unlock. Either I am primary thread, or I am - // secondary thread and still running. - oldLock = unlockHandleEvent(); - assert (oldLock == true); } } // for (;;) + // Unlock. Either I am primary thread, or I am secondary + // thread and still running. + oldLock = unlockHandleEvent(); + assert (oldLock == true); + // I have done some work of some kind. Tell the main run() // loop to wake up now. synchronized (application) { @@ -281,7 +283,14 @@ public class TApplication implements Runnable { synchronized (this) { // Wait for TApplication.run() to finish using the global state // before allowing further event processing. - while (lockoutHandleEvent == true) {} + while (lockoutHandleEvent == true) { + try { + // Backoff so that the backend can finish its work. + Thread.sleep(5); + } catch (InterruptedException e) { + // SQUASH + } + } oldValue = insideHandleEvent; insideHandleEvent = true; @@ -330,7 +339,14 @@ public class TApplication implements Runnable { lockoutHandleEvent = true; // Wait for the last event to finish processing before returning // control to TApplication.run(). - while (insideHandleEvent == true) {} + while (insideHandleEvent == true) { + try { + // Backoff so that the event handler can finish its work. + Thread.sleep(1); + } catch (InterruptedException e) { + // SQUASH + } + } if (debugThreads) { System.err.printf(" XXX\n"); @@ -569,21 +585,19 @@ public class TApplication implements Runnable { /** * Draw everything. */ - public final void drawAll() { + private void drawAll() { if (debugThreads) { System.err.printf("drawAll() enter\n"); } if (!repaint) { - synchronized (getScreen()) { - if ((oldMouseX != mouseX) || (oldMouseY != mouseY)) { - // The only thing that has happened is the mouse moved. - // Clear the old position and draw the new position. - invertCell(oldMouseX, oldMouseY); - invertCell(mouseX, mouseY); - oldMouseX = mouseX; - oldMouseY = mouseY; - } + if ((oldMouseX != mouseX) || (oldMouseY != mouseY)) { + // The only thing that has happened is the mouse moved. + // Clear the old position and draw the new position. + invertCell(oldMouseX, oldMouseY); + invertCell(mouseX, mouseY); + oldMouseX = mouseX; + oldMouseY = mouseY; } if (getScreen().isDirty()) { backend.flushScreen(); @@ -623,7 +637,7 @@ public class TApplication implements Runnable { for (TMenu menu: menus) { CellAttributes menuColor; CellAttributes menuMnemonicColor; - if (menu.getActive()) { + if (menu.isActive()) { menuColor = theme.getColor("tmenu.highlighted"); menuMnemonicColor = theme.getColor("tmenu.mnemonic.highlighted"); } else { @@ -633,12 +647,12 @@ public class TApplication implements Runnable { // Draw the menu title getScreen().hLineXY(x, 0, menu.getTitle().length() + 2, ' ', menuColor); - getScreen().putStrXY(x + 1, 0, menu.getTitle(), menuColor); + getScreen().putStringXY(x + 1, 0, menu.getTitle(), menuColor); // Draw the highlight character getScreen().putCharXY(x + 1 + menu.getMnemonic().getShortcutIdx(), 0, menu.getMnemonic().getShortcut(), menuMnemonicColor); - if (menu.getActive()) { + if (menu.isActive()) { menu.drawChildren(); // Reset the screen clipping so we can draw the next title. getScreen().resetClipping(); @@ -659,7 +673,7 @@ public class TApplication implements Runnable { TWidget activeWidget = null; if (sorted.size() > 0) { activeWidget = sorted.get(sorted.size() - 1).getActiveChild(); - if (activeWidget.visibleCursor()) { + if (activeWidget.isCursorVisible()) { getScreen().putCursor(true, activeWidget.getCursorAbsoluteX(), activeWidget.getCursorAbsoluteY()); cursor = true; @@ -691,24 +705,11 @@ public class TApplication implements Runnable { if (!repaint && ((mouseX == oldMouseX) && (mouseY == oldMouseY)) ) { - // Never sleep longer than 100 millis, to get windows with - // background tasks an opportunity to update the display. - timeout = getSleepTime(100); - - // See if there are any definitely events waiting to be - // processed. If so, do not wait -- either there is I/O - // coming in or the primary/secondary threads are still - // working. - synchronized (drainEventQueue) { - if (drainEventQueue.size() > 0) { - timeout = 0; - } - } - synchronized (fillEventQueue) { - if (fillEventQueue.size() > 0) { - timeout = 0; - } - } + // Never sleep longer than 50 millis. We need time for + // windows with background tasks to update the display, and + // still flip buffers reasonably quickly in + // backend.flushPhysical(). + timeout = getSleepTime(50); } if (timeout > 0) { @@ -727,31 +728,27 @@ public class TApplication implements Runnable { repaint = true; } + // Prevent stepping on the primary or secondary event handler. + stopEventHandlers(); + // Pull any pending I/O events backend.getEvents(fillEventQueue); // Dispatch each event to the appropriate handler, one at a time. for (;;) { TInputEvent event = null; - synchronized (fillEventQueue) { - if (fillEventQueue.size() == 0) { - break; - } - event = fillEventQueue.remove(0); + if (fillEventQueue.size() == 0) { + break; } + event = fillEventQueue.remove(0); metaHandleEvent(event); } // Wake a consumer thread if we have any pending events. - synchronized (drainEventQueue) { - if (drainEventQueue.size() > 0) { - wakeEventHandler(); - } + if (drainEventQueue.size() > 0) { + wakeEventHandler(); } - // Prevent stepping on the primary or secondary event handler. - stopEventHandlers(); - // Process timers and call doIdle()'s doIdle(); @@ -845,9 +842,7 @@ public class TApplication implements Runnable { } // Put into the main queue - synchronized (drainEventQueue) { - drainEventQueue.add(event); - } + drainEventQueue.add(event); } /** @@ -885,11 +880,11 @@ public class TApplication implements Runnable { break; } if ((mouse.getType() == TMouseEvent.Type.MOUSE_MOTION) - && (!mouse.getMouse1()) - && (!mouse.getMouse2()) - && (!mouse.getMouse3()) - && (!mouse.getMouseWheelUp()) - && (!mouse.getMouseWheelDown()) + && (!mouse.isMouse1()) + && (!mouse.isMouse2()) + && (!mouse.isMouse3()) + && (!mouse.isMouseWheelUp()) + && (!mouse.isMouseWheelDown()) ) { break; } @@ -921,7 +916,7 @@ public class TApplication implements Runnable { item = accelerators.get(keypressLowercase); } if (item != null) { - if (item.getEnabled()) { + if (item.isEnabled()) { // Let the menu item dispatch item.dispatch(); return; @@ -947,7 +942,7 @@ public class TApplication implements Runnable { // Dispatch events to the active window ------------------------------- for (TWindow window: windows) { - if (window.getActive()) { + if (window.isActive()) { if (event instanceof TMouseEvent) { TMouseEvent mouse = (TMouseEvent) event; // Convert the mouse relative x/y to window coordinates @@ -985,7 +980,8 @@ public class TApplication implements Runnable { public final void enableSecondaryEventReceiver(final TWidget widget) { assert (secondaryEventReceiver == null); assert (secondaryEventHandler == null); - assert (widget instanceof TMessageBox); + assert ((widget instanceof TMessageBox) + || (widget instanceof TFileOpenBox)); secondaryEventReceiver = widget; secondaryEventHandler = new WidgetEventHandler(this, false); (new Thread(secondaryEventHandler)).start(); @@ -1132,7 +1128,7 @@ public class TApplication implements Runnable { // Swap z/active between active window and the next in the list int activeWindowI = -1; for (int i = 0; i < windows.size(); i++) { - if (windows.get(i).getActive()) { + if (windows.get(i).isActive()) { activeWindowI = i; break; } @@ -1241,7 +1237,7 @@ public class TApplication implements Runnable { // See if they hit the menu bar if ((mouse.getType() == TMouseEvent.Type.MOUSE_DOWN) - && (mouse.getMouse1()) + && (mouse.isMouse1()) && (!modalWindowActive()) && (mouse.getAbsoluteY() == 0) ) { @@ -1268,7 +1264,7 @@ public class TApplication implements Runnable { // See if they hit the menu bar if ((mouse.getType() == TMouseEvent.Type.MOUSE_MOTION) - && (mouse.getMouse1()) + && (mouse.isMouse1()) && (activeMenu != null) && (mouse.getAbsoluteY() == 0) ) { @@ -1322,8 +1318,8 @@ public class TApplication implements Runnable { } // We will be switching to another window - assert (windows.get(0).getActive()); - assert (!window.getActive()); + assert (windows.get(0).isActive()); + assert (!window.isActive()); windows.get(0).setActive(false); windows.get(0).setZ(window.getZ()); window.setZ(0); @@ -1481,9 +1477,9 @@ public class TApplication implements Runnable { // Default: only menu shortcuts // Process Alt-F, Alt-E, etc. menu shortcut keys - if (!keypress.getKey().getIsKey() - && keypress.getKey().getAlt() - && !keypress.getKey().getCtrl() + if (!keypress.getKey().isFnKey() + && keypress.getKey().isAlt() + && !keypress.getKey().isCtrl() && (activeMenu == null) ) { @@ -1491,7 +1487,7 @@ public class TApplication implements Runnable { for (TMenu menu: menus) { if (Character.toLowerCase(menu.getMnemonic().getShortcut()) - == Character.toLowerCase(keypress.getKey().getCh()) + == Character.toLowerCase(keypress.getKey().getChar()) ) { activeMenu = menu; menu.setActive(true); @@ -1826,4 +1822,30 @@ public class TApplication implements Runnable { return new TTerminalWindow(this, x, y, flags); } + /** + * Convenience function to spawn an file open box. + * + * @param path path of selected file + * @return the result of the new file open box + */ + public final String fileOpenBox(final String path) throws IOException { + + TFileOpenBox box = new TFileOpenBox(this, path, TFileOpenBox.Type.OPEN); + return box.getFilename(); + } + + /** + * Convenience function to spawn an file open box. + * + * @param path path of selected file + * @param type one of the Type constants + * @return the result of the new file open box + */ + public final String fileOpenBox(final String path, + final TFileOpenBox.Type type) throws IOException { + + TFileOpenBox box = new TFileOpenBox(this, path, type); + return box.getFilename(); + } + }