Skip to content

Commit ea07cf3

Browse files
authored
Merge pull request #986 from wordpress-mobile/feature/placeholder-improvements
Add option to set placeholder size based on the item shown
2 parents 8be1d79 + 3819730 commit ea07cf3

File tree

3 files changed

+47
-34
lines changed

3 files changed

+47
-34
lines changed

media-placeholders/src/main/java/org/wordpress/aztec/placeholders/AztecPlaceholderSpan.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ class AztecPlaceholderSpan(
1515
attributes: AztecAttributes = AztecAttributes(),
1616
onMediaDeletedListener: AztecText.OnMediaDeletedListener? = null,
1717
editor: AztecText? = null,
18-
private val adapter: PlaceholderManager.PlaceholderAdapter) :
18+
private val adapter: PlaceholderManager.PlaceholderAdapter,
19+
override val TAG: String) :
1920
AztecMediaSpan(context, drawable, attributes, onMediaDeletedListener, editor), IAztecFullWidthImageSpan, IAztecSpan {
20-
override val TAG: String = "placeholder"
2121
override fun onClick() {
2222

2323
}
2424

2525
override fun getMaxWidth(editorWidth: Int): Int {
26-
return adapter.getWidth(editorWidth)
26+
return adapter.calculateWidth(attributes, editorWidth)
2727
}
2828
}

media-placeholders/src/main/java/org/wordpress/aztec/placeholders/ImageWithCaptionAdapter.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@ import android.widget.LinearLayout
88
import android.widget.TextView
99
import com.bumptech.glide.Glide
1010
import org.wordpress.aztec.AztecAttributes
11-
import org.wordpress.aztec.placeholders.PlaceholderManager.PlaceholderAdapter.PlaceholderSize
11+
import org.wordpress.aztec.placeholders.PlaceholderManager.PlaceholderAdapter.Proportion
1212

1313
/**
1414
* A sample adapter which creates a custom layout over the placeholder. Treat this as an example of what can be done.
1515
* This adapter creates an image with a caption under it
1616
*/
1717
class ImageWithCaptionAdapter(
18-
override val placeholderSize: PlaceholderSize = PlaceholderSize(height = PlaceholderSize.Proportion.Ratio(0.5f)),
1918
override val type: String = "image_with_caption"
2019
) : PlaceholderManager.PlaceholderAdapter {
2120
private val media = mutableMapOf<String, ImageWithCaptionObject>()
21+
override fun getHeight(attrs: AztecAttributes): Proportion {
22+
return Proportion.Ratio(0.5f)
23+
}
2224
override fun createView(context: Context, placeholderUuid: String, attrs: AztecAttributes): View {
2325
val imageWithCaptionObject = media[placeholderUuid] ?: ImageWithCaptionObject(placeholderUuid, attrs.getValue(SRC_ATTRIBUTE), View.generateViewId()).apply {
2426
media[placeholderUuid] = this

media-placeholders/src/main/java/org/wordpress/aztec/placeholders/PlaceholderManager.kt

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class PlaceholderManager(
5050

5151
fun onDestroy() {
5252
aztecText.contentChangeWatcher.unregisterObserver(this)
53+
adapters.values.forEach { it.onDestroy() }
5354
adapters.clear()
5455
}
5556

@@ -70,15 +71,15 @@ class PlaceholderManager(
7071
val adapter = adapters[type]
7172
?: throw IllegalArgumentException("Adapter for inserted type not found. Register it with `registerAdapter` method")
7273
val attrs = getAttributesForMedia(type, attributes)
73-
val drawable = buildPlaceholderDrawable(adapter)
74+
val drawable = buildPlaceholderDrawable(adapter, attrs)
7475
aztecText.insertMediaSpan(AztecPlaceholderSpan(aztecText.context, drawable, 0, attrs,
75-
this, aztecText, adapter))
76+
this, aztecText, adapter, TAG = htmlTag))
7677
insertContentOverSpanWithId(attrs.getValue(UUID_ATTRIBUTE), null)
7778
}
7879

79-
private fun buildPlaceholderDrawable(adapter: PlaceholderAdapter): Drawable {
80+
private fun buildPlaceholderDrawable(adapter: PlaceholderAdapter, attrs: AztecAttributes): Drawable {
8081
val drawable = ContextCompat.getDrawable(aztecText.context, android.R.color.transparent)!!
81-
updateDrawableBounds(adapter, drawable)
82+
updateDrawableBounds(adapter, attrs, drawable)
8283
return drawable
8384
}
8485

@@ -140,7 +141,7 @@ class PlaceholderManager(
140141
box = adapter.createView(container.context, uuid, attrs)
141142
}
142143
val params = FrameLayout.LayoutParams(
143-
adapter.getWidth(parentTextViewRect.right - parentTextViewRect.left - 20),
144+
adapter.calculateWidth(attrs, parentTextViewRect.right - parentTextViewRect.left - 20),
144145
parentTextViewRect.bottom - parentTextViewRect.top - 20
145146
)
146147
val padding = 10
@@ -232,16 +233,17 @@ class PlaceholderManager(
232233
if (opening) {
233234
val type = attributes.getValue(TYPE_ATTRIBUTE)
234235
val adapter = adapters[type] ?: return false
235-
val drawable = buildPlaceholderDrawable(adapter)
236236
val aztecAttributes = AztecAttributes(attributes)
237237
aztecAttributes.setValue(UUID_ATTRIBUTE, UUID.randomUUID().toString())
238+
val drawable = buildPlaceholderDrawable(adapter, aztecAttributes)
238239
val span = AztecPlaceholderSpan(
239240
context = aztecText.context,
240241
drawable = drawable,
241242
nestingLevel = nestingLevel,
242243
attributes = aztecAttributes,
243244
onMediaDeletedListener = this,
244-
adapter = adapter
245+
adapter = adapter,
246+
TAG = htmlTag
245247
)
246248
val clickableSpan = AztecMediaClickableSpan(span)
247249
val position = output.length
@@ -269,7 +271,7 @@ class PlaceholderManager(
269271
spans.forEach {
270272
val type = it.attributes.getValue(TYPE_ATTRIBUTE)
271273
val adapter = adapters[type] ?: return
272-
updateDrawableBounds(adapter, it.drawable)
274+
updateDrawableBounds(adapter, it.attributes, it.drawable)
273275
aztecText.post {
274276
aztecText.refreshText(false)
275277
insertInPosition(it.attributes, aztecText.editableText.getSpanStart(it))
@@ -279,10 +281,10 @@ class PlaceholderManager(
279281
})
280282
}
281283

282-
private fun updateDrawableBounds(adapter: PlaceholderAdapter, drawable: Drawable?) {
284+
private fun updateDrawableBounds(adapter: PlaceholderAdapter, attrs: AztecAttributes, drawable: Drawable?) {
283285
val editorWidth = if (aztecText.width > 0) aztecText.width else aztecText.maxImagesWidth
284286
if (drawable?.bounds?.right != editorWidth) {
285-
drawable?.setBounds(0, 0, adapter.getWidth(editorWidth), adapter.getHeight(editorWidth))
287+
drawable?.setBounds(0, 0, adapter.calculateWidth(attrs, editorWidth), adapter.calculateHeight(attrs, editorWidth))
286288
}
287289
}
288290

@@ -330,6 +332,11 @@ class PlaceholderManager(
330332
*/
331333
fun onPlaceholderDeleted(placeholderUuid: String) {}
332334

335+
/**
336+
* This method is called when the placeholders are destroyed
337+
*/
338+
fun onDestroy() {}
339+
333340
/**
334341
* Override this method if you want to handle view touches. To handle clicks on subviews just use
335342
* `setOnClickListener` on the view that you want to handle the click.
@@ -339,30 +346,36 @@ class PlaceholderManager(
339346
}
340347

341348
/**
342-
* Override this field to set the width of the placeholder. It could be either a ratio of window width or
343-
* a fixed size.
349+
* Define unique string type here in order to differentiate between the adapters drawing the custom views.
344350
*/
345-
val placeholderSize: PlaceholderSize
351+
val type: String
346352

347353
/**
348-
* Define unique string type here in order to differentiate between the adapters drawing the custom views.
354+
* Returns width of the view based on the HTML attributes. Use this method to either set fixed width or to
355+
* calculate width based on the view.
349356
*/
350-
val type: String
357+
fun getWidth(attrs: AztecAttributes): Proportion = Proportion.Ratio(1.0f)
358+
359+
/**
360+
* Returns height of the view based on the HTML attributes. Use this method to either set fixed height or to
361+
* calculate width based on the view.
362+
*/
363+
fun getHeight(attrs: AztecAttributes): Proportion
351364

352365
/**
353366
* Returns height of the view based on the width and the placeholder height.
354367
*/
355-
fun getHeight(windowWidth: Int): Int {
356-
return placeholderSize.height.let { height ->
368+
fun calculateHeight(attrs: AztecAttributes, windowWidth: Int): Int {
369+
return getHeight(attrs).let { height ->
357370
when (height) {
358-
is PlaceholderSize.Proportion.Fixed -> height.value
359-
is PlaceholderSize.Proportion.Ratio -> {
371+
is Proportion.Fixed -> height.value
372+
is Proportion.Ratio -> {
360373
val ratio = if (height.ratio < 0.1) {
361374
0.1f
362375
} else {
363376
height.ratio
364377
}
365-
(ratio * getWidth(windowWidth)).toInt()
378+
(ratio * calculateWidth(attrs, windowWidth)).toInt()
366379
}
367380
}
368381
}
@@ -371,11 +384,11 @@ class PlaceholderManager(
371384
/**
372385
* Returns height of the view based on the width and the placeholder height.
373386
*/
374-
fun getWidth(windowWidth: Int): Int {
375-
return placeholderSize.width.let { width ->
387+
fun calculateWidth(attrs: AztecAttributes, windowWidth: Int): Int {
388+
return getWidth(attrs).let { width ->
376389
when (width) {
377-
is PlaceholderSize.Proportion.Fixed -> min(windowWidth, width.value)
378-
is PlaceholderSize.Proportion.Ratio -> {
390+
is Proportion.Fixed -> min(windowWidth, width.value)
391+
is Proportion.Ratio -> {
379392
val safeRatio: Float = when {
380393
width.ratio < 0.1 -> 0.1f
381394
width.ratio > 1.0 -> 1.0f
@@ -387,11 +400,9 @@ class PlaceholderManager(
387400
}
388401
}
389402

390-
data class PlaceholderSize(val height: Proportion, val width: Proportion = Proportion.Ratio(1.0f)) {
391-
sealed class Proportion {
392-
data class Fixed(val value: Int) : Proportion()
393-
data class Ratio(val ratio: Float) : Proportion()
394-
}
403+
sealed class Proportion {
404+
data class Fixed(val value: Int) : Proportion()
405+
data class Ratio(val ratio: Float) : Proportion()
395406
}
396407
}
397408

0 commit comments

Comments
 (0)