Skip to content

Instantly share code, notes, and snippets.

@odyssomay
Created October 25, 2012 21:36
Show Gist options
  • Save odyssomay/3955592 to your computer and use it in GitHub Desktop.
Save odyssomay/3955592 to your computer and use it in GitHub Desktop.
jQuery Split pane
(ns ui.split
(:require [ui.trigger :as trigger]
[jayq.util :as util])
(:use [jayq.core :only [$ append css inner]]))
(defn set-css [outer f-elem s-elem options]
(let [{:keys [split-type start-position]} options
base-css (case split-type
:vertical {:width "100%"}
:horizontal {:float "left" :height "100%"})
border-key (case split-type
:vertical :border-bottom
:horizontal :border-right)
]
(css outer {:height "100%" :width "100%" :overflow "hidden"})
(css f-elem (merge base-css
{(case split-type :vertical :height :horizontal :width)
start-position
:position "relative"
border-key "5px solid #EEE"}))
(css s-elem (merge base-css
{:position "relative"}))))
(defn append-all [outer f-elem s-elem f s]
(append outer f-elem) (append outer s-elem)
(append f-elem f) (append s-elem s))
(defn get-set-val-fn [type]
(case type
:width (fn ([o] (.width o)) ([o v] (.width o v)))
:height (fn ([o] (.height o)) ([o v] (.height o v)))))
(defn create-start-fn [start-value outer split-type]
(let [get-val (get-set-val-fn (case split-type
:vertical :height
:horizontal :width))]
(fn [] (reset! start-value (get-val outer)))))
(defn create-resize-fn [start-value f-elem s-elem split-type]
(let [get-f-elem-val (case split-type
:vertical #(.outerHeight f-elem)
:horizontal #(.outerWidth f-elem))
set-val (get-set-val-fn (case split-type
:vertical :height
:horizontal :width))]
(fn [] (set-val s-elem (- @start-value (get-f-elem-val))))))
(defn create-resize-outer-fn [outer f-elem s-elem split-type]
(let [get-set-val (get-set-val-fn (case split-type
:vertical :width
:horizontal :height))]
(fn [] (let [v (get-set-val outer)]
(get-set-val f-elem v)
(get-set-val s-elem v)))))
(defn set-resizable [f-elem s-elem on-start on-resize options]
(let [{[min-first min-second] :min-sizes :keys [split-type]} options
handles (case split-type
:vertical "s"
:horizontal "e")
]
(.resizable f-elem (util/clj->js {:handles handles
:start on-start
:resize on-resize
(case split-type
:vertical :minHeight
:horizontal :minWidth)
min-first
}))
))
(defn split [views & {:as options}]
(let [[f s] views
{:keys [split-type]} options
outer ($ "<div>")
f-elem ($ "<div>")
s-elem ($ "<div>")
]
(set-css outer f-elem s-elem options)
(append-all outer f-elem s-elem f s)
(let [start-value (atom nil)
start-fn (create-start-fn start-value outer split-type)
resize-fn (create-resize-fn start-value f-elem s-elem split-type)
resize-outer-fn (create-resize-outer-fn outer f-elem s-elem split-type)
trigger-fn (fn [] (start-fn) (resize-fn) (resize-outer-fn))
]
(set-resizable f-elem s-elem start-fn (fn [] (resize-fn) (.rresize f-elem)
(.rresize s-elem))
options)
(.resize ($ js/window) trigger-fn)
(.resize outer trigger-fn)
(trigger/add-trigger trigger-fn)
outer)))
(ns ui.trigger)
(def triggers (atom ()))
(defn add-trigger [trigger]
(swap! triggers conj trigger))
(defn fire []
(doseq [t @triggers]
(t)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment