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

(msg/key-press key & options)

Create a key press message (mainly for testing).

Options:

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

key-press?

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

Check if a message is a key press.

key-match?

(msg/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
    (msg/key-match? msg "q") [state program/quit-cmd]
    (msg/key-match? msg :enter) [(submit state) nil]
    (msg/key-match? msg "ctrl+c") [state program/quit-cmd]
    (msg/key-match? msg :up) [(move-up state) nil]
    :else [state nil]))

Modifier Predicates

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

Mouse Messages

mouse

(msg/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)

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

mouse?

(msg/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 (msg/mouse? msg) (= :press (:action msg)))
    (let [{:keys [x y button]} msg]
      [(handle-click state x y button) nil])

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

    :else
    [state nil]))

Window Size Messages

window-size

(msg/window-size width height)

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

window-size?

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

Window size message structure:

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

Example:

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

Focus Messages

focus / blur

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

focus? / blur?

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

Requires :focus-reporting true in run options.

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

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

    :else
    [state nil]))

Quit and Error Messages

quit

(msg/quit) ; Create quit message

quit?

(msg/quit? msg) ; => boolean

error

(msg/error throwable) ; Create error message

error?

(msg/error? msg) ; => boolean

Message Type Helper

msg-type

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

Get the type of any message.

(msg/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.message :as msg]
   [charm.program :as program]))

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

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

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

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

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

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

    (msg/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