@@ -13,13 +13,12 @@ import androidx.compose.ui.graphics.Color
1313import androidx.compose.ui.layout.Layout
1414import androidx.compose.ui.layout.Placeable
1515import androidx.compose.ui.platform.LocalContext
16+ import androidx.compose.ui.platform.LocalDensity
1617import androidx.compose.ui.platform.testTag
1718import androidx.compose.ui.semantics.contentDescription
1819import androidx.compose.ui.semantics.semantics
1920import androidx.compose.ui.tooling.preview.Preview
20- import androidx.compose.ui.unit.Dp
21- import androidx.compose.ui.unit.IntOffset
22- import androidx.compose.ui.unit.dp
21+ import androidx.compose.ui.unit.*
2322import co.yml.coreui.core.ui.ytag.model.TagViewContainerModifiers
2423import co.yml.coreui.core.ui.ytag.model.TagViewData
2524import co.yml.coreui.core.ui.ytag.model.TagViewModifiers
@@ -41,38 +40,48 @@ fun TagViewContainer(
4140 updatedTagViewData.add(moreTag)
4241
4342 with (tagViewContainerModifiers) {
44- val modifier = Modifier
4543 val context = LocalContext .current
44+ var modifier = if (tagViewContainerModifiers.width != Dp .Unspecified ) {
45+ Modifier .width(tagViewContainerModifiers.width)
46+ } else {
47+ Modifier .wrapContentWidth()
48+ }
49+
50+ modifier = if (tagViewContainerModifiers.height != Dp .Unspecified ) {
51+ modifier.then(Modifier .height(tagViewContainerModifiers.height))
52+ } else {
53+ modifier.then(Modifier .wrapContentHeight())
54+ }
55+
56+ modifier = modifier.then(Modifier
57+ .run {
58+ if (enableBorder) {
59+ border(
60+ width = borderWidth,
61+ color = borderColor,
62+ shape = shape
63+ )
64+ } else {
65+ background(color = backgroundColor, shape = shape)
66+ }
67+ }
68+ .defaultMinSize(minWidth, minHeight)
69+ .clickable { }
70+ .semantics {
71+ this .contentDescription =
72+ context.getString(co.yml.coreui.ui.R .string.tag_view_container_accessibility_title)
73+ }
74+ .testTag(" tag_view_container" )
75+ .background(
76+ color = backgroundColor,
77+ shape = shape
78+ )
79+ .padding(containerPaddingValues)
80+ )
81+
4682 Box (
4783 modifier = modifier
48- .run {
49- if (enableBorder) {
50- border(
51- width = borderWidth,
52- color = borderColor,
53- shape = shape
54- )
55- } else {
56- background(color = backgroundColor, shape = shape)
57- }
58- }
59- .width(width = width ? : Dp .Unspecified )
60- .height(height = height)
61- .defaultMinSize(minWidth = minWidth, minHeight = minHeight)
62- .clickable { }
63- .semantics {
64- this .contentDescription =
65- context.getString(co.yml.coreui.ui.R .string.tag_view_container_accessibility_title)
66- }
67- .testTag(" tag_view_container" )
68- .background(
69- color = backgroundColor,
70- shape = shape
71- )
72- .padding(containerPaddingValues)
7384 ) {
74-
75-
7685 TagViewContainerLayout (
7786 tagViewContainerModifiers = tagViewContainerModifiers,
7887 content = {
@@ -107,6 +116,8 @@ fun TagViewContainerLayout(
107116 tagViewContainerModifiers : TagViewContainerModifiers ,
108117 content : @Composable () -> Unit
109118) {
119+ val localDensity = LocalDensity .current
120+
110121 Layout (content = content) { measurables, constraints ->
111122 val looseConstraints = constraints.copy(
112123 minWidth = 0 ,
@@ -138,8 +149,6 @@ fun TagViewContainerLayout(
138149 .toInt()
139150 )
140151 }
141- Log .i(" check_measure" , " common: ${currentOffset} " )
142-
143152 placeAble to currentOffset.also {
144153 currentOffset = it.copy(
145154 x = it.x + placeAble.width + tagViewContainerModifiers.tagSpacingHorizontal.toPx()
@@ -148,34 +157,25 @@ fun TagViewContainerLayout(
148157 }
149158 }
150159
151- layout(width = constraints.maxWidth,
152- height = placeAbles.lastOrNull()?.run { first.height } ? : 0 ) {
160+ layout(
161+ width = constraints.maxWidth,
162+ height = constraints.maxHeight
163+ ) {
153164 Log .i(" check_placeAble" , " size: ${placeAbles.size} " )
154165 placeAbles.forEachIndexed { index, placeable ->
155166 val (placeable, offset) = placeable
156167 // check whether current item has enough space
157- val currentItemHorizontalSpace =
158- placeable.width + tagViewContainerModifiers.tagSpacingHorizontal.toPx()
159- .toInt()
160- val currentItemVerticalSpace =
161- placeable.height + tagViewContainerModifiers.tagSpacingVertical.toPx()
162- .toInt()
163-
164- if (offset.x + currentItemHorizontalSpace < constraints.maxWidth && offset.y + currentItemVerticalSpace < constraints.maxHeight) {
168+ if (offset.x + placeable.width < constraints.maxWidth && offset.y + placeable.height < constraints.maxHeight) {
165169 // current item has space
166170 Log .i(" check_placeable" , " index: $index current item has space" )
167171 val nextItemIndex = index + 1
168172 if (nextItemIndex <= placeAbles.lastIndex) {
169173 val nextItemOffset = placeAbles[nextItemIndex].second
170-
171- val nextItemHorizontalSpace =
172- placeAbles[nextItemIndex].first.width + tagViewContainerModifiers.tagSpacingHorizontal.toPx()
173- .toInt()
174- val nextItemVerticalSpace =
175- placeAbles[nextItemIndex].first.height + tagViewContainerModifiers.tagSpacingVertical.toPx()
176- .toInt()
177-
178- if (nextItemOffset.x + nextItemHorizontalSpace < constraints.maxWidth && nextItemOffset.y + nextItemVerticalSpace < constraints.maxHeight) {
174+ Log .i(
175+ " check_placeable" ,
176+ " next index: $nextItemIndex nextItemOffset : $nextItemOffset Before checking"
177+ )
178+ if (nextItemOffset.x + placeAbles[nextItemIndex].first.width < constraints.maxWidth && nextItemOffset.y + placeAbles[nextItemIndex].first.height < constraints.maxHeight) {
179179 // next item has space
180180 Log .i(
181181 " check_placeable" ,
@@ -185,54 +185,99 @@ fun TagViewContainerLayout(
185185 } else {
186186 // next item has no space
187187 // check space to accommodate more tag
188- Log .i(" check_placeable" , " index: $index next item has no space" )
189- val moreTagPlaceAble = placeAbles.last()
190- val remainingTags = placeAbles.lastIndex - 1 - index
191-
192-
193- // tagViewContainerModifiers.moreTagConfiguration.overFlowText.invoke(remainingTags)
194- val moreTagHorizontalSpace =
195- moreTagPlaceAble.first.width + tagViewContainerModifiers.tagSpacingHorizontal.toPx()
196- .toInt()
197- val moreTagVerticalSpace =
198- moreTagPlaceAble.first.height + tagViewContainerModifiers.tagSpacingVertical.toPx()
199- .toInt()
200-
201- if (offset.x + moreTagHorizontalSpace < constraints.maxWidth && offset.y + moreTagVerticalSpace < constraints.maxHeight) {
202- // place more tag
203- Log .i(" check_placeable" , " index: $index more tag placed" )
204- moreTagPlaceAble.first.place(offset.x, offset.y)
205- return @layout
206- } else {
207- Log .i(" check_placeable" , " index: $index more tag has no space" )
188+ val overflow = showOverFlow(
189+ index,
190+ placeAbles,
191+ tagViewContainerModifiers,
192+ constraints,
193+ localDensity
194+ )
195+ overflow?.let {
196+ it.first.place(it.second)
208197 }
198+ return @layout
209199 }
210200 }
211201 } else {
212202 // current item has no space
213203 // check space to accommodate more tag
214- Log .i(" check_placeable" , " index: $index current item has no space" )
215- val remainingTags = placeAbles.lastIndex - 1 - index
216- val moreTagPlaceAble = placeAbles.last()
217- val moreTagHorizontalSpace =
218- moreTagPlaceAble.first.width + tagViewContainerModifiers.tagSpacingHorizontal.toPx()
219- .toInt()
220- val moreTagVerticalSpace =
221- moreTagPlaceAble.first.height + tagViewContainerModifiers.tagSpacingVertical.toPx()
222- .toInt()
223-
224- if (offset.x + moreTagHorizontalSpace < constraints.maxWidth && offset.y + moreTagVerticalSpace < constraints.maxHeight) {
225- // place more tag
226- Log .i(" check_placeable" , " index: $index more tag placed" )
227- placeable.place(offset.x, offset.y)
228- return @layout
229- } else {
230- Log .i(" check_placeable" , " index: $index more tag has no space" )
204+ val overflow = showOverFlow(
205+ index,
206+ placeAbles,
207+ tagViewContainerModifiers,
208+ constraints,
209+ localDensity
210+ )
211+ overflow?.let {
212+ it.first.place(it.second)
231213 }
214+ return @layout
215+ }
216+ }
217+ }
218+ }
219+ }
220+
221+ /* *
222+ * Used for displaying the over flow details when tags not fit in the container
223+ * @param index current placeAble index
224+ * @param placeAbles placeAble details of tags
225+ * @param tagViewContainerModifiers collection of modifier elements that decorate or add behavior to tag view container
226+ * @param constraints immutable constraints for measuring layouts
227+ * @param localDensity A density of the screen. Used for the conversions between pixels and Dp
228+ */
229+ fun showOverFlow (
230+ index : Int ,
231+ placeAbles : List <Pair <Placeable , IntOffset >>,
232+ tagViewContainerModifiers : TagViewContainerModifiers ,
233+ constraints : Constraints ,
234+ localDensity : Density
235+ ): Pair <Placeable , IntOffset >? {
236+ val offset = placeAbles[index].second
237+ val placeable = placeAbles[index]
238+
239+ if (tagViewContainerModifiers.moreTagConfiguration.showOverFlow) {
240+ Log .i(" check_placeable" , " index: $index next item has no space" )
241+ val moreTagPlaceAble = placeAbles.last()
242+ val remainingTags = placeAbles.lastIndex - 1 - index
243+
244+ if (offset.x + moreTagPlaceAble.first.width < constraints.maxWidth && offset.y + moreTagPlaceAble.first.height < constraints.maxHeight) {
245+ // place more tag
246+ Log .i(
247+ " check_placeable" ,
248+ " index: $index more tag placed offset: $offset "
249+ )
250+
251+ // check whether more tag can be placed in between current and previous offset
252+ val previousIndex = index - 1
253+ if (previousIndex >= 0 ) {
254+ val previousOffset = placeAbles[previousIndex].second
255+ val previousTag = placeAbles[previousIndex].first
256+
257+ val moreTagXOffset =
258+ previousOffset.x + localDensity.run { tagViewContainerModifiers.tagSpacingHorizontal.toPx() }
259+ .toInt() + previousTag.width
260+ val moreTagYOffset = previousOffset.y
261+
262+ if (moreTagXOffset + moreTagPlaceAble.first.width < constraints.maxWidth && moreTagYOffset + moreTagPlaceAble.first.height < constraints.maxHeight) {
263+ Log .i(
264+ " check_placeable" ,
265+ " prev index: $previousIndex more tag placed on in btw offset: $previousOffset "
266+ )
267+
268+ return Pair (moreTagPlaceAble.first, IntOffset (moreTagXOffset, moreTagYOffset))
232269 }
233270 }
271+
272+ return moreTagPlaceAble
273+ } else {
274+ Log .i(" check_placeable" , " index: $index more tag has no space" )
234275 }
276+ } else {
277+ return placeable
235278 }
279+
280+ return null
236281}
237282
238283@Preview(name = " Default Tag container" )
0 commit comments