diff --git a/src/anabapa_list/data.cljd b/src/anabapa_list/data.cljd index 00e3eee..1ba3ec4 100644 --- a/src/anabapa_list/data.cljd +++ b/src/anabapa_list/data.cljd @@ -526,4 +526,6 @@ (group-by #(str (first %))) (map (fn [[k v]] (map-indexed (fn [idx itm] {:name itm :idx idx :tag (str (first itm))}) v))) (flatten) - (sort-by (juxt :tag :name)))) \ No newline at end of file + (sort-by (juxt :tag :name)) + (map-indexed (fn [idx itm] (assoc itm :index idx))) + )) \ No newline at end of file diff --git a/src/anabapa_list/index_bar.cljd b/src/anabapa_list/index_bar.cljd index bc2c682..dfe0573 100644 --- a/src/anabapa_list/index_bar.cljd +++ b/src/anabapa_list/index_bar.cljd @@ -2,6 +2,7 @@ (:require ["package:flutter/material.dart" :as m] ["package:flutter/rendering.dart" :as render] + ["package:flutter/services.dart" :as services] ["package:mongol/mongol.dart" :as mgl] [cljd.flutter.alpha2 :as f])) @@ -39,51 +40,95 @@ (def index-bar-width 30) (def index-bar-item-height 16) -;; (defn ^render/RenderBox get-render-box [ctx] -;; (let [^render/RenderBox render-object (.findRenderObject ctx)] -;; (if (nil? render-object) -;; nil -;; render-object))) - (defn index-bar-content [] - (.generate - List - (count index-bar-data) - (fn [i] - (m/SizedBox - .width index-bar-width - .height index-bar-item-height - .child - (m/Center - .child - (m/Text - (nth index-bar-data i) - .style (m/TextStyle .fontSize 12 .color (m/Color 0xFF666666)))))))) + (f/widget + :get [:state] + :let [selected-decoration (m/BoxDecoration .shape (.circle m/BoxShape) .color (.blueAccent m/Colors)) + selected-style (m/TextStyle .fontSize 12 .color (.white m/Colors)) + style (m/TextStyle .fontSize 12 .color (m/Color 0xFF666666))] + :watch [{:keys [tag]} state] + (m/Column + .mainAxisSize (.min m/MainAxisSize) + .children + (.generate + List + (count index-bar-data) + (fn [i] + (m/SizedBox + .width index-bar-width + .height index-bar-item-height + .child + ;; (m/Center + ;; .child + ;; (m/Text + ;; (nth index-bar-data i) + ;; .style (m/TextStyle .fontSize 12 .color (m/Color 0xFF666666)))) + (m/Container + .alignment (.center m/Alignment) + .decoration (if (= tag (nth index-bar-data i)) selected-decoration) + .child (m/Text + (nth index-bar-data i) + .style (if (= tag (nth index-bar-data i)) + selected-style + style))))))))) + +(declare drag-down-position + drag-update-position + trigger-event) (defn index-bar [] (f/widget :context ctx + :get [:item-num :item-position-listner + :state :item-scroll-controller + :items] ;; (m/Container .alignment (.centerRight m/Alignment)) ;; .child (m/GestureDetector .onVerticalDragDown (fn [^m/DragDownDetails details] - (dart:core/print "on vertical drag down")) + ;; (dart:core/print "on vertical drag down") + (let [i (drag-down-position details)] + (trigger-event :action-down i item-scroll-controller items))) + .onVerticalDragUpdate (fn [^m/DragUpdateDetails details] - (dart:core/print ".onVerticalDragUpdate")) + ;; (dart:core/print ".onVerticalDragUpdate") + (let [i (drag-update-position details)] + (trigger-event :action-update i item-scroll-controller items))) + .onVerticalDragEnd (fn [^m/DragEndDetails details] (dart:core/print ".onVerticalDragEnd")) .onVerticalDragCancel - (fn [] + (fn [] (dart:core/print ".onVerticalDragCancel")) - .onTapUp - (fn [^m/TapUpDetails details] - (dart:core/print ".onTapUp")) + ;; .onTapUp + ;; (fn [^m/TapUpDetails details] + ;; (dart:core/print ".onTapUp")) .behavior (.translucent m/HitTestBehavior)) - .child - (m/Column - .mainAxisSize (.min m/MainAxisSize) - .children - (index-bar-content)))) \ No newline at end of file + .child (index-bar-content))) + +(defn get-scroll-index-by-tag [tag items] + (->> items + (filter #(and (zero? (:idx %)) + (= tag (:tag %)))) + last + :index)) + +(defn trigger-event [type bar-index scroll-controller items] + ;; (if (some #{type} [:action-down :action-update]) + ;; (.vibrate services/HapticFeedback)) + (let [tag (nth index-bar-data bar-index) + i (get-scroll-index-by-tag tag items)] + ;; (dart:core/print (str "tag = " tag)) + ;; (dart:core/print (str "index = " i)) + (.jumpTo scroll-controller .index (int i)))) + +(defn drag-down-position [^m/DragDownDetails details] + (let [widget-index (quot (-> details .-localPosition .-dy) 16)] + (min widget-index (dec (count index-bar-data))))) + +(defn drag-update-position [^m/DragUpdateDetails details] + (let [widget-index (quot (-> details .-localPosition .-dy) 16)] + (min widget-index (dec (count index-bar-data))))) \ No newline at end of file diff --git a/src/anabapa_list/indexed_list.cljd b/src/anabapa_list/indexed_list.cljd index 6358b82..eeccb3d 100644 --- a/src/anabapa_list/indexed_list.cljd +++ b/src/anabapa_list/indexed_list.cljd @@ -1,7 +1,7 @@ (ns anabapa-list.indexed-list (:require ["package:flutter/material.dart" :as m] - ["package:scrollable_positioned_list/scrollable_positioned_list.dart" :as scroll-list] + ["package:scrollable_positioned_list/scrollable_positioned_list.dart" :as scroll-list :refer [ItemPosition]] ["package:mongol/mongol.dart" :as mgl] [anabapa-list.index-bar :as index-bar] [anabapa-list.data :as sample-data] @@ -27,6 +27,31 @@ (m/ListTile .title (m/Text (:name item)))]) (m/ListTile .title (m/Text (:name item)))))) +(defn positions-changed + [^scroll-list/ItemPositionsListener + item-position-listner + state + items] + (let [^Iterable + positions + (-> item-position-listner + .-itemPositions + .-value)] + (when (.-isNotEmpty positions) + (let [^ItemPosition item-position + (-> positions + (.where (fn [^ItemPosition position] (> (.-itemTrailingEdge position) 0))) + (.reduce + (fn [^ItemPosition min ^ItemPosition position] + (if (< (.-itemTrailingEdge position) (.-itemTrailingEdge min)) + position + min)))) + i (.-index item-position) + tag-temp (-> items (nth i) :tag)] + (when (not= (:tag @state) tag-temp) + (dart:core/print tag-temp) + (swap! state assoc :tag tag-temp)))))) + (defn indexed-list [] (let [items (sample-data/convert-list)] ;; (dart:core/print (str "aaaaa" (count items))) @@ -35,7 +60,17 @@ (f/widget :context ctx :let [item-scroll-controller (scroll-list/ItemScrollController) - item-position-listener (.create scroll-list/ItemPositionsListener)] + item-position-listener (.create scroll-list/ItemPositionsListener) + state (atom {:tag "A"}) + _ (-> item-position-listener + .-itemPositions + (.addListener + #(positions-changed item-position-listener state items)))] + :bind {:item-num (count items) + :item-scroll-controller item-scroll-controller + :item-position-listener item-position-listener + :items items + :state state} (m/Container .width (-> m/MediaQuery (.of ctx) .-size .-width)) .child diff --git a/src/anabapa_list/main.cljd b/src/anabapa_list/main.cljd index 366131a..7a4ff50 100644 --- a/src/anabapa_list/main.cljd +++ b/src/anabapa_list/main.cljd @@ -5,7 +5,6 @@ [cljd.flutter.alpha2 :as f] [anabapa-list.indexed-list :as indexed-list])) -;; (.vibrate m/HapticFeedback) (defn main [] (m/runApp (m/MaterialApp