Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add font size customization #9

Merged
merged 5 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.infomaniak.lib.richhtmleditor
import android.graphics.Color
import android.webkit.JavascriptInterface
import androidx.annotation.ColorInt
import androidx.annotation.IntRange
import com.infomaniak.lib.richhtmleditor.executor.JsExecutableMethod
import com.infomaniak.lib.richhtmleditor.executor.JsExecutor
import kotlinx.coroutines.CoroutineDispatcher
Expand Down Expand Up @@ -41,17 +42,21 @@ internal class JsBridge(

fun removeFormat() = execCommand(OtherCommand.REMOVE_FORMAT)

fun setTextColor(@ColorInt color: Int) = execCommand(StatusCommand.TEXT_COLOR, colorToRgbHex(color))
fun setTextColor(color: JsColor) = execCommand(StatusCommand.TEXT_COLOR, color)

fun setTextBackgroundColor(@ColorInt color: Int) = execCommand(StatusCommand.BACKGROUND_COLOR, colorToRgbHex(color))
fun setTextBackgroundColor(color: JsColor) = execCommand(StatusCommand.BACKGROUND_COLOR, color)

fun setFontSize(@IntRange(from = FONT_MIN_SIZE, to = FONT_MAX_SIZE) fontSize: Int) {
execCommand(StatusCommand.FONT_SIZE, fontSize)
}

fun createLink(displayText: String?, url: String) {
jsExecutor.executeImmediatelyAndRefreshToolbar(JsExecutableMethod("createLink", displayText, url))
}

fun unlink() = jsExecutor.executeImmediatelyAndRefreshToolbar(JsExecutableMethod("unlink"))

private fun execCommand(command: ExecCommand, argument: String? = null) {
private fun execCommand(command: ExecCommand, argument: Any? = null) {
jsExecutor.executeImmediatelyAndRefreshToolbar(
JsExecutableMethod(
"document.execCommand",
Expand All @@ -72,9 +77,6 @@ internal class JsBridge(
return Color.argb(255, r.toInt(), g.toInt(), b.toInt())
}

@OptIn(ExperimentalStdlibApi::class)
private fun colorToRgbHex(color: Int) = color.toHexString(HexFormat.UpperCase).takeLast(6)

@JavascriptInterface
fun reportCommandDataChange(
isBold: Boolean,
Expand Down Expand Up @@ -120,5 +122,7 @@ internal class JsBridge(

companion object {
private val CHARACTERS_TO_REMOVE = setOf('r', 'g', 'b', 'a', '(', ')', ' ')
const val FONT_MIN_SIZE: Long = 1
const val FONT_MAX_SIZE: Long = 7
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.infomaniak.lib.richhtmleditor

import androidx.annotation.ColorInt

data class JsColor(@ColorInt val color: Int)
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.annotation.ColorInt
import androidx.annotation.IntRange
import androidx.core.os.bundleOf
import androidx.core.view.updateLayoutParams
import com.infomaniak.lib.richhtmleditor.JsBridge.Companion.FONT_MAX_SIZE
import com.infomaniak.lib.richhtmleditor.JsBridge.Companion.FONT_MIN_SIZE
import com.infomaniak.lib.richhtmleditor.executor.JsExecutableMethod
import com.infomaniak.lib.richhtmleditor.executor.JsExecutor
import com.infomaniak.lib.richhtmleditor.executor.KeyboardOpener
Expand Down Expand Up @@ -124,8 +127,16 @@ class RichHtmlEditorWebView @JvmOverloads constructor(
fun toggleStrikeThrough() = jsBridge.toggleStrikeThrough()
fun toggleUnderline() = jsBridge.toggleUnderline()
fun removeFormat() = jsBridge.removeFormat()
fun setTextColor(@ColorInt color: Int) = jsBridge.setTextColor(color)
fun setTextBackgroundColor(@ColorInt color: Int) = jsBridge.setTextBackgroundColor(color)
fun setTextColor(@ColorInt color: Int) = jsBridge.setTextColor(JsColor(color))
fun setTextBackgroundColor(@ColorInt color: Int) = jsBridge.setTextBackgroundColor(JsColor(color))

/**
* Updates the font size of the text.
*
* @param fontSize The new size of the text. This value's range constraint comes from the JavaScript `execCommand` method
* called with the argument `fontSize`.
*/
fun setFontSize(@IntRange(from = FONT_MIN_SIZE, to = FONT_MAX_SIZE) fontSize: Int) = jsBridge.setFontSize(fontSize)
fun createLink(displayText: String?, url: String) = jsBridge.createLink(displayText?.takeIf { it.isNotBlank() }, url)
fun unlink() = jsBridge.unlink()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.infomaniak.lib.richhtmleditor.executor

import android.webkit.WebView
import androidx.annotation.ColorInt
import com.infomaniak.lib.richhtmleditor.JsColor

class JsExecutableMethod(
private val methodName: String,
Expand Down Expand Up @@ -33,7 +35,8 @@ class JsExecutableMethod(
return when (value) {
null -> "null"
is String -> "'${looselyEscapeStringForJs(value)}'"
is Boolean -> value.toString()
is Boolean, is Number -> value.toString()
is JsColor -> "'${colorToRgbHex(value.color)}'"
else -> throw NotImplementedError("Encoding ${value::class} for JS is not yet implemented")
}
}
Expand All @@ -55,5 +58,8 @@ class JsExecutableMethod(

return stringBuilder.toString()
}

@OptIn(ExperimentalStdlibApi::class)
private fun colorToRgbHex(@ColorInt color: Int) = color.toHexString(HexFormat.UpperCase).takeLast(6)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ class EditorSampleFragment : Fragment() {
textColorBlue.setOnClickListener { editor.setTextColor(BLUE) }
textBackgroundColorRed.setOnClickListener { editor.setTextBackgroundColor(RED) }
textBackgroundColorBlue.setOnClickListener { editor.setTextBackgroundColor(BLUE) }

fontSmallButton.setOnClickListener { editor.setFontSize(SMALL_FONT_SIZE) }
fontMediumButton.setOnClickListener { editor.setFontSize(MEDIUM_FONT_SIZE) }
fontBigButton.setOnClickListener { editor.setFontSize(BIG_FONT_SIZE) }
}

private fun observeEditorStatusUpdates() = with(binding) {
Expand Down Expand Up @@ -121,6 +125,7 @@ class EditorSampleFragment : Fragment() {
private fun setToolbarEnabledStatus(isEnabled: Boolean) = with(binding) {
toolbarLayout.forEach { view -> view.isEnabled = isEnabled }
colorLayout.forEach { view -> view.isEnabled = isEnabled }
fontLayout.forEach { view -> view.isEnabled = isEnabled }
}

inner class CreateLinkDialog {
Expand Down Expand Up @@ -155,5 +160,9 @@ class EditorSampleFragment : Fragment() {
companion object {
private val RED = Color.parseColor("#FF0000")
private val BLUE = Color.parseColor("#0000FF")

private const val SMALL_FONT_SIZE = 2
private const val MEDIUM_FONT_SIZE = 4
private const val BIG_FONT_SIZE = 6
}
}
39 changes: 39 additions & 0 deletions sample/src/main/res/layout/fragment_editor_sample.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,45 @@
</HorizontalScrollView>
</LinearLayout>

<LinearLayout
android:id="@+id/fontLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="Font size:"
android:textColor="@color/subtitleColor" />

<com.google.android.material.button.MaterialButton
android:id="@+id/fontSmallButton"
style="@style/EditorButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:text="Small" />

<com.google.android.material.button.MaterialButton
android:id="@+id/fontMediumButton"
style="@style/EditorButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:text="Medium" />

<com.google.android.material.button.MaterialButton
android:id="@+id/fontBigButton"
style="@style/EditorButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:text="Big" />

</LinearLayout>

<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
Expand Down
Loading