branch: elpa/casual
commit d8ee219ef906783ebd251c5cf0a085e54348efaa
Author: Charles Choi <[email protected]>
Commit: Charles Choi <[email protected]>

    Add Casual Timezone Planner Features
    
    - Add f/b bindings for forward/backward day in planner.
    - Add highlighting for working hours with variable customization. 
(casual-timezone-planner-working-highlight)
    - Add customizable working hour glyph (casual-timezone-working-hour-glyph).
    - Add support for world-clock to casual-timezone-planner-tmenu.
---
 docs/casual.info                                   |  39 +++++++---
 docs/casual.org                                    |  15 +++-
 docs/images/casual-timezone-planner-screenshot.png | Bin 458462 -> 486962 bytes
 lisp/casual-timezone-settings.el                   |  37 ++++++++-
 lisp/casual-timezone-utils.el                      |  83 +++++++++++++++++++--
 tests/test-casual-timezone-settings.el             |   6 +-
 tests/test-casual-timezone-utils.el                |  12 +++
 7 files changed, 171 insertions(+), 21 deletions(-)

diff --git a/docs/casual.info b/docs/casual.info
index 7be08ce860..072aa56b16 100644
--- a/docs/casual.info
+++ b/docs/casual.info
@@ -11,7 +11,7 @@ File: casual.info,  Node: Top,  Next: Motivations,  Up: (dir)
 Casual User Guide
 *****************
 
-Version: 2.4.3
+Version: 2.5.0
 
 Casual is a project to re-imagine the primary user interface for Emacs
 using keyboard-driven menus.
@@ -1166,6 +1166,26 @@ Command                                  Format
 ‘casual-timezone-local-time-to-remote’   
‘casual-timezone-convert-datestamp-format’
 ‘casual-timezone-remote-time-to-local’   
‘casual-timezone-convert-datestamp-format’
 
+These variables can be customized via the Transient menu
+‘casual-timezone-settings-tmenu’.
+
+Planner Configuration
+=====================
+
+The following variables can control how working hours are displayed in
+the timezone planner.
+
+   • ‘casual-timezone-working-hours-range’ will set the range (start,
+     stop) of working hours.  The values are integers that map to
+     24-hour time (0..23).
+   • ‘casual-timezone-working-hour-glyph’ will set the glyph used to
+     denote a working hour (default is ☼).
+   • ‘casual-timezone-planner-working-highlight’ will set the face used
+     to highlight a working hour.
+
+These variables can be customized via the Transient menu
+‘casual-timezone-settings-tmenu’.
+
 
 File: casual.info,  Node: UX Conventions,  Next: Customization,  Prev: Casual 
Modes,  Up: Top
 
@@ -1364,6 +1384,7 @@ File: casual.info,  Node: Index,  Next: Variable Index,  
Prev: Acknowledgments,
 * Timezone:                              Timezone.             (line  6)
 * Timezone Configuration:                Timezone.             (line 19)
 * Timezone Formatting:                   Timezone.             (line 47)
+* Timezone Planner Configuration:        Timezone.             (line 71)
 * Timezone Usage:                        Timezone.             (line 31)
 * Transient Conventions:                 Transient Conventions.
                                                                (line  6)
@@ -1401,14 +1422,14 @@ Node: I-Search24468
 Node: Make25629
 Node: RE-Builder28013
 Node: Timezone31437
-Node: UX Conventions33834
-Node: Customization36535
-Node: Feedback & Discussion36909
-Node: Sponsorship37327
-Node: About37621
-Node: Acknowledgments37898
-Node: Index38280
-Node: Variable Index42474
+Node: UX Conventions34567
+Node: Customization37268
+Node: Feedback & Discussion37642
+Node: Sponsorship38060
+Node: About38354
+Node: Acknowledgments38631
+Node: Index39013
+Node: Variable Index43280
 
 End Tag Table
 
diff --git a/docs/casual.org b/docs/casual.org
index f9514402c2..4b7d9ca2bf 100644
--- a/docs/casual.org
+++ b/docs/casual.org
@@ -6,7 +6,7 @@
 #+OPTIONS: ':t toc:t author:t email:t compact-itemx:t
 #+LANGUAGE: en
 
-#+MACRO: version 2.4.3
+#+MACRO: version 2.5.0
 
 #+TEXINFO_FILENAME: casual.info
 #+TEXINFO_HEADER: @syncodeindex pg cp
@@ -849,6 +849,19 @@ The following table shows which format variable applies to 
which command.
 | ~casual-timezone-local-time-to-remote~ | 
~casual-timezone-convert-datestamp-format~ |
 | ~casual-timezone-remote-time-to-local~ | 
~casual-timezone-convert-datestamp-format~ |
 
+These variables can be customized via the Transient menu 
~casual-timezone-settings-tmenu~. 
+
+#+TEXINFO: @unnumberedsec Planner Configuration
+#+CINDEX: Timezone Planner Configuration
+
+The following variables can control how working hours are displayed in the 
timezone planner.
+
+- ~casual-timezone-working-hours-range~  will set the range (start, stop) of 
working hours. The values are integers that map to 24-hour time (0..23).
+- ~casual-timezone-working-hour-glyph~ will set the glyph used to denote a 
working hour (default is ☼).
+- ~casual-timezone-planner-working-highlight~ will set the face used to 
highlight a working hour.
+
+These variables can be customized via the Transient menu 
~casual-timezone-settings-tmenu~. 
+  
 * UX Conventions
 #+CINDEX: UX Conventions
 
diff --git a/docs/images/casual-timezone-planner-screenshot.png 
b/docs/images/casual-timezone-planner-screenshot.png
index 78cf0fff96..987ba5a000 100644
Binary files a/docs/images/casual-timezone-planner-screenshot.png and 
b/docs/images/casual-timezone-planner-screenshot.png differ
diff --git a/lisp/casual-timezone-settings.el b/lisp/casual-timezone-settings.el
index 62cbf1d76f..ae54c63f32 100644
--- a/lisp/casual-timezone-settings.el
+++ b/lisp/casual-timezone-settings.el
@@ -28,10 +28,21 @@
 (transient-define-prefix casual-timezone-settings-tmenu ()
   "Casual Timezone settings menu."
   ["Timezone: Settings"
-   ["Customize"
-    ("w" "Working Hours" casual-timezone--customize-working-hours-range)
-    (casual-lib-customize-unicode)
-    (casual-lib-customize-hide-navigation)]
+   ["Working Hours"
+    ("r" "Range" casual-timezone--customize-working-hours-range
+     :description (lambda ()
+                    (format
+                     "Range (%d..%d)"
+                     (map-elt casual-timezone-working-hours-range :start)
+                     (map-elt casual-timezone-working-hours-range :stop))))
+
+    ("g" "Glyph" casual-timezone--customize-working-hour-glyph
+     :description (lambda ()
+                    (format
+                     "Glyph (%s)"
+                     casual-timezone-working-hour-glyph)))
+
+    ("F" "Face" casual-timezone--customize-planner-working-highlight)]
 
    ["Formats"
     ("c" "Convert" casual-timezone--customize-convert-timestamp-format
@@ -51,12 +62,30 @@
                      (current-time)))))
     ("f" "Describe Format" casual-timezone--describe-format-time-string)]]
 
+  [:class transient-row
+   (casual-lib-customize-unicode)
+   (casual-lib-customize-hide-navigation)]
+
   [:class transient-row
    (casual-lib-quit-one)
    ("a" "About" casual-timezone-about :transient nil)
 
    (casual-lib-quit-all)])
 
+(defun casual-timezone--customize-working-hour-glyph ()
+  "Set working hour glyph.
+
+This customizes the variable `casual-timezone-working-hour-glyph'."
+  (interactive)
+  (customize-variable 'casual-timezone-working-hour-glyph))
+
+(defun casual-timezone--customize-planner-working-highlight ()
+  "Set working hour highlight face.
+
+This customizes the face `casual-timezone-working-highlight'."
+  (interactive)
+  (customize-face 'casual-timezone-planner-working-highlight))
+
 (defun casual-timezone--customize-working-hours-range ()
   "Set working hours range.
 
diff --git a/lisp/casual-timezone-utils.el b/lisp/casual-timezone-utils.el
index f8e0a5b364..8793b0abc1 100644
--- a/lisp/casual-timezone-utils.el
+++ b/lisp/casual-timezone-utils.el
@@ -30,6 +30,8 @@
 (defconst casual-timezone-unicode-db
   '((:previous . '("↑" "Previous"))
     (:next . '("↓" "Next"))
+    (:forward . '("→" "Forward"))
+    (:backward . '("←" "Backward"))
     (:current . '("⨀" "Current Hour")))
 
   "Unicode symbol DB to use for Timezone Transient menus.")
@@ -62,7 +64,6 @@ The specification of this variable conforms to the format 
string used by
   :type 'string
   :group 'casual)
 
-
 (defcustom casual-timezone-datestamp-format "%a %b %-e %Y, %l:%M %p"
   "Datestamp format used by `casual-timezone-planner'.
 
@@ -76,6 +77,31 @@ If 24 hour clock time is preferred, use ‘%k’ instead of 
‘%l’."
   :type 'string
   :group 'casual)
 
+(defcustom casual-timezone-working-hour-glyph "☼"
+  "Working hour glyph used by `casual-timezone-planner'.
+
+This customizable variable contains the glyph used to annotate a
+working hour in `casual-timezone-planner'."
+  :type 'string
+  :group 'casual)
+
+(defface casual-timezone-planner-working-highlight
+  '((((type tty) (class color))
+     :background "gray25")
+    (((class color) (min-colors 88) (background light))
+     :background "#FDFEB1" :foreground "black")
+    (((class color) (min-colors 88) (background dark))
+     :background "gray25")
+    (((class color) (min-colors 16) (background light))
+     :background "yellow")
+    (((class color) (min-colors 16) (background dark))
+     :background "olive")
+    (((class color) (min-colors 8))
+     :background "olive" :foreground "black")
+    (t :inverse-video t))
+  "Casual Timezone Planner working hours highlight."
+  :group 'casual)
+
 (defun casual-timezone-zone-info ()
   "List of timezones in zoneinfo database.
 
@@ -207,6 +233,8 @@ The format of the timestamp is defined in the variable
   "t" #'casual-timezone-planner-current-time
   "l" #'casual-timezone-planner-current-local
   "r" #'casual-timezone-planner-current-remote
+  "f" #'casual-timezone-planner-forward-day
+  "b" #'casual-timezone-planner-backward-day
   "p" #'previous-line
   "n" #'next-line
   "q" #'quit-window
@@ -263,7 +291,6 @@ customized via the variable 
`casual-timezone-working-hours-range'."
 
     (get-buffer-create tz-buffer-name)
     (switch-to-buffer (set-buffer tz-buffer-name))
-    ;;(read-only-mode)
     (casual-timezone-planner-mode)
 
     (let ((inhibit-read-only t))
@@ -381,11 +408,46 @@ This formats the output result using the customizable 
variables
 
     (if (and (>= hour (map-elt casual-timezone-working-hours-range :start))
              (<= hour (map-elt casual-timezone-working-hours-range :stop)))
-        (concat datestamp " " "☼")
+        (propertize
+         (concat datestamp " " casual-timezone-working-hour-glyph)
+         'face
+         'casual-timezone-planner-working-highlight)
       datestamp)))
 
-;; Transients
+(defun casual-timezone-planner-forward-day ()
+  "Move forward one day in timezone planner.
 
+Note: This command relies on `vtable-update-object' which breaks if the
+window width has changed."
+  (interactive)
+  (unless (vtable-current-table) (error "No planner table"))
+  (casual-timezone--planner-adjust-day nil))
+
+(defun casual-timezone-planner-backward-day ()
+  "Move backward one day in timezone planner.
+
+Note: This command relies on `vtable-update-object' which breaks if the
+window width has changed."
+  (interactive)
+  (unless (vtable-current-table) (error "No planner table"))
+  (casual-timezone--planner-adjust-day t))
+
+(defun casual-timezone--planner-adjust-day (backward)
+  "If BACKWARD is non-nil, adjust timezone planner -24 hours, otherwise ahead."
+  (let* ((table (vtable-current-table))
+         (objects (oref table objects))
+         (posix-day 86400)
+         (time-adjust (if backward
+                          (* -1 posix-day)
+                        posix-day)))
+    (mapc (lambda (obj)
+            (let ((adjusted-obj
+                   (seq-map (lambda (x) (+ x time-adjust)) obj)))
+              (vtable-update-object table adjusted-obj obj)))
+          objects)
+    (casual-timezone-jump-to-relative-now)))
+
+;; Transients
 (transient-define-prefix casual-timezone-planner-tmenu ()
   "Main menu for Casual Timezone."
 
@@ -401,13 +463,22 @@ This formats the output result using the customizable 
variables
      :description (lambda () (casual-timezone-unicode-get :next))
      :transient t)]
 
+   ["Day"
+    ("f" "Forward" casual-timezone-planner-forward-day
+     :description (lambda () (casual-timezone-unicode-get :forward))
+     :transient t)
+    ("b" "Backward" casual-timezone-planner-backward-day
+     :description (lambda () (casual-timezone-unicode-get :backward))
+     :transient t)]
+
    ["Copy Time"
-    ("t" "Time" casual-timezone-planner-current-time)
+    ("t" "Times" casual-timezone-planner-current-time)
     ("l" "Local" casual-timezone-planner-current-local)
     ("r" "Remote" casual-timezone-planner-current-remote)]
 
    ["Misc"
-    ("z" "Planner…" casual-timezone-planner)]]
+    ("z" "Planner…" casual-timezone-planner)
+    ("w" "World Clock" world-clock)]]
 
   [:class transient-row
    (casual-lib-quit-one)
diff --git a/tests/test-casual-timezone-settings.el 
b/tests/test-casual-timezone-settings.el
index fa8a7dd040..6eef0cc2e3 100644
--- a/tests/test-casual-timezone-settings.el
+++ b/tests/test-casual-timezone-settings.el
@@ -33,12 +33,16 @@
     (casualt-timezone-setup)
     (cl-letf ((casualt-mock #'casual-timezone-about)
               (casualt-mock #'casual-timezone--customize-working-hours-range)
+              (casualt-mock #'casual-timezone--customize-working-hour-glyph)
+              (casualt-mock 
#'casual-timezone--customize-planner-working-highlight)
               (casualt-mock 
#'casual-timezone--customize-convert-timestamp-format)
               (casualt-mock #'casual-timezone--customize-datestamp-format)
               (casualt-mock #'casual-timezone--describe-format-time-string))
 
       (let ((test-vectors
-             '((:binding "w" :command 
casual-timezone--customize-working-hours-range)
+             '((:binding "r" :command 
casual-timezone--customize-working-hours-range)
+               (:binding "g" :command 
casual-timezone--customize-working-hour-glyph)
+               (:binding "F" :command 
casual-timezone--customize-planner-working-highlight)
                (:binding "c" :command 
casual-timezone--customize-convert-timestamp-format)
                (:binding "p" :command 
casual-timezone--customize-datestamp-format)
                (:binding "f" :command 
casual-timezone--describe-format-time-string)
diff --git a/tests/test-casual-timezone-utils.el 
b/tests/test-casual-timezone-utils.el
index a9f8c6c74b..228ff76866 100644
--- a/tests/test-casual-timezone-utils.el
+++ b/tests/test-casual-timezone-utils.el
@@ -29,10 +29,16 @@
 
 (ert-deftest test-casual-timezone-unicode-get ()
   (let ((casual-lib-use-unicode nil))
+    (should (string-equal (casual-timezone-unicode-get :forward) "Forward"))
+    (should (string-equal (casual-timezone-unicode-get :backward) "Backward"))
+    (should (string-equal (casual-timezone-unicode-get :current) "Current 
Hour"))
     (should (string-equal (casual-timezone-unicode-get :previous) "Previous"))
     (should (string-equal (casual-timezone-unicode-get :next) "Next")))
 
   (let ((casual-lib-use-unicode t))
+    (should (string-equal (casual-timezone-unicode-get :forward) "→"))
+    (should (string-equal (casual-timezone-unicode-get :backward) "←"))
+    (should (string-equal (casual-timezone-unicode-get :current) "⨀"))
     (should (string-equal (casual-timezone-unicode-get :previous) "↑"))
     (should (string-equal (casual-timezone-unicode-get :next) "↓"))))
 
@@ -42,20 +48,26 @@
     (cl-letf ((casualt-mock #'casual-timezone-jump-to-relative-now)
               (casualt-mock #'previous-line)
               (casualt-mock #'next-line)
+              (casualt-mock #'casual-timezone-planner-forward-day)
+              (casualt-mock #'casual-timezone-planner-backward-day)
               (casualt-mock #'casual-timezone-planner-current-time)
               (casualt-mock #'casual-timezone-planner-current-local)
               (casualt-mock #'casual-timezone-planner-current-remote)
               (casualt-mock #'casual-timezone-planner)
+              (casualt-mock #'world-clock)
               (casualt-mock #'quit-window))
 
       (let ((test-vectors
              '((:binding "." :command casual-timezone-jump-to-relative-now)
                (:binding "p" :command previous-line)
                (:binding "n" :command next-line)
+               (:binding "f" :command casual-timezone-planner-forward-day)
+               (:binding "b" :command casual-timezone-planner-backward-day)
                (:binding "t" :command casual-timezone-planner-current-time)
                (:binding "l" :command casual-timezone-planner-current-local)
                (:binding "r" :command casual-timezone-planner-current-remote)
                (:binding "z" :command casual-timezone-planner)
+               (:binding "w" :command world-clock)
                (:binding "q" :command quit-window))))
 
         (casualt-suffix-testcase-runner test-vectors

Reply via email to