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:
 
-- TCheckbox
 - TDirectoryList
 - TField
 - TMessageBox
index 5d5485a83fe4fb529bc751bcecb23cb30d2cb777..44333a42b4be7f3a30f93f38c995bf31f5a395c1 100644 (file)
 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() {
-       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
@@ -47,12 +91,12 @@ lines.
 The default result (if someone hits the top-left
 close button) is CANCEL.
 EOS",
-       TMessageBox.Type.YESNOCANCEL);
+        TMessageBox.Type.YESNOCANCEL);
     }
 
     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
@@ -61,12 +105,12 @@ lines.
 The default result (if someone hits the top-left
 close button) is NO.
 EOS",
-       TMessageBox.Type.YESNO);
+        TMessageBox.Type.YESNO);
     }
 
     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
@@ -75,12 +119,12 @@ lines.
 The default result (if someone hits the top-left
 close button) is CANCEL.
 EOS",
-       TMessageBox.Type.OKCANCEL);
+        TMessageBox.Type.OKCANCEL);
     }
 
     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.
 
@@ -90,7 +134,7 @@ lines.
 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) {
-       this(parent, TWindow.CENTERED | TWindow.RESIZABLE);
+        this(parent, TWindow.CENTERED | TWindow.RESIZABLE);
     }
 
     /**
      * 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",
-                   "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);
     }
 
-    /// 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.
@@ -217,30 +256,40 @@ class DemoMainWindow extends TWindow {
         }
         row += 2;
 
-        /*
         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;
 
+        /*
         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);
-            addButton("&Checkboxes", 35, row, &openCheckboxWindow);
+            addButton("&Checkboxes", 35, row,
+                new TAction() {
+                    public void DO() {
+                        new DemoCheckboxWindow(getApplication(), MODAL);
+                    }
+                }
+            );
         }
         row += 2;
 
-        if (!isModal) {
+        /*
+        if (!isModal()) {
             addLabel("Editor window", 1, row);
             addButton("Edito&r", 35, row,
                 {
@@ -250,7 +299,7 @@ class DemoMainWindow extends TWindow {
         }
         row += 2;
 
-        if (!isModal) {
+        if (!isModal()) {
             addLabel("Text areas", 1, row);
             addButton("&Text", 35, row,
                 {
@@ -260,7 +309,7 @@ class DemoMainWindow extends TWindow {
         }
         row += 2;
 
-        if (!isModal) {
+        if (!isModal()) {
             addLabel("Tree views", 1, row);
             addButton("Tree&View", 35, row,
                 {
@@ -270,17 +319,15 @@ class DemoMainWindow extends TWindow {
         }
         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++;
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;
 
+    /**
+     * 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.
      *
@@ -326,11 +335,47 @@ public abstract class TWidget implements Comparable<TWidget> {
      */
     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;
 
+    /**
+     * 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.
      *
@@ -341,7 +386,7 @@ public abstract class TWidget implements Comparable<TWidget> {
     @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());
         }
@@ -956,5 +1001,19 @@ public abstract class TWidget implements Comparable<TWidget> {
         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);
+    }
 
 }