checkbox working
authorKevin Lamonte <kevin.lamonte@gmail.com>
Sat, 14 Mar 2015 21:52:39 +0000 (17:52 -0400)
committerKevin Lamonte <kevin.lamonte@gmail.com>
Sat, 14 Mar 2015 21:52:39 +0000 (17:52 -0400)
README.md
demos/Demo1.java
src/jexer/TCheckbox.java [new file with mode: 0644]
src/jexer/TWidget.java

index 2e9ef73bec5b45ab70e55807bffb0b93f1b76933..11e09c34f4abc63564e2b4fb21e413f495769b10 100644 (file)
--- a/README.md
+++ b/README.md
@@ -58,7 +58,6 @@ Many tasks remain before calling this version 1.0:
 
 0.0.1:
 
 
 0.0.1:
 
-- TCheckbox
 - TDirectoryList
 - TField
 - TMessageBox
 - TDirectoryList
 - TField
 - TMessageBox
index 5d5485a83fe4fb529bc751bcecb23cb30d2cb777..44333a42b4be7f3a30f93f38c995bf31f5a395c1 100644 (file)
 import jexer.*;
 import jexer.menu.*;
 
 import jexer.*;
 import jexer.menu.*;
 
+class DemoCheckboxWindow extends TWindow {
+
+    /**
+     * Constructor
+     */
+    DemoCheckboxWindow(TApplication parent) {
+        this(parent, CENTERED | RESIZABLE);
+    }
+
+    /**
+     * Constructor
+     */
+    DemoCheckboxWindow(TApplication parent, int flags) {
+        // Construct a demo window.  X and Y don't matter because it
+        // will be centered on screen.
+        super(parent, "Radiobuttons and Checkboxes", 0, 0, 60, 15, flags);
+
+        int row = 1;
+
+        // Add some widgets
+        addLabel("Check box example 1", 1, row);
+        addCheckbox(35, row++, "Checkbox 1", false);
+        addLabel("Check box example 2", 1, row);
+        addCheckbox(35, row++, "Checkbox 2", true);
+        row += 2;
+
+        /*
+        auto group = addRadioGroup(1, row, "Group 1");
+        group.addRadioButton("Radio option 1");
+        group.addRadioButton("Radio option 2");
+        group.addRadioButton("Radio option 3");
+
+        addButton("&Close Window", (width - 14) / 2, height - 4,
+            {
+                application.closeWindow(this);
+            }
+
+        );
+         */
+    }
+
+}
+
+
 class DemoMsgBoxWindow extends TWindow {
     /*
     private void openYNCMessageBox() {
 class DemoMsgBoxWindow extends TWindow {
     /*
     private void openYNCMessageBox() {
-       application.messageBox("Yes/No/Cancel MessageBox",
-           q"EOS
+        application.messageBox("Yes/No/Cancel MessageBox",
+            q"EOS
 This is an example of a Yes/No/Cancel MessageBox.
 
 Note that the MessageBox text can span multiple
 This is an example of a Yes/No/Cancel MessageBox.
 
 Note that the MessageBox text can span multiple
@@ -47,12 +91,12 @@ lines.
 The default result (if someone hits the top-left
 close button) is CANCEL.
 EOS",
 The default result (if someone hits the top-left
 close button) is CANCEL.
 EOS",
-       TMessageBox.Type.YESNOCANCEL);
+        TMessageBox.Type.YESNOCANCEL);
     }
 
     private void openYNMessageBox() {
     }
 
     private void openYNMessageBox() {
-       application.messageBox("Yes/No MessageBox",
-           q"EOS
+        application.messageBox("Yes/No MessageBox",
+            q"EOS
 This is an example of a Yes/No MessageBox.
 
 Note that the MessageBox text can span multiple
 This is an example of a Yes/No MessageBox.
 
 Note that the MessageBox text can span multiple
@@ -61,12 +105,12 @@ lines.
 The default result (if someone hits the top-left
 close button) is NO.
 EOS",
 The default result (if someone hits the top-left
 close button) is NO.
 EOS",
-       TMessageBox.Type.YESNO);
+        TMessageBox.Type.YESNO);
     }
 
     private void openOKCMessageBox() {
     }
 
     private void openOKCMessageBox() {
-       application.messageBox("OK/Cancel MessageBox",
-           q"EOS
+        application.messageBox("OK/Cancel MessageBox",
+            q"EOS
 This is an example of a OK/Cancel MessageBox.
 
 Note that the MessageBox text can span multiple
 This is an example of a OK/Cancel MessageBox.
 
 Note that the MessageBox text can span multiple
@@ -75,12 +119,12 @@ lines.
 The default result (if someone hits the top-left
 close button) is CANCEL.
 EOS",
 The default result (if someone hits the top-left
 close button) is CANCEL.
 EOS",
-       TMessageBox.Type.OKCANCEL);
+        TMessageBox.Type.OKCANCEL);
     }
 
     private void openOKMessageBox() {
     }
 
     private void openOKMessageBox() {
-       application.messageBox("OK MessageBox",
-           q"EOS
+        application.messageBox("OK MessageBox",
+            q"EOS
 This is an example of a OK MessageBox.  This is the
 default MessageBox.
 
 This is an example of a OK MessageBox.  This is the
 default MessageBox.
 
@@ -90,7 +134,7 @@ lines.
 The default result (if someone hits the top-left
 close button) is OK.
 EOS",
 The default result (if someone hits the top-left
 close button) is OK.
 EOS",
-       TMessageBox.Type.OK);
+        TMessageBox.Type.OK);
     }
 
      */
     }
 
      */
@@ -99,55 +143,55 @@ EOS",
      * Constructor.
      */
     DemoMsgBoxWindow(final TApplication parent) {
      * Constructor.
      */
     DemoMsgBoxWindow(final TApplication parent) {
-       this(parent, TWindow.CENTERED | TWindow.RESIZABLE);
+        this(parent, TWindow.CENTERED | TWindow.RESIZABLE);
     }
 
     /**
      * Constructor.
      */
     DemoMsgBoxWindow(final TApplication parent, final int flags) {
     }
 
     /**
      * Constructor.
      */
     DemoMsgBoxWindow(final TApplication parent, final int flags) {
-       // Construct a demo window.  X and Y don't matter because it
-       // will be centered on screen.
-       super(parent, "Message Boxes", 0, 0, 60, 15, flags);
+        // Construct a demo window.  X and Y don't matter because it
+        // will be centered on screen.
+        super(parent, "Message Boxes", 0, 0, 60, 15, flags);
         /*
         /*
-       uint row = 1;
-
-       // Add some widgets
-       addLabel("Default OK message box", 1, row);
-       addButton("Open O&K MB", 35, row, &openOKMessageBox);
-       row += 2;
-
-       addLabel("OK/Cancel message box", 1, row);
-       addButton("O&pen OKC MB", 35, row, &openOKCMessageBox);
-       row += 2;
-
-       addLabel("Yes/No message box", 1, row);
-       addButton("Open &YN MB", 35, row, &openYNMessageBox);
-       row += 2;
-
-       addLabel("Yes/No/Cancel message box", 1, row);
-       addButton("Ope&n YNC MB", 35, row, &openYNCMessageBox);
-       row += 2;
-
-       addLabel("Input box", 1, row);
-       addButton("Open &input box", 35, row,
-           {
-               application.inputBox("Input Box",
-           q"EOS
+        uint row = 1;
+
+        // Add some widgets
+        addLabel("Default OK message box", 1, row);
+        addButton("Open O&K MB", 35, row, &openOKMessageBox);
+        row += 2;
+
+        addLabel("OK/Cancel message box", 1, row);
+        addButton("O&pen OKC MB", 35, row, &openOKCMessageBox);
+        row += 2;
+
+        addLabel("Yes/No message box", 1, row);
+        addButton("Open &YN MB", 35, row, &openYNMessageBox);
+        row += 2;
+
+        addLabel("Yes/No/Cancel message box", 1, row);
+        addButton("Ope&n YNC MB", 35, row, &openYNCMessageBox);
+        row += 2;
+
+        addLabel("Input box", 1, row);
+        addButton("Open &input box", 35, row,
+            {
+                application.inputBox("Input Box",
+            q"EOS
 This is an example of an InputBox.
 
 Note that the InputBox text can span multiple
 lines.
 EOS",
 This is an example of an InputBox.
 
 Note that the InputBox text can span multiple
 lines.
 EOS",
-                   "some input text");
-           }
-       );
-
-       addButton("&Close Window", (width - 14) / 2, height - 4,
-           {
-               application.closeWindow(this);
-           }
-       );
+                    "some input text");
+            }
+        );
+
+        addButton("&Close Window", (width - 14) / 2, height - 4,
+            {
+                application.closeWindow(this);
+            }
+        );
          */
     }
 }
          */
     }
 }
@@ -174,11 +218,6 @@ class DemoMainWindow extends TWindow {
         application.closeWindow(modalWindow);
     }
 
         application.closeWindow(modalWindow);
     }
 
-    /// This is an example of having a button call a function.
-    private void openCheckboxWindow() {
-        new DemoCheckboxWindow(application);
-    }
-
     /// We need to override onClose so that the timer will no longer be
     /// called after we close the window.  TTimers currently are completely
     /// unaware of the rest of the UI classes.
     /// We need to override onClose so that the timer will no longer be
     /// called after we close the window.  TTimers currently are completely
     /// unaware of the rest of the UI classes.
@@ -217,30 +256,40 @@ class DemoMainWindow extends TWindow {
         }
         row += 2;
 
         }
         row += 2;
 
-        /*
         addLabel("Open me as modal", 1, row);
         addButton("W&indow", 35, row,
         addLabel("Open me as modal", 1, row);
         addButton("W&indow", 35, row,
-            {
-                new DemoMainWindow(application, Flag.MODAL);
+            new TAction() {
+                public void DO() {
+                    new DemoMainWindow(getApplication(), MODAL);
+                }
             }
         );
 
         row += 2;
 
             }
         );
 
         row += 2;
 
+        /*
         addLabel("Variable-width text field:", 1, row);
         addField(35, row++, 15, false, "Field text");
 
         addLabel("Fixed-width text field:", 1, row);
         addField(35, row, 15, true);
         row += 2;
         addLabel("Variable-width text field:", 1, row);
         addField(35, row++, 15, false, "Field text");
 
         addLabel("Fixed-width text field:", 1, row);
         addField(35, row, 15, true);
         row += 2;
+         */
 
 
-        if (!isModal) {
+        if (!isModal()) {
             addLabel("Radio buttons and checkboxes", 1, row);
             addLabel("Radio buttons and checkboxes", 1, row);
-            addButton("&Checkboxes", 35, row, &openCheckboxWindow);
+            addButton("&Checkboxes", 35, row,
+                new TAction() {
+                    public void DO() {
+                        new DemoCheckboxWindow(getApplication(), MODAL);
+                    }
+                }
+            );
         }
         row += 2;
 
         }
         row += 2;
 
-        if (!isModal) {
+        /*
+        if (!isModal()) {
             addLabel("Editor window", 1, row);
             addButton("Edito&r", 35, row,
                 {
             addLabel("Editor window", 1, row);
             addButton("Edito&r", 35, row,
                 {
@@ -250,7 +299,7 @@ class DemoMainWindow extends TWindow {
         }
         row += 2;
 
         }
         row += 2;
 
-        if (!isModal) {
+        if (!isModal()) {
             addLabel("Text areas", 1, row);
             addButton("&Text", 35, row,
                 {
             addLabel("Text areas", 1, row);
             addButton("&Text", 35, row,
                 {
@@ -260,7 +309,7 @@ class DemoMainWindow extends TWindow {
         }
         row += 2;
 
         }
         row += 2;
 
-        if (!isModal) {
+        if (!isModal()) {
             addLabel("Tree views", 1, row);
             addButton("Tree&View", 35, row,
                 {
             addLabel("Tree views", 1, row);
             addButton("Tree&View", 35, row,
                 {
@@ -270,17 +319,15 @@ class DemoMainWindow extends TWindow {
         }
         row += 2;
 
         }
         row += 2;
 
-        version(Posix) {
-            if (!isModal) {
-                addLabel("Terminal", 1, row);
-                addButton("Termi&nal", 35, row,
-                    {
-                        application.openTerminal(0, 0);
-                    }
-                );
-            }
-            row += 2;
+        if (!isModal()) {
+            addLabel("Terminal", 1, row);
+            addButton("Termi&nal", 35, row,
+                {
+                    application.openTerminal(0, 0);
+                }
+            );
         }
         }
+        row += 2;
 
         TProgressBar bar = addProgressBar(1, row, 22);
         row++;
 
         TProgressBar bar = addProgressBar(1, row, 22);
         row++;
diff --git a/src/jexer/TCheckbox.java b/src/jexer/TCheckbox.java
new file mode 100644 (file)
index 0000000..556a11b
--- /dev/null
@@ -0,0 +1,149 @@
+/**
+ * Jexer - Java Text User Interface
+ *
+ * License: LGPLv3 or later
+ *
+ * This module is licensed under the GNU Lesser General Public License
+ * Version 3.  Please see the file "COPYING" in this directory for more
+ * information about the GNU Lesser General Public License Version 3.
+ *
+ *     Copyright (C) 2015  Kevin Lamonte
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * http://www.gnu.org/licenses/, or write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * @author Kevin Lamonte [kevin.lamonte@gmail.com]
+ * @version 1
+ */
+package jexer;
+
+import jexer.bits.CellAttributes;
+import jexer.bits.GraphicsChars;
+import jexer.event.TKeypressEvent;
+import jexer.event.TMouseEvent;
+import static jexer.TKeypress.*;
+
+/**
+ * TCheckbox implements an on/off checkbox.
+ */
+public final class TCheckbox extends TWidget {
+
+    /**
+     * Checkbox state, true means checked.
+     */
+    private boolean checked = false;
+
+    /**
+     * Label for this checkbox.
+     */
+    private String label;
+
+    /**
+     * Public constructor.
+     *
+     * @param parent parent widget
+     * @param x column relative to parent
+     * @param y row relative to parent
+     * @param label label to display next to (right of) the checkbox
+     * @param checked initial check state
+     */
+    public TCheckbox(final TWidget parent, final int x, final int y,
+        final String label, final boolean checked) {
+
+        // Set parent and window
+        super(parent);
+
+        setX(x);
+        setY(y);
+        setHeight(1);
+        this.label = label;
+        setWidth(label.length() + 4);
+        this.checked = checked;
+
+        setHasCursor(true);
+        setCursorX(1);
+    }
+
+    /**
+     * Returns true if the mouse is currently on the checkbox.
+     *
+     * @param mouse mouse event
+     * @return true if the mouse is currently on the checkbox
+     */
+    private boolean mouseOnCheckbox(final TMouseEvent mouse) {
+        if ((mouse != null)
+            && (mouse.getY() == 0)
+            && (mouse.getX() >= 0)
+            && (mouse.getX() <= 2)
+        ) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Draw a checkbox with label.
+     */
+    @Override
+    public void draw() {
+        CellAttributes checkboxColor;
+
+        if (getAbsoluteActive()) {
+            checkboxColor = getTheme().getColor("tcheckbox.active");
+        } else {
+            checkboxColor = getTheme().getColor("tcheckbox.inactive");
+        }
+
+        getScreen().putCharXY(0, 0, '[', checkboxColor);
+        if (checked) {
+            getScreen().putCharXY(1, 0, GraphicsChars.CHECK, checkboxColor);
+        } else {
+            getScreen().putCharXY(1, 0, ' ', checkboxColor);
+        }
+        getScreen().putCharXY(2, 0, ']', checkboxColor);
+        getScreen().putStrXY(4, 0, label, checkboxColor);
+    }
+
+    /**
+     * Handle mouse checkbox presses.
+     *
+     * @param mouse mouse button down event
+     */
+    @Override
+    public void onMouseDown(final TMouseEvent mouse) {
+        if ((mouseOnCheckbox(mouse)) && (mouse.getMouse1())) {
+            // Switch state
+            checked = !checked;
+        }
+    }
+
+    /**
+     * Handle keystrokes.
+     *
+     * @param keypress keystroke event
+     */
+    @Override
+    public void onKeypress(final TKeypressEvent keypress) {
+        if (keypress.equals(kbSpace)) {
+            checked = !checked;
+            return;
+        }
+
+        // Pass to parent for the things we don't care about.
+        super.onKeypress(keypress);
+    }
+
+}
index 2ca7108146c0090809d543b91233da31adda130b..6c03a9cccef8d85c4fb934022e88d545a2922d32 100644 (file)
@@ -312,6 +312,15 @@ public abstract class TWidget implements Comparable<TWidget> {
      */
     private boolean hasCursor = false;
 
      */
     private boolean hasCursor = false;
 
+    /**
+     * Set visible cursor flag.
+     *
+     * @param hasCursor if true, this widget has a cursor
+     */
+    public final void setHasCursor(final boolean hasCursor) {
+        this.hasCursor = hasCursor;
+    }
+
     /**
      * See if this widget has a visible cursor.
      *
     /**
      * See if this widget has a visible cursor.
      *
@@ -326,11 +335,47 @@ public abstract class TWidget implements Comparable<TWidget> {
      */
     private int cursorX = 0;
 
      */
     private int cursorX = 0;
 
+    /**
+     * Get cursor X value.
+     *
+     * @return cursor column position in relative coordinates
+     */
+    public final int getCursorX() {
+        return cursorX;
+    }
+
+    /**
+     * Set cursor X value.
+     *
+     * @param cursorX column position in relative coordinates
+     */
+    public final void setCursorX(final int cursorX) {
+        this.cursorX = cursorX;
+    }
+
     /**
      * Cursor row position in relative coordinates.
      */
     private int cursorY = 0;
 
     /**
      * Cursor row position in relative coordinates.
      */
     private int cursorY = 0;
 
+    /**
+     * Get cursor Y value.
+     *
+     * @return cursor row position in relative coordinates
+     */
+    public final int getCursorY() {
+        return cursorY;
+    }
+
+    /**
+     * Set cursor Y value.
+     *
+     * @param cursorY row position in relative coordinates
+     */
+    public final void setCursorY(final int cursorY) {
+        this.cursorY = cursorY;
+    }
+
     /**
      * Comparison operator sorts on tabOrder for TWidgets and z for TWindows.
      *
     /**
      * Comparison operator sorts on tabOrder for TWidgets and z for TWindows.
      *
@@ -341,7 +386,7 @@ public abstract class TWidget implements Comparable<TWidget> {
     @Override
     public final int compareTo(final TWidget that) {
         if ((this instanceof TWindow)
     @Override
     public final int compareTo(final TWidget that) {
         if ((this instanceof TWindow)
-            && (that instanceof TWindow) 
+            && (that instanceof TWindow)
         ) {
             return (((TWindow) this).getZ() - ((TWindow) that).getZ());
         }
         ) {
             return (((TWindow) this).getZ() - ((TWindow) that).getZ());
         }
@@ -956,5 +1001,19 @@ public abstract class TWidget implements Comparable<TWidget> {
         return new TButton(this, text, x, y, action);
     }
 
         return new TButton(this, text, x, y, action);
     }
 
+    /**
+     * Convenience function to add a checkbox to this container/window.
+     *
+     * @param x column relative to parent
+     * @param y row relative to parent
+     * @param label label to display next to (right of) the checkbox
+     * @param checked initial check state
+     * @return the new checkbox
+     */
+    public final TCheckbox addCheckbox(final int x, final int y,
+        final String label, final boolean checked) {
+
+        return new TCheckbox(this, x, y, label, checked);
+    }
 
 }
 
 }