X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTApplication.java;h=b4c53ec3a5ea8899db40c6dbdda283abe85153f7;hb=499fdccfad144aa58869d839d50edb898670626a;hp=cedb631f77fa40188112ac5caa04e2dd67756733;hpb=85c07c5e6db3a5e74f5ba2bd6e7ee2656d5b63a0;p=fanfix.git diff --git a/src/jexer/TApplication.java b/src/jexer/TApplication.java index cedb631..b4c53ec 100644 --- a/src/jexer/TApplication.java +++ b/src/jexer/TApplication.java @@ -28,12 +28,14 @@ */ package jexer; +import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Reader; import java.io.UnsupportedEncodingException; +import java.text.MessageFormat; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -41,6 +43,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.ResourceBundle; import jexer.bits.CellAttributes; import jexer.bits.ColorTheme; @@ -68,6 +71,11 @@ import static jexer.TKeypress.*; */ public class TApplication implements Runnable { + /** + * Translated strings. + */ + private static final ResourceBundle i18n = ResourceBundle.getBundle(TApplication.class.getName()); + // ------------------------------------------------------------------------ // Public constants ------------------------------------------------------- // ------------------------------------------------------------------------ @@ -537,8 +545,9 @@ public class TApplication implements Runnable { * Display the about dialog. */ protected void showAboutDialog() { - messageBox("About", "Jexer Version " + - this.getClass().getPackage().getImplementationVersion(), + messageBox(i18n.getString("aboutDialogTitle"), + MessageFormat.format(i18n.getString("aboutDialogText"), + this.getClass().getPackage().getImplementationVersion()), TMessageBox.Type.OK); } @@ -732,6 +741,8 @@ public class TApplication implements Runnable { * Draw everything. */ private void drawAll() { + boolean menuIsActive = false; + if (debugThreads) { System.err.printf("%d %s drawAll() enter\n", System.currentTimeMillis(), Thread.currentThread()); @@ -799,6 +810,7 @@ public class TApplication implements Runnable { CellAttributes menuColor; CellAttributes menuMnemonicColor; if (menu.isActive()) { + menuIsActive = true; menuColor = theme.getColor("tmenu.highlighted"); menuMnemonicColor = theme.getColor("tmenu.mnemonic.highlighted"); topLevel = menu; @@ -851,22 +863,24 @@ public class TApplication implements Runnable { oldMouseY = mouseY; // Place the cursor if it is visible - TWidget activeWidget = null; - if (sorted.size() > 0) { - activeWidget = sorted.get(sorted.size() - 1).getActiveChild(); - if (activeWidget.isCursorVisible()) { - if ((activeWidget.getCursorAbsoluteY() < desktopBottom) - && (activeWidget.getCursorAbsoluteY() > desktopTop) - ) { - getScreen().putCursor(true, - activeWidget.getCursorAbsoluteX(), - activeWidget.getCursorAbsoluteY()); - cursor = true; - } else { - getScreen().putCursor(false, - activeWidget.getCursorAbsoluteX(), - activeWidget.getCursorAbsoluteY()); - cursor = false; + if (!menuIsActive) { + TWidget activeWidget = null; + if (sorted.size() > 0) { + activeWidget = sorted.get(sorted.size() - 1).getActiveChild(); + if (activeWidget.isCursorVisible()) { + if ((activeWidget.getCursorAbsoluteY() < desktopBottom) + && (activeWidget.getCursorAbsoluteY() > desktopTop) + ) { + getScreen().putCursor(true, + activeWidget.getCursorAbsoluteX(), + activeWidget.getCursorAbsoluteY()); + cursor = true; + } else { + getScreen().putCursor(false, + activeWidget.getCursorAbsoluteX(), + activeWidget.getCursorAbsoluteY()); + cursor = false; + } } } } @@ -1030,6 +1044,10 @@ public class TApplication implements Runnable { desktop.setDimensions(0, 0, resize.getWidth(), resize.getHeight() - 1); } + + // Change menu edges if needed. + recomputeMenuX(); + // We are dirty, redraw the screen. doRepaint(); return; @@ -1413,9 +1431,15 @@ public class TApplication implements Runnable { if (activeWindow != null) { assert (activeWindow.getZ() == 0); - activeWindow.onUnfocus(); activeWindow.setActive(false); activeWindow.setZ(window.getZ()); + + // Unset activeWindow now before unfocus, so that a window + // lifecycle change inside onUnfocus() doesn't call + // switchWindow() and lead to a stack overflow. + TWindow oldActiveWindow = activeWindow; + activeWindow = null; + oldActiveWindow.onUnfocus(); } activeWindow = window; activeWindow.setZ(0); @@ -1992,8 +2016,8 @@ public class TApplication implements Runnable { // They selected the menu, go activate it for (TMenu menu: menus) { - if ((mouse.getAbsoluteX() >= menu.getX()) - && (mouse.getAbsoluteX() < menu.getX() + if ((mouse.getAbsoluteX() >= menu.getTitleX()) + && (mouse.getAbsoluteX() < menu.getTitleX() + menu.getTitle().length() + 2) ) { menu.setActive(true); @@ -2020,8 +2044,8 @@ public class TApplication implements Runnable { // See if we should switch menus for (TMenu menu: menus) { - if ((mouse.getAbsoluteX() >= menu.getX()) - && (mouse.getAbsoluteX() < menu.getX() + if ((mouse.getAbsoluteX() >= menu.getTitleX()) + && (mouse.getAbsoluteX() < menu.getTitleX() + menu.getTitle().length() + 2) ) { menu.setActive(true); @@ -2282,7 +2306,14 @@ public class TApplication implements Runnable { int x = 0; for (TMenu menu: menus) { menu.setX(x); + menu.setTitleX(x); x += menu.getTitle().length() + 2; + + // Don't let the menu window exceed the screen width + int rightEdge = menu.getX() + menu.getWidth(); + if (rightEdge > getScreen().getWidth()) { + menu.setX(getScreen().getWidth() - menu.getWidth()); + } } } @@ -2335,14 +2366,14 @@ public class TApplication implements Runnable { * @return the new menu */ public final TMenu addFileMenu() { - TMenu fileMenu = addMenu("&File"); + TMenu fileMenu = addMenu(i18n.getString("fileMenuTitle")); fileMenu.addDefaultItem(TMenu.MID_OPEN_FILE); fileMenu.addSeparator(); fileMenu.addDefaultItem(TMenu.MID_SHELL); fileMenu.addDefaultItem(TMenu.MID_EXIT); - TStatusBar statusBar = fileMenu.newStatusBar("File-management " + - "commands (Open, Save, Print, etc.)"); - statusBar.addShortcutKeypress(kbF1, cmHelp, "Help"); + TStatusBar statusBar = fileMenu.newStatusBar(i18n. + getString("fileMenuStatus")); + statusBar.addShortcutKeypress(kbF1, cmHelp, i18n.getString("Help")); return fileMenu; } @@ -2352,14 +2383,14 @@ public class TApplication implements Runnable { * @return the new menu */ public final TMenu addEditMenu() { - TMenu editMenu = addMenu("&Edit"); + TMenu editMenu = addMenu(i18n.getString("editMenuTitle")); editMenu.addDefaultItem(TMenu.MID_CUT); editMenu.addDefaultItem(TMenu.MID_COPY); editMenu.addDefaultItem(TMenu.MID_PASTE); editMenu.addDefaultItem(TMenu.MID_CLEAR); - TStatusBar statusBar = editMenu.newStatusBar("Editor operations, " + - "undo, and Clipboard access"); - statusBar.addShortcutKeypress(kbF1, cmHelp, "Help"); + TStatusBar statusBar = editMenu.newStatusBar(i18n. + getString("editMenuStatus")); + statusBar.addShortcutKeypress(kbF1, cmHelp, i18n.getString("Help")); return editMenu; } @@ -2369,7 +2400,7 @@ public class TApplication implements Runnable { * @return the new menu */ public final TMenu addWindowMenu() { - TMenu windowMenu = addMenu("&Window"); + TMenu windowMenu = addMenu(i18n.getString("windowMenuTitle")); windowMenu.addDefaultItem(TMenu.MID_TILE); windowMenu.addDefaultItem(TMenu.MID_CASCADE); windowMenu.addDefaultItem(TMenu.MID_CLOSE_ALL); @@ -2379,9 +2410,9 @@ public class TApplication implements Runnable { windowMenu.addDefaultItem(TMenu.MID_WINDOW_NEXT); windowMenu.addDefaultItem(TMenu.MID_WINDOW_PREVIOUS); windowMenu.addDefaultItem(TMenu.MID_WINDOW_CLOSE); - TStatusBar statusBar = windowMenu.newStatusBar("Open, arrange, and " + - "list windows"); - statusBar.addShortcutKeypress(kbF1, cmHelp, "Help"); + TStatusBar statusBar = windowMenu.newStatusBar(i18n. + getString("windowMenuStatus")); + statusBar.addShortcutKeypress(kbF1, cmHelp, i18n.getString("Help")); return windowMenu; } @@ -2391,7 +2422,7 @@ public class TApplication implements Runnable { * @return the new menu */ public final TMenu addHelpMenu() { - TMenu helpMenu = addMenu("&Help"); + TMenu helpMenu = addMenu(i18n.getString("helpMenuTitle")); helpMenu.addDefaultItem(TMenu.MID_HELP_CONTENTS); helpMenu.addDefaultItem(TMenu.MID_HELP_INDEX); helpMenu.addDefaultItem(TMenu.MID_HELP_SEARCH); @@ -2400,8 +2431,9 @@ public class TApplication implements Runnable { helpMenu.addDefaultItem(TMenu.MID_HELP_ACTIVE_FILE); helpMenu.addSeparator(); helpMenu.addDefaultItem(TMenu.MID_ABOUT); - TStatusBar statusBar = helpMenu.newStatusBar("Access online help"); - statusBar.addShortcutKeypress(kbF1, cmHelp, "Help"); + TStatusBar statusBar = helpMenu.newStatusBar(i18n. + getString("helpMenuStatus")); + statusBar.addShortcutKeypress(kbF1, cmHelp, i18n.getString("Help")); return helpMenu; } @@ -2419,7 +2451,8 @@ public class TApplication implements Runnable { protected boolean onCommand(final TCommandEvent command) { // Default: handle cmExit if (command.equals(cmExit)) { - if (messageBox("Confirmation", "Exit application?", + if (messageBox(i18n.getString("exitDialogTitle"), + i18n.getString("exitDialogText"), TMessageBox.Type.YESNO).getResult() == TMessageBox.Result.YES) { exit(); } @@ -2468,7 +2501,8 @@ public class TApplication implements Runnable { // Default: handle MID_EXIT if (menu.getId() == TMenu.MID_EXIT) { - if (messageBox("Confirmation", "Exit application?", + if (messageBox(i18n.getString("exitDialogTitle"), + i18n.getString("exitDialogText"), TMessageBox.Type.YESNO).getResult() == TMessageBox.Result.YES) { exit(); } @@ -2496,6 +2530,10 @@ public class TApplication implements Runnable { showAboutDialog(); return true; } + if (menu.getId() == TMenu.MID_REPAINT) { + doRepaint(); + return true; + } return false; } @@ -2724,6 +2762,7 @@ public class TApplication implements Runnable { TWindow window = new TWindow(this, title, 0, 0, width, height); return window; } + /** * Convenience function to create a new window and make it active. * Window will be located at (0, 0). @@ -2774,4 +2813,17 @@ public class TApplication implements Runnable { return window; } + /** + * Convenience function to open a file in an editor window and make it + * active. + * + * @param file the file to open + * @throws IOException if a java.io operation throws + */ + public final TEditorWindow addEditor(final File file) throws IOException { + + TEditorWindow editor = new TEditorWindow(this, file); + return editor; + } + }