Browse Source

continuing work on control panel; fixed error in cell eval function

Brandon Wong 3 years ago
parent
commit
b8ffc6fe30

+ 31 - 7
frontend/resources/public/site.css

@@ -1,13 +1,11 @@
 body {
   font-family: 'Helvetica Neue', Verdana, Helvetica, Arial, sans-serif;
   max-width: 600px;
-  margin: 0 auto;
-  padding-top: 72px;
+  margin: 0;
   -webkit-font-smoothing: antialiased;
   font-size: 1.125em;
   color: #333;
   line-height: 1.5em;
-  overflow: hidden;
 }
 
 h1, h2, h3 {
@@ -35,9 +33,9 @@ a:hover {
 }
 
 #main-table {
-    position: fixed;
+    /*position: fixed;
     top: 0;
-    left: 0;
+    left: 0;*/
 }
 
 table {
@@ -94,21 +92,34 @@ td input:not(:focus) {
     font-size: xxx-large;
     font-weight: bold;
     text-align: center;
+    border: 1px solid black;
 }
 #main-logo > img {
     width: 100%;
     height:100%;
 }
+#left-controls-button, #bottom-controls-button {
+    border: 1px solid black;
+    border-radius: 2px;
+    text-align: center;
+    font-weight: bold;
+    font-size: xx-large;
+    background-color: white;
+    cursor: pointer;
+    user-select: none;
+}
 #left-controls-button {
     left: 0;
-    width: calc(var(--controls-width) + 2 * var(--controls-padding));
+    width: calc(var(--controls-width) + 2 * var(--controls-padding) - 2px);
     height: var(--controls-opener-width);
     z-index: 999;
     bottom: calc(var(--controls-width) + 2 * var(--controls-padding));
+    line-height: 3px;
+    text-align: right;
 }
 #bottom-controls-button {
     bottom: 0;
-    height: calc(var(--controls-width) + 2 * var(--controls-padding));
+    height: calc(var(--controls-width) + 2 * var(--controls-padding) - 2px);
     width: var(--controls-opener-width);
     z-index: 999;
     left: calc(var(--controls-width) + 2 * var(--controls-padding));
@@ -121,6 +132,7 @@ td input:not(:focus) {
     padding: 5px;
     height: calc(100vh - var(--controls-padding));
     width: var(--controls-width);
+    border-right: 1px solid black;
 }
 /*TODO: link left controls with position of the whole table*/
 #controls-left.open {
@@ -135,11 +147,23 @@ td input:not(:focus) {
     padding: var(--controls-padding);
     padding-left: calc(var(--controls-width) + 3 * var(--controls-padding) + var(--controls-opener-width));
     width: calc(100vw - var(--controls-width) - 4 * var(--controls-padding) - var(--controls-opener-width));
+    border-top: 1px solid black;
 }
 #controls-bottom.open {
     bottom: 0;
 }
 
+
+.control-group {
+    float: left;
+    margin: 5px;
+    background-color: lightgreen;
+}
+.control-label {
+    font-size: x-small;
+}
+
+
 .smartborder {
     width: calc(100% + 2px);
     height: calc(100% + 2px);

+ 20 - 13
frontend/src/cljs/microtables_frontend/utils.cljs

@@ -47,19 +47,26 @@
 
 ; the order goes top to bottom, then left to right - that makes the most sense to me
 ; I don't know why a different order would be important, or even in what situation order is important at all
-(def parse-range
+(defn parse-range
+  "Converts a range in \"A1:B2\" notation to a comma-separated list of cells: \"A1,A2,B1,B2\"."
+  [range-string]
+  (let [col1 (second (re-find #"\(\s*([A-Z]+)" range-string))
+        col2 (second (re-find #":\s*([A-Z]+)" range-string))
+        row1 (.parseInt js/window (second (re-find #"([0-9]+)\s*:" range-string)))
+        row2 (.parseInt js/window (second (re-find #"([0-9]+)\s*\)" range-string)))
+        [start-col end-col] (order-two-cols col1 col2)
+        start-row (min row1 row2)
+        end-row (max row1 row2)]
+    (for [col (take-while #(not= (next-letter end-col) %) (iterate next-letter start-col))
+             row (range start-row (inc end-row))]
+         {:col col :row row})))
+
+(def range->commalist
   "Converts a range in \"A1:B2\" notation to a comma-separated list of cells: \"A1,A2,B1,B2\"."
   (memoize (fn [range-string]
-             (let [col1 (second (re-find #"\(\s*([A-Z]+)" range-string))
-                   col2 (second (re-find #":\s*([A-Z]+)" range-string))
-                   row1 (.parseInt js/window (second (re-find #"([0-9]+)\s*:" range-string)))
-                   row2 (.parseInt js/window (second (re-find #"([0-9]+)\s*\)" range-string)))
-                   [start-col end-col] (order-two-cols col1 col2)
-                   start-row (min row1 row2)
-                   end-row (max row1 row2)]
-               (str "(" (clojure.string/join "," (for [col (take-while #(not= (next-letter end-col) %) (iterate next-letter start-col))
-                                                       row (range start-row (inc end-row))]
-                                                  (str col row))) ")")))))
+            (let [cell-list (parse-range range-string)
+                  strings (map #(str (:col %) (:row %)) cell-list)]
+             (str "(" (clojure.string/join "," strings) ")")))))
 
 (def replace-ranges-in-expression
   "Receives an expression string, and replaces all ranges in colon notation (\"A1:B2\") into a comma-separated list of cells (\"A1,A2,B1,B2\")."
@@ -161,7 +168,7 @@
   "Assuming all references have been added, insert all back references."
   [data]
   (loop [data data
-         formulas (walk-get-refs data formula?)]
+         formulas (walk-get-refs data #(formula? (:value %3)))]
     (if (empty? formulas)
       data
       (let [origin (first formulas)
@@ -274,7 +281,7 @@
         cycle-refs (some #(= (:display %) :cycle-error) resolved-refs)
         disqualified? (or invalid-refs dirty-refs error-refs)]
     (cond
-      formula (assoc-in data [c r] datum)           ; if it's not a formula, then return as is (with the dirty flag removed)
+      (not formula) (assoc-in data [c r] datum)     ; if it's not a formula, then return as is (with the dirty flag removed)
       cycle-refs (-> data                           ; if one of its references has a reference cycle, then this one is "poisoned" as well
                      (assoc-in [c r] datum)
                      (assoc-in [c r :display] :cycle-error))

+ 22 - 7
frontend/src/cljs/microtables_frontend/views.cljs

@@ -40,24 +40,39 @@
     ;TODO: figure out appropriate starting values for maxrow and maxcol (maybe keep them intentionally small)
     ;TODO: figure out movement (maybe allow scroll overflow)
     (let [maxrow 50;(utils/highest-row data)
-          maxcol "L";(utils/highest-col data)
+          maxcol "Z";(utils/highest-col data)
           cols (take-while (partial not= (utils/next-letter maxcol)) utils/col-letters)]
       (cons
         (header-row cols)
         (map #(row % cols data) (range 1 (inc maxrow)))))]])
 
+
+(defn extend-range
+  []
+  [:div {:class "control-group"}
+   [:div {:class "control-label"}
+    "Extend Range"]
+   [:button "-cols"]
+   [:input]
+   [:button]])
+
 (defn controls []
   [:div
-   [:button "one"]
+   ;[extend-range]
    ;extend range (number field, then shrink/left/up and expand/right/down buttons on either side)
    ;fill range (single tap, single column/row fill? number field and button?)
    ;move range (designate new "top-left corner" cell for range, figure out overwriting destination cells)
    ;empty range (delete contents, re-evaluate)
    ;delete range (figure out how to move cells over)
    ;copy range (figure out clipboard)
-   [:button "two"]])
+   [:div
+    {:class "control-group"}
+    [:a ;TODO: consider making the "About" info an overlay rather than a link
+     {:href "/about.html"
+      :target "_blank"}
+     "About"]]])
 
-(defn controls-group [state]
+(defn control-panel [state]
   [:div
    {:id "controls"}
    [:div
@@ -70,11 +85,11 @@
      :class (if (= state :bottom) "open" "")}
     [controls]]
    ;←↑→↓
-   [:button
+   [:div
     {:id "left-controls-button"
      :on-click #(re-frame/dispatch [::events/set-controls-state (if (= state :left) nil :left)])}
     (if (= state :left) "←" "→")]
-   [:button
+   [:div
     {:id "bottom-controls-button"
      :on-click #(re-frame/dispatch [::events/set-controls-state (if (= state :bottom) nil :bottom)])}
     (if (= state :bottom) "↓" "↑")]
@@ -88,6 +103,6 @@
         controls-state (re-frame/subscribe [::subs/controls-state])]
     [:div
      [sheet @data]
-     [controls-group @controls-state]]))
+     [control-panel @controls-state]]))