Liking cljdoc? Tell your friends :D

Messages API

Messages are plain maps with a :type key that flow through the update function. charm.clj provides factory functions and predicates for common message types.

Key Press Messages

key-press

(charm/key-press key & options)

Create a key press message (mainly for testing).

Options:

OptionTypeDefaultDescription
keystring/keywordrequiredThe key pressed
:ctrlbooleanfalseCtrl modifier
:altbooleanfalseAlt modifier
:shiftbooleanfalseShift modifier
(charm/key-press "a")
(charm/key-press :enter)
(charm/key-press "c" :ctrl true)

key-press?

(charm/key-press? msg) ; => boolean

Check if a message is a key press.

key-match?

(charm/key-match? msg key) ; => boolean

Check if a key press matches a specific key pattern.

Key patterns:

PatternMatches
"a"Letter a
"A"Shift+a
"1"Number 1
" "Space
:enterEnter key
:tabTab key
:upUp arrow
:downDown arrow
:leftLeft arrow
:rightRight arrow
:backspaceBackspace
:deleteDelete
:escape or "esc"Escape
:homeHome
:endEnd
:pgupPage Up
:pgdownPage Down
"ctrl+c"Ctrl+C
"ctrl+x"Ctrl+X
"alt+f"Alt+F
"shift+tab"Shift+Tab
"ctrl+alt+delete"Ctrl+Alt+Delete

Examples:

(defn update-fn [state msg]
  (cond
    (charm/key-match? msg "q") [state charm/quit-cmd]
    (charm/key-match? msg :enter) [(submit state) nil]
    (charm/key-match? msg "ctrl+c") [state charm/quit-cmd]
    (charm/key-match? msg :up) [(move-up state) nil]
    :else [state nil]))

Modifier Predicates

(charm/ctrl? msg)  ; => boolean - Ctrl modifier set?
(charm/alt? msg)   ; => boolean - Alt modifier set?
(charm/shift? msg) ; => boolean - Shift modifier set?

Mouse Messages

mouse

(charm/mouse action button x y & options)

Create a mouse event message (mainly for testing).

Parameters:

ParameterTypeDescription
actionkeyword:press, :release, :motion, :wheel-up, :wheel-down
buttonkeyword:left, :middle, :right, :none
xintColumn (0-indexed)
yintRow (0-indexed)

Options: :ctrl, :alt, :shift (boolean modifiers)

(charm/mouse :press :left 10 5)
(charm/mouse :wheel-up :none 10 5)

mouse?

(charm/mouse? msg) ; => boolean

Check if a message is a mouse event.

Mouse message structure:

{:type :mouse
 :action :press      ; :press, :release, :motion, :wheel-up, :wheel-down
 :button :left       ; :left, :middle, :right, :none
 :x 10               ; column
 :y 5                ; row
 :ctrl false
 :alt false
 :shift false}

Example:

(defn update-fn [state msg]
  (cond
    (and (charm/mouse? msg) (= :press (:action msg)))
    (let [{:keys [x y button]} msg]
      [(handle-click state x y button) nil])

    (and (charm/mouse? msg) (= :wheel-up (:action msg)))
    [(scroll-up state) nil]

    :else
    [state nil]))

Window Size Messages

window-size

(charm/window-size width height)

Create a window size message (sent automatically on resize).

window-size?

(charm/window-size? msg) ; => boolean

Window size message structure:

{:type :window-size
 :width 80
 :height 24}

Example:

(defn update-fn [state msg]
  (if (charm/window-size? msg)
    [(assoc state
            :width (:width msg)
            :height (:height msg))
     nil]
    [state nil]))

Focus Messages

focus / blur

(charm/focus) ; Create focus gained message
(charm/blur)  ; Create focus lost message

focus? / blur?

(charm/focus? msg) ; => boolean
(charm/blur? msg)  ; => boolean

Requires :focus-reporting true in run options.

(defn update-fn [state msg]
  (cond
    (charm/focus? msg)
    [(assoc state :active true) nil]

    (charm/blur? msg)
    [(assoc state :active false) nil]

    :else
    [state nil]))

Quit and Error Messages

quit

(charm/quit) ; Create quit message

quit?

(charm/quit? msg) ; => boolean

error

(charm/error throwable) ; Create error message

error?

(charm/error? msg) ; => boolean

Message Type Helper

msg-type

(charm/msg-type msg) ; => keyword

Get the type of any message.

(charm/msg-type {:type :key-press :key "a"}) ; => :key-press

Custom Messages

Create custom messages as plain maps with a :type key:

;; Define custom message types
(defn data-loaded [data]
  {:type :data-loaded
   :data data})

(defn timer-tick [id]
  {:type :timer-tick
   :id id})

;; Use in update function
(defn update-fn [state msg]
  (case (:type msg)
    :data-loaded (handle-data state (:data msg))
    :timer-tick (handle-tick state (:id msg))
    :key-press (handle-key state msg)
    [state nil]))

Complete Example

(ns my-app
  (:require [charm.core :as charm]))

(defn update-fn [state msg]
  (cond
    ;; Quit on q or Ctrl+C
    (or (charm/key-match? msg "q")
        (charm/key-match? msg "ctrl+c"))
    [state charm/quit-cmd]

    ;; Navigation
    (charm/key-match? msg :up)
    [(update state :cursor dec) nil]

    (charm/key-match? msg :down)
    [(update state :cursor inc) nil]

    ;; Window resize
    (charm/window-size? msg)
    [(assoc state :size [(:width msg) (:height msg)]) nil]

    ;; Mouse click
    (and (charm/mouse? msg) (= :press (:action msg)))
    [(assoc state :clicked [(:x msg) (:y msg)]) nil]

    ;; Focus changes
    (charm/focus? msg)
    [(assoc state :focused true) nil]

    (charm/blur? msg)
    [(assoc state :focused false) nil]

    :else
    [state nil]))

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close