Index: main/widget/checkbox.lisp
===================================================================
--- main/widget/checkbox.lisp	(revision main,84)
+++ main/widget/checkbox.lisp	(revision main,84)
@@ -0,0 +1,87 @@
+(defpackage #:tui-widget-checkbox
+  (:use #:cl #:tui-widget-generic)
+  (:import-from #:dso-util #:nothing)
+  (:import-from #:tui-cursor #:cursor-position #:set-cursor-visible)
+  (:import-from #:tui-input #:read-key)
+  (:import-from #:tui-output #:add-clipped-string #:background)
+  (:import-from #:tui-window #:create-subwindow #:destroy-subwindow #:erase
+                #:refresh #:window-pointer)
+  (:export
+
+   ;; inherited
+   #:text #:widget #:parent-window #:column #:row #:inactive-background
+   #:active-background #:scroll #:insertion-point #:create-widget #:destroy
+   #:draw #:activate
+
+   ;; local
+   #:checkbox #:checked #:listener))
+
+(in-package #:tui-widget-checkbox)
+
+
+
+(defclass checkbox (widget)
+  ((checked :type boolean :initform nil :accessor checked)
+   (listener :type (or null function) :initform nil :accessor listener)
+   (cue-window :initarg :cue-window)
+   (data-window :initarg :data-window)
+   (active :type boolean :initform nil)))
+
+
+
+(defmethod draw ((cb checkbox))
+  (with-slots (checked cue-window data-window inactive-background
+                       active-background active) cb
+    (erase cue-window)
+    (add-clipped-string cue-window 0 0 "[ ]")
+    (setf (background data-window)
+          (if active active-background inactive-background))
+    (add-clipped-string data-window 0 0 (if (checked cb) "X" " "))
+    (setf (cursor-position data-window) '(0 0))
+    (refresh cue-window)))
+
+(defmethod (setf checked) :after (flag (cb checkbox))
+  (draw cb)
+  (with-slots (listener) cb
+    (when listener
+      (funcall listener))))
+
+
+
+(defmethod create-widget ((type (eql 'checkbox)) parent y x &rest args &key
+                          inactive-background active-background)
+  (declare (ignore type inactive-background active-background))
+  (let* ((cue-window (create-subwindow parent 1 3 y x))
+         (data-window (create-subwindow cue-window 1 1 0 1))
+         (inst (apply 'make-instance 'checkbox :cue-window cue-window
+                                               :data-window data-window args)))
+    (draw inst)
+    inst))
+
+(defmethod destroy ((cb checkbox))
+  (with-slots (cue-window data-window) cb
+    (destroy-subwindow data-window)
+    (destroy-subwindow cue-window)))
+
+
+
+(defmethod activate ((cb checkbox) &key (key-callback 'nothing)
+                     &allow-other-keys)
+  (with-slots (data-window active) cb
+    (with-accessors ((checked checked)) cb
+      (set-cursor-visible t)
+      (setf active t)
+      (unwind-protect
+           (progn
+             (cdk::c-keypad (window-pointer data-window) t)
+             (loop
+                (let ((key (read-key data-window)))
+                  (case key
+                    (#\Space
+                     (setf checked (not checked)))
+                    (t
+                     (let ((r (funcall key-callback key)))
+                       (when r
+                         (return r))))))))
+        (setf active nil)
+        (set-cursor-visible nil)))))
Index: main/widget/db-checkbox.lisp
===================================================================
--- main/widget/db-checkbox.lisp	(revision main,84)
+++ main/widget/db-checkbox.lisp	(revision main,84)
@@ -0,0 +1,35 @@
+(defpackage #:tui-widget-db-checkbox
+  (:use #:cl #:tui-widget-checkbox)
+  (:export
+
+   ;; widget
+   #:text #:widget #:parent-window #:column #:row #:inactive-background
+   #:active-background #:scroll #:insertion-point #:create-widget #:destroy
+   #:draw #:activate
+
+   ;; checkbox
+   #:checkbox #:checked #:listener
+
+   ;; db-checkbox
+   #:db-checkbox))
+
+(in-package #:tui-widget-db-checkbox)
+
+
+
+(defclass db-checkbox (checkbox)
+  ((data :initarg :data :accessor data)))
+
+(defmethod checked ((cb db-checkbox))
+  (text (data cb)))
+
+(defmethod (setf checked) (flag (cb db-checkbox))
+  (setf (text (data cb)) flag))
+
+
+
+(defmethod create-widget ((type (eql 'db-checkbox)) parent y x &rest args
+                          &key data &allow-other-keys)
+  (assert data (data) "DATA must be specified.")
+  (let ((inst (apply 'create-widget 'checkbox parent y x args)))
+    (change-class inst 'db-checkbox :data data)))
Index: main/tui.asd
===================================================================
--- main/tui.asd	(revision main,70)
+++ main/tui.asd	(revision main,84)
@@ -23,5 +23,8 @@
                                      "output"
                                      "window")
-                        :components ((:file "generic")
+                        :components ((:file "checkbox" :depends-on ("generic"))
+                                     (:file "db-checkbox"
+                                      :depends-on ("checkbox"))
+                                     (:file "generic")
                                      (:file "label"
                                       :depends-on ("generic"))
@@ -31,5 +34,7 @@
                                       :depends-on ("generic" "textbox"))
                                      (:file "package"
-                                      :depends-on ("label"
+                                      :depends-on ("checkbox"
+                                                   "db-checkbox"
+                                                   "label"
                                                    "textbox"
                                                    "numberbox"))))
Index: main/widget/generic.lisp
===================================================================
--- main/widget/generic.lisp	(revision main,63)
+++ main/widget/generic.lisp	(revision main,84)
@@ -2,6 +2,6 @@
   (:use #:cl)
   (:export #:text #:widget #:parent-window #:column #:row #:inactive-background
-           #:active-background #:scroll #:insertion-point #:destroy #:draw
-           #:activate))
+           #:active-background #:scroll #:insertion-point #:create-widget
+           #:destroy #:draw #:activate))
 
 (in-package #:tui-widget-generic)
@@ -26,6 +26,6 @@
    (row :type (integer 0) :initarg :row)
    ;; TODO: initform for bg-color
-   (inactive-background :initarg :inactive-background)
-   (active-background :initarg :active-background)))
+   (inactive-background :initform '(#\Nul 0) :initarg :inactive-background)
+   (active-background :initform '(#\Nul 0) :initarg :active-background)))
 
 (defclass scroll ()
@@ -39,4 +39,6 @@
 
 
+(defgeneric create-widget (type parent y x &key &allow-other-keys))
+
 (defgeneric destroy (widget))
 
Index: main/widget/package.lisp
===================================================================
--- main/widget/package.lisp	(revision main,40)
+++ main/widget/package.lisp	(revision main,84)
@@ -2,5 +2,8 @@
   (:use #:cl #:tui-widget-generic #:tui-widget-label #:tui-widget-textbox
         #:tui-widget-numberbox)
-  (:export #:text #:widget #:scroll #:insertion-point #:destroy #:activate
+  (:export #:text #:widget #:scroll #:insertion-point #:create-widget #:destroy
+           #:activate
+           #:checkbox #:checked #:listener
+           #:db-checkbox
            #:label #:create-label
            #:textbox #:create-textbox
