#40 twidget API updates
authorKevin Lamonte <kevin.lamonte@gmail.com>
Fri, 2 Aug 2019 10:30:32 +0000 (05:30 -0500)
committerKevin Lamonte <kevin.lamonte@gmail.com>
Fri, 2 Aug 2019 10:30:32 +0000 (05:30 -0500)
src/jexer/TStatusBar.java
src/jexer/TTableWidget.java
src/jexer/TWidget.java
src/jexer/TWindow.java

index 72a0ec6662163740385f887ecd701fcf5ae4c73f..98565d0f8c8c7d50c29ea86218156dbaa991049b 100644 (file)
@@ -125,24 +125,26 @@ public class TStatusBar extends TWidget {
     /**
      * Public constructor.
      *
-     * @param parent parent widget
+     * @param window the window associated with this status bar
      * @param text text for the bar on the bottom row
      */
-    public TStatusBar(final TWidget parent, final String text) {
+    public TStatusBar(final TWindow window, final String text) {
 
-        // Set parent and window
-        super(parent, false, 0, 0, text.length(), 1);
+        // TStatusBar is a parentless widget, because TApplication handles
+        // its drawing and event routing directly.
+        super(null, false, 0, 0, text.length(), 1);
 
         this.text = text;
+        setWindow(window);
     }
 
     /**
      * Public constructor.
      *
-     * @param parent parent widget
+     * @param window the window associated with this status bar
      */
-    public TStatusBar(final TWidget parent) {
-        this(parent, "");
+    public TStatusBar(final TWindow window) {
+        this(window, "");
     }
 
     // ------------------------------------------------------------------------
index d8e01909e03717bc10f60eb56793adb011e2ab27..9b4d7c9847faaa6688dae4a65b63173169683e77 100644 (file)
@@ -1383,7 +1383,7 @@ public class TTableWidget extends TWidget {
     }
 
     /**
-     * Save contents to file in CSV format.
+     * Load contents from file in CSV format.
      *
      * @param csvFile a File referencing the CSV data
      * @throws IOException if a java.io operation throws
index 8a49c816ac1ceb8ab847cadeef41f25b3cc30d9f..9e02613735d210d2d95e00641c766b024c61ad4f 100644 (file)
@@ -180,13 +180,10 @@ public abstract class TWidget implements Comparable<TWidget> {
     protected TWidget(final TWidget parent, final boolean enabled) {
         this.enabled = enabled;
         this.parent = parent;
-        this.window = parent.window;
         children = new ArrayList<TWidget>();
 
-        // Do not add TStatusBars, they are drawn by TApplication.
-        if (this instanceof TStatusBar) {
-            // NOP
-        } else {
+        if (parent != null) {
+            this.window = parent.window;
             parent.addChild(this);
         }
     }
@@ -213,13 +210,10 @@ public abstract class TWidget implements Comparable<TWidget> {
 
         this.enabled = enabled;
         this.parent = parent;
-        this.window = parent.window;
         children = new ArrayList<TWidget>();
 
-        // Do not add TStatusBars, they are drawn by TApplication.
-        if (this instanceof TStatusBar) {
-            // NOP
-        } else {
+        if (parent != null) {
+            this.window = parent.window;
             parent.addChild(this);
         }
 
@@ -306,6 +300,7 @@ public abstract class TWidget implements Comparable<TWidget> {
      * @param keypress keystroke event
      */
     public void onKeypress(final TKeypressEvent keypress) {
+        assert (parent != null);
 
         if ((children.size() == 0)
             || (this instanceof TTreeView)
@@ -700,6 +695,97 @@ public abstract class TWidget implements Comparable<TWidget> {
         return children;
     }
 
+    /**
+     * Remove this widget from its parent container.  close() will be called
+     * before it is removed.
+     */
+    public final void remove() {
+        remove(true);
+    }
+
+    /**
+     * Remove this widget from its parent container.
+     *
+     * @param doClose if true, call the close() method before removing the
+     * child
+     */
+    public final void remove(final boolean doClose) {
+        if (parent != null) {
+            parent.remove(this, doClose);
+        }
+    }
+
+    /**
+     * Remove a child widget from this container.
+     *
+     * @param child the child widget to remove
+     * @param doClose if true, call the close() method before removing the
+     * child
+     */
+    public final void remove(final TWidget child, final boolean doClose) {
+        if (!children.contains(child)) {
+            throw new IndexOutOfBoundsException("child widget is not in " +
+                "list of children of this parent");
+        }
+        if (doClose) {
+            child.close();
+        }
+        children.remove(child);
+        child.parent = null;
+    }
+
+    /**
+     * Set this widget's parent to a different widget.
+     *
+     * @param newParent new parent widget
+     * @param doClose if true, call the close() method before removing the
+     * child from its existing parent widget
+     */
+    public final void setParent(final TWidget newParent,
+        final boolean doClose) {
+
+        if (parent != null) {
+            parent.remove(this, doClose);
+        }
+        assert (parent == null);
+        window = newParent.window;
+        newParent.addChild(this);
+    }
+
+    /**
+     * Set this widget's window to a specific window.  Parent must already be
+     * null.  Having a null parent with a specified window is only used
+     * within Jexer by TStatusBar because TApplication routes events directly
+     * to it and calls its draw() method.  Any other non-parented widgets
+     * will require similar special case functionality to receive events or
+     * be drawn to screen.
+     *
+     * @param window the window to use
+     */
+    public final void setWindow(final TWindow window) {
+
+        if (parent != null) {
+            throw new IllegalArgumentException("Cannot have different " +
+                "windows for parent and child");
+        }
+        this.window = window;
+    }
+
+    /**
+     * Remove a child widget from this container, and all of its children
+     * recursively from their parent containers.
+     *
+     * @param child the child widget to remove
+     * @param doClose if true, call the close() method before removing each
+     * child
+     */
+    public final void removeAll(final TWidget child, final boolean doClose) {
+        remove(child, doClose);
+        for (TWidget w: child.children) {
+            child.removeAll(w, doClose);
+        }
+    }
+
     /**
      * Get active flag.
      *
@@ -896,6 +982,8 @@ public abstract class TWidget implements Comparable<TWidget> {
             return false;
         }
 
+        assert (window != null);
+
         // If cursor is out of my window's bounds, it is not visible.
         if ((getCursorAbsoluteX() >= window.getAbsoluteX()
                 + window.getWidth() - 1)
@@ -1000,7 +1088,7 @@ public abstract class TWidget implements Comparable<TWidget> {
         if (parent == this) {
             return active;
         }
-        return (active && parent.isAbsoluteActive());
+        return (active && (parent == null ? true : parent.isAbsoluteActive()));
     }
 
     /**
@@ -1251,6 +1339,18 @@ public abstract class TWidget implements Comparable<TWidget> {
         }
     }
 
+    /**
+     * Make this widget the active child of its parent.  Note that this is
+     * not final since TWindow overrides activate().
+     */
+    public void activate() {
+        if (enabled) {
+            if (parent != null) {
+                parent.activate(this);
+            }
+        }
+    }
+
     /**
      * Switch the active widget with the next in the tab order.
      *
@@ -1264,6 +1364,8 @@ public abstract class TWidget implements Comparable<TWidget> {
             return;
         }
 
+        assert (parent != null);
+
         // If there is only one child, make it active if it is enabled.
         if (children.size() == 1) {
             if (children.get(0).enabled == true) {
index 3f860d636cac5db22e3454f0661acb3efe5ae4e6..b8513c44298e01819e12d2cf5dbf07a18a1bdd02 100644 (file)
@@ -1186,6 +1186,7 @@ public class TWindow extends TWidget {
     /**
      * Activate window (bring to top and receive events).
      */
+    @Override
     public void activate() {
         application.activateWindow(this);
     }