<commit_before>;; Copyright (c) <NAME>. All rights reserved.
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file LICENSE at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.

(ns conexp.graphics.draw
  (:use [conexp.util :only (update-ns-meta!,
			    get-root-cause,
			    with-swing-error-msg,
			    with-printed-result,
			    now)]
	[conexp.base :only (defvar-)]
	[conexp.math.util :only (with-doubles)]
	[conexp.layout :only (*standard-layout-function*)]
	[conexp.layout.base :only (lattice, annotation)]
	[conexp.layout.force :only (force-layout,
				    layout-energy,
				    *repulsive-amount*,
				    *attractive-amount*,
				    *gravitative-amount*)]
	[conexp.graphics.util :only (device-to-world)]
	[conexp.graphics.scenes :only (add-callback-for-hook,
				       redraw-scene,
				       start-interaction,
				       get-zoom-factors,
				       save-image,
				       get-canvas-from-scene,
				       show-labels)]
	[conexp.graphics.scene-layouts :only (draw-on-scene,
					      get-layout-from-scene,
					      update-layout-of-scene,
					      do-nodes)]
	[conexp.graphics.nodes-and-connections :only (move-interaction,
						      zoom-interaction,
						      move-node-by,
						      all-nodes-above,
						      all-nodes-below,
						      all-inf-add-influenced-nodes,
						      all-sup-add-influenced-nodes,
						      *default-node-radius*,
						      set-node-radius!)]
	clojure.contrib.swing-utils)
  (:import [javax.swing JFrame JPanel JButton JTextField JLabel
	                JOptionPane JSeparator SwingConstants
	                BoxLayout Box JScrollBar JComboBox JScrollPane
	                JFileChooser]
	   [javax.swing.filechooser FileNameExtensionFilter]
	   [java.awt Canvas Color Dimension BorderLayout GridLayout Component Graphics]
	   [java.awt.event ActionListener]
	   [java.io File]))

(update-ns-meta! conexp.graphics.draw
  :doc "This namespace provides a lattice editor and a convenience function to draw lattices.")


;;; Lattice Editor

(declare make-button, make-label, make-labeled-text-field,
	 make-padding, make-separator, make-combo-box)


;; editor features

(declare single-move, ideal-move, filter-move, chain-move,
	 infimum-additive-move, supremum-additive-move)

(defn- change-parameters
  "Installs parameter list which influences lattice drawing."
  [frame scn buttons]
  ;; node radius
  (let [#^JTextField node-radius (make-labeled-text-field buttons "radius" (str *default-node-radius*))]
    (add-action-listener node-radius
			 (fn [evt]
			   (let [new-radius (Double/parseDouble (.getText node-radius))]
			     (do-swing
			      (do-nodes [n scn]
					(set-node-radius! n new-radius))
			      (redraw-scene scn))))))
  (make-padding buttons)

  ;; labels
  (let [#^JButton label-toggler (make-button buttons "No Labels")]
    (show-labels scn false)
    (add-action-listener label-toggler
			 (fn [evt]
			   (do-swing
			    (if (= "Labels" (.getText label-toggler))
			      (do
				(show-labels scn false)
				(.setText label-toggler "No Labels"))
			      (do
				(show-labels scn true)
				(.setText label-toggler  "Labels")))
			    (redraw-scene scn)))))

  ;; layouts
  (let [layouts {"standard" *standard-layout-function*},
	#^JComboBox combo-box (make-combo-box buttons (keys layouts))]
    (add-action-listener combo-box
			 (fn [evt]
			   (let [selected (.. evt getSource getSelectedItem),
				 layout-fn (get layouts selected)]
			     (do-swing
			      (update-layout-of-scene
			       scn
			       (layout-fn (lattice (get-layout-from-scene scn)))))))))

  ;; move mode (ideal, filter, chain, single)
  (let [move-modes {"single" single-move,
		    "ideal"  ideal-move,
		    "filter" filter-move,
		    "chain"  chain-move,
		    "inf"    infimum-additive-move,
		    "sup"    supremum-additive-move}
	#^JComboBox combo-box (make-combo-box buttons (keys move-modes)),
	current-move-mode (atom single-move)]
    (add-callback-for-hook scn :move-drag
			   (fn [node dx dy]
			     (@current-move-mode node dx dy)))
    (add-action-listener combo-box
			 (fn [evt]
			   (let [selected (.. evt getSource getSelectedItem),
				 move-mode (get move-modes selected)]
			     (reset! current-move-mode move-mode)))))
  nil)

(defn- single-move
  "Moves the single node only."
  [node dx dy]
  nil)

(defn- neighbor-move-mode
  "Moves nodes neighbored to node by [dx dy]."
  [neighbors node dx dy]
  (do-swing
   (doseq [n (neighbors node)]
     (move-node-by n dx dy))))

(def all-nodes-above* (memoize all-nodes-above))

(defn- ideal-move
  "Moves all nodes below the current node."
  [node dx dy]
  (neighbor-move-mode all-nodes-above* node dx dy))

(def all-nodes-below* (memoize all-nodes-below))

(defn- filter-move
  "Moves all nodes above the current node."
  [node dx dy]
  (neighbor-move-mode all-nodes-below* node dx dy))

(defn- chain-move
  "Combined ideal and filter move mode."
  [node dx dy]
  (ideal-move node dx dy)
  (filter-move node dx dy))

(defn- additive-move
  "Abstract move mode for moving nodes according to additive
  influence."
  [influenced-nodes dx dy]
  (do-swing
   (doseq [[n weight] influenced-nodes]
     (with-doubles [dx dy weight]
       (move-node-by n (* dx weight) (* dy weight))))))

(def all-inf-add-influenced-nodes* all-inf-add-influenced-nodes)

(defn- infimum-additive-move
  "Moves all nodes infimum-additively with node."
  [node dx dy]
  (additive-move (all-inf-add-influenced-nodes* node) dx dy))

(def all-sup-add-influenced-nodes* all-sup-add-influenced-nodes)

(defn- supremum-additive-move
  "Moves all nodes supremum-additively with node."
  [node dx dy]
  (additive-move (all-sup-add-influenced-nodes* node) dx dy))


;; improve with force layout

(defn- improve-with-force
  "Improves layout on scene with force layout."
  [scn iterations r a g]
  (binding [*repulsive-amount* r,
	    *attractive-amount* a,<commit_msg>Removed global memoization from move modes<commit_after>;; Copyright (c) <NAME>. All rights reserved.
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file LICENSE at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.

(ns conexp.graphics.draw
  (:use [conexp.util :only (update-ns-meta!,
			    get-root-cause,
			    with-swing-error-msg,
			    with-printed-result,
			    now)]
	[conexp.base :only (defvar-)]
	[conexp.math.util :only (with-doubles)]
	[conexp.layout :only (*standard-layout-function*)]
	[conexp.layout.base :only (lattice, annotation)]
	[conexp.layout.force :only (force-layout,
				    layout-energy,
				    *repulsive-amount*,
				    *attractive-amount*,
				    *gravitative-amount*)]
	[conexp.graphics.util :only (device-to-world)]
	[conexp.graphics.scenes :only (add-callback-for-hook,
				       redraw-scene,
				       start-interaction,
				       get-zoom-factors,
				       save-image,
				       get-canvas-from-scene,
				       show-labels)]
	[conexp.graphics.scene-layouts :only (draw-on-scene,
					      get-layout-from-scene,
					      update-layout-of-scene,
					      do-nodes)]
	[conexp.graphics.nodes-and-connections :only (move-interaction,
						      zoom-interaction,
						      move-node-by,
						      all-nodes-above,
						      all-nodes-below,
						      all-inf-add-influenced-nodes,
						      all-sup-add-influenced-nodes,
						      *default-node-radius*,
						      set-node-radius!)]
	clojure.contrib.swing-utils)
  (:import [javax.swing JFrame JPanel JButton JTextField JLabel
	                JOptionPane JSeparator SwingConstants
	                BoxLayout Box JScrollBar JComboBox JScrollPane
	                JFileChooser]
	   [javax.swing.filechooser FileNameExtensionFilter]
	   [java.awt Canvas Color Dimension BorderLayout GridLayout Component Graphics]
	   [java.awt.event ActionListener]
	   [java.io File]))

(update-ns-meta! conexp.graphics.draw
  :doc "This namespace provides a lattice editor and a convenience function to draw lattices.")


;;; Lattice Editor

(declare make-button, make-label, make-labeled-text-field,
	 make-padding, make-separator, make-combo-box)


;; editor features

(declare single-move-mode, ideal-move-mode, filter-move-mode, chain-move-mode,
	 infimum-additive-move-mode, supremum-additive-move-mode)

(defn- change-parameters
  "Installs parameter list which influences lattice drawing."
  [frame scn buttons]
  ;; node radius
  (let [#^JTextField node-radius (make-labeled-text-field buttons "radius" (str *default-node-radius*))]
    (add-action-listener node-radius
			 (fn [evt]
			   (let [new-radius (Double/parseDouble (.getText node-radius))]
			     (do-swing
			      (do-nodes [n scn]
					(set-node-radius! n new-radius))
			      (redraw-scene scn))))))
  (make-padding buttons)

  ;; labels
  (let [#^JButton label-toggler (make-button buttons "No Labels")]
    (show-labels scn false)
    (add-action-listener label-toggler
			 (fn [evt]
			   (do-swing
			    (if (= "Labels" (.getText label-toggler))
			      (do
				(show-labels scn false)
				(.setText label-toggler "No Labels"))
			      (do
				(show-labels scn true)
				(.setText label-toggler  "Labels")))
			    (redraw-scene scn)))))

  ;; layouts
  (let [layouts {"standard" *standard-layout-function*},
	#^JComboBox combo-box (make-combo-box buttons (keys layouts))]
    (add-action-listener combo-box
			 (fn [evt]
			   (let [selected (.. evt getSource getSelectedItem),
				 layout-fn (get layouts selected)]
			     (do-swing
			      (update-layout-of-scene
			       scn
			       (layout-fn (lattice (get-layout-from-scene scn)))))))))

  ;; move mode (ideal, filter, chain, single)
  (let [move-modes {"single" (single-move-mode),
		    "ideal"  (ideal-move-mode),
		    "filter" (filter-move-mode),
		    "chain"  (chain-move-mode),
		    "inf"    (infimum-additive-move-mode),
		    "sup"    (supremum-additive-move-mode)}
	#^JComboBox combo-box (make-combo-box buttons (keys move-modes)),
	current-move-mode (atom (move-modes "single"))]
    (add-callback-for-hook scn :move-drag
			   (fn [node dx dy]
			     (@current-move-mode node dx dy)))
    (add-action-listener combo-box
			 (fn [evt]
			   (let [selected (.. evt getSource getSelectedItem),
				 move-mode (get move-modes selected)]
			     (reset! current-move-mode move-mode)))))
  nil)

(defn- single-move-mode
  "Moves the single node only."
  []
  (fn [node dx dy]
    nil))

(defn- neighbor-move-mode
  "Moves nodes neighbored to node by [dx dy]."
  [neighbors]
  (fn [node dx dy]
    (do-swing
     (doseq [n (neighbors node)]
       (move-node-by n dx dy)))))

(defn- ideal-move-mode
  "Moves all nodes below the current node."
  []
  (neighbor-move-mode (memoize all-nodes-above)))

(defn- filter-move-mode
  "Moves all nodes above the current node."
  []
  (neighbor-move-mode (memoize all-nodes-below)))

(defn- chain-move-mode
  "Combined ideal and filter move mode."
  []
  (let [ideal (ideal-move),
	filter (filter-move)]
    (fn [node dx dy]
      (ideal node dx dy)
      (filter node dx dy))))

(defn- additive-move-mode
  "Abstract move mode for moving nodes according to additive
  influence."
  [influenced-nodes]
  (fn [node dx dy]
    (do-swing
     (doseq [[n weight] (influenced-nodes node)]
       (with-doubles [dx dy weight]
	 (move-node-by n (* dx weight) (* dy weight)))))))

(defn- infimum-additive-move-mode
  "Moves all nodes infimum-additively with node."
  []
  (additive-move (memoize all-inf-add-influenced-nodes)))

(defn- supremum-additive-move-mode
  "Moves all nodes supremum-additively with node."
  []
  (additive-move (memoize all-sup-add-influenced-nodes)))


;; improve with force layout

(defn- improve-with-force
  "Improves layout on scene with force layout."
  [scn iterations r a g]
  (binding [*repulsive-amount* r,
	    *attractive-amount* a,
{'fraction_non_alphanumeric': 0.132564373324669, 'fraction_numerical': 0.0006498253594346519, 'mean_word_length': 2.8271681691016477, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5602577', 'n_tokens_mistral': 4603, 'n_tokens_neox': 4007, 'n_words': 1074}