(ns microtables-frontend.events (:require [re-frame.core :as re-frame] [microtables-frontend.db :as db] [microtables-frontend.utils :as utils])) (re-frame/reg-event-db ::initialize-db (fn [_ _] (println "initializing db") (-> db/default-db (update-in [:table-data] #(utils/walk-modify-data % (fn [c r datum] (if (= (first (:value datum)) "=") (assoc datum :dirty true) datum)))) (update-in [:table-data] utils/create-all-references) (update-in [:table-data] utils/create-all-back-references) (update-in [:table-data] utils/evaluate-all)))) (re-frame/reg-event-db ::movement-enter-cell (fn [db [_ c r]] (println "::movement-enter-cell" c r) (assoc-in db [:position :cursor] {:col c :row r}))) (re-frame/reg-event-db ::movement-leave-cell (fn [db [_ c r]] (println "::movement-leave-cell" c r) (-> db (assoc-in [:position :cursor] nil) (assoc-in [:position :selection] nil) (update-in [:table-data] #(utils/reset-references % c r)) (update-in [:table-data] #(utils/evaluate-from-cell % c r))))) (re-frame/reg-event-db ::edit-cell-value (fn [db [_ c r value]] (println "::edit-cell-value" c r value) (update-in db [:table-data] #(utils/change-datum-value % c r value)))) ; handle pressing enter (move to the next cell down) ; tab is taken care of natively, and is good enough (re-frame/reg-event-fx ::press-enter-in-cell (fn [{:keys [db]} [_ c r]] (let [max-row? (= (utils/highest-row (:table-data db)) r) max-col? (= (utils/highest-col (:table-data db)) c) new-col (if max-row? (if max-col? "A" (utils/next-letter c)) c) new-row (if max-row? 1 (inc r))] (println "::press-enter-in-cell" c r) {:focus-on-cell [new-col new-row]}))) (re-frame/reg-fx :focus-on-cell (fn [[c r]] (println "fx for :press-enter" c r) (.focus (.getElementById js/document (str c r)))))