From 5d286f98d7b9d6bba4b085cca3cd73cd4c40967e Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Sat, 15 Jun 2019 13:42:11 +0100 Subject: [PATCH] Added files --- .gitignore | 17 +++--- CHANGELOG.md | 24 +++++++++ README.md | 30 +++++++++++ doc/intro.md | 3 ++ project.clj | 10 ++++ src/swingbox_clj/core.clj | 91 +++++++++++++++++++++++++++++++++ test/swingbox_clj/core_test.clj | 7 +++ 7 files changed, 172 insertions(+), 10 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 doc/intro.md create mode 100644 project.clj create mode 100644 src/swingbox_clj/core.clj create mode 100644 test/swingbox_clj/core_test.clj diff --git a/.gitignore b/.gitignore index a4cb69a..c53038e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,11 @@ +/target +/classes +/checkouts pom.xml pom.xml.asc *.jar *.class -/lib/ -/classes/ -/target/ -/checkouts/ -.lein-deps-sum -.lein-repl-history -.lein-plugins/ -.lein-failures -.nrepl-port -.cpcache/ +/.lein-* +/.nrepl-port +.hgignore +.hg/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3300fa7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +# Change Log +All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). + +## [Unreleased] +### Changed +- Add a new arity to `make-widget-async` to provide a different widget shape. + +## [0.1.1] - 2019-06-15 +### Changed +- Documentation on how to make the widgets. + +### Removed +- `make-widget-sync` - we're all async, all the time. + +### Fixed +- Fixed widget maker to keep working when daylight savings switches over. + +## 0.1.0 - 2019-06-15 +### Added +- Files from the new template. +- Widget maker public API - `make-widget-sync`. + +[Unreleased]: https://github.com/your-name/swingbox-clj/compare/0.1.1...HEAD +[0.1.1]: https://github.com/your-name/swingbox-clj/compare/0.1.0...0.1.1 diff --git a/README.md b/README.md new file mode 100644 index 0000000..70d8ff4 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# swingbox-clj + +A Clojure library designed to allow opening HTML windows from Clojure. + +## Rationale + +It's pretty hard to visualise data or create desktop UI components for Clojure applications. This is part of an exploration to see whether an HTML component can help. + +There is a supposedly open source Java wrapper for chromium, [java-cef](https://bitbucket.org/chromiumembedded/java-cef/src/master/), but it doesn't build (for me, following [the instructions](https://bitbucket.org/chromiumembedded/java-cef/wiki/BranchesAndBuilding.md), although it does appear to be under current development); There's another that's commercial, [jxbrowser](https://www.teamdev.com/jxbrowser) but it isn't useful when trying to develop open source components. [SwingBox](https://mvnrepository.com/artifact/net.sf.cssbox/swingbox/1.0) is pure Java and open source so I thought it worth playing with. + +This is simple and within limitations works. The browser isn't live (at least not at this stage), clicking links does not work and does not reload pages. Also, JavaScript is not interpreted. + +## Usage + +```clojure +(show-in-window "From a string" "Hello") + +(show-in-window "From the tinkerweb" "https://www.journeyman.cc/~simon/") + +(show-in-window "From Hiccup" [:html [:head [:title "Test from Hiccup"]][:body [:h1 "Excuse me"] [:p "This is hiccup"]]]) + +(set-visible (set-content-markdown (create-window "From a Markdown file") "README.md")) +``` + +## License + +Copyright © 2019 FIXME + +Distributed under the GNU Lesser General Public Licence 3.0 or (at +your option) any later version, following the license of SwingBox. diff --git a/doc/intro.md b/doc/intro.md new file mode 100644 index 0000000..0f67068 --- /dev/null +++ b/doc/intro.md @@ -0,0 +1,3 @@ +# Introduction to swingbox-clj + +TODO: write [great documentation](http://jacobian.org/writing/what-to-write/) diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..30d2c68 --- /dev/null +++ b/project.clj @@ -0,0 +1,10 @@ +(defproject swingbox-clj "0.1.0-SNAPSHOT" + :description "FIXME: write description" + :url "http://example.com/FIXME" + :license {:name "Eclipse Public License" + :url "http://www.eclipse.org/legal/epl-v10.html"} + :dependencies [[org.clojure/clojure "1.8.0"] + [hiccup "1.0.5"] + [markdown-clj "0.9.99" :exclusions [com.keminglabs/cljx]] + [net.sf.cssbox/swingbox "1.0"] + ]) diff --git a/src/swingbox_clj/core.clj b/src/swingbox_clj/core.clj new file mode 100644 index 0000000..9dfd358 --- /dev/null +++ b/src/swingbox_clj/core.clj @@ -0,0 +1,91 @@ +(ns swingbox-clj.core + (:import java.awt.GraphicsConfiguration + java.io.File + java.net.URI + javax.swing.JFrame + org.fit.cssbox.swingbox.BrowserPane) + (:require [hiccup.core :refer [html]] + [markdown.core :as md] + )) + +(defn window? + "True if `x` is a window within the meaning used in this file, i.e. + it is a map containing at least the keys `:frame` and `:browser`. such that + * The value of `:frame` shall be a top-level JFrame. + * The value of `:browser` shall be a BrowserPane." + [x] + (and + (map? x) + (instance? javax.swing.JFrame (:frame x)) + (instance? org.fit.cssbox.swingbox.BrowserPane (:browser x)))) + +(defn create-window + "Create (but do not show) a top level JFrame window, with this `title` if + supplied. The created window will contain a browser pane. Returns a map + containing two keys, `:frame` and `:browser`." + ([] (create-window nil)) + ([title] + (let [frame (JFrame. (if title (str title) "Untitled Window")) + browser (BrowserPane.)] + (.setText browser "") ;; window won't open if content is not added to the + ;; browser before the browser is added to the frame. + ;; you can change the content later. + (.add frame browser) + (.pack frame) + {:frame frame + :browser browser}))) + +(defn set-content + "Set the content of the browser in this `window` to this `content,` which may + be + * a URL or string representation of a URL + * a file (java.io.File) + * a [hiccup]() structure representing HTML + * literally anything else. + Returns the `window`." + [window content] + (if (window? window) + (let [browser (:browser window) + url (try (.toURL (URI/create (str content))) (catch Exception _ nil)) + html (try (html content) (catch Exception _ nil))] + (cond + url + (.setPage browser url) + html + (.setText browser html) + :else + (case (type content) + java.lang.String (.setText browser content) + clojure.lang.PersistentVector (.setText browser (html content)) + java.io.File (.setPage browser (.toURL content)) + (.setText browser (str content)))) + window))) + +(defn set-content-markdown + "Set the content of this `window` to the markdown read from this `filename`. + Return the `window`." + [window filename] + (set-content window (md/md-to-html-string (slurp filename))) + window) + +(defn set-visible + "Set this `window` to be visible if `visible?` is `true` or not supplied; + else false. Returns the `window`." + ([window] + (set-visible window true)) + ([window visible?] + (if + (window? window) + (.setVisible + (:frame window) + (true? visible?))) + window)) + +(defn show-in-window + "Show this `content`, in a window with this `title`. Return the window as + discussed above." + [title content] + (set-visible (set-content (create-window title) content))) + + + diff --git a/test/swingbox_clj/core_test.clj b/test/swingbox_clj/core_test.clj new file mode 100644 index 0000000..9c1f922 --- /dev/null +++ b/test/swingbox_clj/core_test.clj @@ -0,0 +1,7 @@ +(ns swingbox-clj.core-test + (:require [clojure.test :refer :all] + [swingbox-clj.core :refer :all])) + +(deftest a-test + (testing "FIXME, I fail." + (is (= 0 1))))