@@ -112,6 +112,234 @@ fun Modifier.enhancedZoom(
112112 inspectorInfo = {
113113 name = " enhancedZoom"
114114 // add name and value of each argument
115+ properties[" key" ] = key
116+ properties[" consume" ] = consume
117+ properties[" clip" ] = clip
118+ properties[" onDown" ] = onGestureStart
119+ properties[" onMove" ] = onGesture
120+ properties[" onUp" ] = onGestureEnd
121+ }
122+ )
123+
124+
125+ /* *
126+ * Modifier that zooms in or out of Composable set to. This zoom modifier has option
127+ * to move back to bounds with an animation or option to have fling gesture when user removes
128+ * from screen while velocity is higher than threshold to have smooth touch effect.
129+ *
130+ * [key1], [key2] are used for [Modifier.pointerInput] to restart closure when any keys assigned
131+ * change
132+ * @param consume flag to prevent other gestures such as scroll, drag or transform to get
133+ * @param clip when set to true clips to parent bounds. Anything outside parent bounds is not
134+ * drawn
135+ * empty space on sides or edges of parent.
136+ * @param enhancedZoomState State of the zoom that contains option to set initial, min, max zoom,
137+ * enabling rotation, pan or zoom and contains current [ZoomData]
138+ * event propagations
139+ * @param onGestureStart callback to to notify gesture has started and return current
140+ * [EnhancedZoomData] of this modifier
141+ * @param onGesture callback to notify about ongoing gesture and return current
142+ * [EnhancedZoomData] of this modifier
143+ * @param onGestureEnd callback to notify that gesture finished return current
144+ * [EnhancedZoomData] of this modifier
145+ */
146+ fun Modifier.enhancedZoom (
147+ key1 : Any? ,
148+ key2 : Any? ,
149+ consume : Boolean = true,
150+ clip : Boolean = true,
151+ enhancedZoomState : EnhancedZoomState ,
152+ onGestureStart : ((EnhancedZoomData ) -> Unit )? = null,
153+ onGesture : ((EnhancedZoomData ) -> Unit )? = null,
154+ onGestureEnd : ((EnhancedZoomData ) -> Unit )? = null,
155+ ) = composed(
156+
157+ factory = {
158+
159+ val coroutineScope = rememberCoroutineScope()
160+
161+ val boundPan = enhancedZoomState.limitPan && ! enhancedZoomState.rotationEnabled
162+ val clipToBounds = (clip || boundPan)
163+
164+ val transformModifier = Modifier .pointerInput(key1,key2) {
165+ // Pass size of this Composable this Modifier is attached for constraining operations
166+ // inside this bounds
167+ enhancedZoomState.size = this .size
168+ detectTransformGestures(
169+ consume = consume,
170+ onGestureStart = {
171+ onGestureStart?.invoke(enhancedZoomState.enhancedZoomData)
172+ },
173+ onGestureEnd = {
174+ coroutineScope.launch {
175+ enhancedZoomState.onGestureEnd {
176+ onGestureEnd?.invoke(enhancedZoomState.enhancedZoomData)
177+ }
178+ }
179+ },
180+ onGesture = { centroid, pan, zoom, rotate, mainPointer, pointerList ->
181+
182+ coroutineScope.launch {
183+ enhancedZoomState.onGesture(
184+ centroid = centroid,
185+ pan = pan,
186+ zoom = zoom,
187+ rotation = rotate,
188+ mainPointer = mainPointer,
189+ changes = pointerList
190+ )
191+ }
192+
193+ onGesture?.invoke(enhancedZoomState.enhancedZoomData)
194+ }
195+ )
196+ }
197+
198+ val tapModifier = Modifier .pointerInput(key1,key2) {
199+ // Pass size of this Composable this Modifier is attached for constraining operations
200+ // inside this bounds
201+ enhancedZoomState.size = this .size
202+ detectTapGestures(
203+ onDoubleTap = {
204+ coroutineScope.launch {
205+ enhancedZoomState.onDoubleTap {
206+ onGestureEnd?.invoke(enhancedZoomState.enhancedZoomData)
207+ }
208+ }
209+ }
210+ )
211+ }
212+
213+ val graphicsModifier = Modifier .graphicsLayer {
214+ this .update(enhancedZoomState)
215+ }
216+
217+ this .then(
218+ (if (clipToBounds) Modifier .clipToBounds() else Modifier )
219+ .then(tapModifier)
220+ .then(transformModifier)
221+ .then(graphicsModifier)
222+ )
223+ },
224+ inspectorInfo = {
225+ name = " enhancedZoom"
226+ // add name and value of each argument
227+ properties[" key1" ] = key1
228+ properties[" key2" ] = key2
229+ properties[" consume" ] = consume
230+ properties[" clip" ] = clip
231+ properties[" onDown" ] = onGestureStart
232+ properties[" onMove" ] = onGesture
233+ properties[" onUp" ] = onGestureEnd
234+ }
235+ )
236+
237+
238+
239+ /* *
240+ * Modifier that zooms in or out of Composable set to. This zoom modifier has option
241+ * to move back to bounds with an animation or option to have fling gesture when user removes
242+ * from screen while velocity is higher than threshold to have smooth touch effect.
243+ *
244+ * @param keys are used for [Modifier.pointerInput] to restart closure when any keys assigned
245+ * change
246+ * @param consume flag to prevent other gestures such as scroll, drag or transform to get
247+ * @param clip when set to true clips to parent bounds. Anything outside parent bounds is not
248+ * drawn
249+ * empty space on sides or edges of parent.
250+ * @param enhancedZoomState State of the zoom that contains option to set initial, min, max zoom,
251+ * enabling rotation, pan or zoom and contains current [ZoomData]
252+ * event propagations
253+ * @param onGestureStart callback to to notify gesture has started and return current
254+ * [EnhancedZoomData] of this modifier
255+ * @param onGesture callback to notify about ongoing gesture and return current
256+ * [EnhancedZoomData] of this modifier
257+ * @param onGestureEnd callback to notify that gesture finished return current
258+ * [EnhancedZoomData] of this modifier
259+ */
260+ fun Modifier.enhancedZoom (
261+ vararg keys : Any? ,
262+ consume : Boolean = true,
263+ clip : Boolean = true,
264+ enhancedZoomState : EnhancedZoomState ,
265+ onGestureStart : ((EnhancedZoomData ) -> Unit )? = null,
266+ onGesture : ((EnhancedZoomData ) -> Unit )? = null,
267+ onGestureEnd : ((EnhancedZoomData ) -> Unit )? = null,
268+ ) = composed(
269+
270+ factory = {
271+
272+ val coroutineScope = rememberCoroutineScope()
273+
274+ val boundPan = enhancedZoomState.limitPan && ! enhancedZoomState.rotationEnabled
275+ val clipToBounds = (clip || boundPan)
276+
277+ val transformModifier = Modifier .pointerInput(keys) {
278+ // Pass size of this Composable this Modifier is attached for constraining operations
279+ // inside this bounds
280+ enhancedZoomState.size = this .size
281+ detectTransformGestures(
282+ consume = consume,
283+ onGestureStart = {
284+ onGestureStart?.invoke(enhancedZoomState.enhancedZoomData)
285+ },
286+ onGestureEnd = {
287+ coroutineScope.launch {
288+ enhancedZoomState.onGestureEnd {
289+ onGestureEnd?.invoke(enhancedZoomState.enhancedZoomData)
290+ }
291+ }
292+ },
293+ onGesture = { centroid, pan, zoom, rotate, mainPointer, pointerList ->
294+
295+ coroutineScope.launch {
296+ enhancedZoomState.onGesture(
297+ centroid = centroid,
298+ pan = pan,
299+ zoom = zoom,
300+ rotation = rotate,
301+ mainPointer = mainPointer,
302+ changes = pointerList
303+ )
304+ }
305+
306+ onGesture?.invoke(enhancedZoomState.enhancedZoomData)
307+ }
308+ )
309+ }
310+
311+ val tapModifier = Modifier .pointerInput(keys) {
312+ // Pass size of this Composable this Modifier is attached for constraining operations
313+ // inside this bounds
314+ enhancedZoomState.size = this .size
315+ detectTapGestures(
316+ onDoubleTap = {
317+ coroutineScope.launch {
318+ enhancedZoomState.onDoubleTap {
319+ onGestureEnd?.invoke(enhancedZoomState.enhancedZoomData)
320+ }
321+ }
322+ }
323+ )
324+ }
325+
326+ val graphicsModifier = Modifier .graphicsLayer {
327+ this .update(enhancedZoomState)
328+ }
329+
330+ this .then(
331+ (if (clipToBounds) Modifier .clipToBounds() else Modifier )
332+ .then(tapModifier)
333+ .then(transformModifier)
334+ .then(graphicsModifier)
335+ )
336+ },
337+ inspectorInfo = {
338+ name = " enhancedZoom"
339+ // add name and value of each argument
340+ properties[" keys" ] = keys
341+ properties[" consume" ] = consume
342+ properties[" clip" ] = clip
115343 properties[" onDown" ] = onGestureStart
116344 properties[" onMove" ] = onGesture
117345 properties[" onUp" ] = onGestureEnd
0 commit comments