|
|
@@ -14,12 +14,37 @@ import androidx.compose.foundation.layout.padding
|
|
|
import androidx.compose.foundation.rememberScrollState
|
|
|
import androidx.compose.foundation.verticalScroll
|
|
|
import androidx.compose.material.icons.Icons
|
|
|
+import androidx.compose.material.icons.filled.AlignHorizontalCenter
|
|
|
+import androidx.compose.material.icons.filled.AlignHorizontalLeft
|
|
|
+import androidx.compose.material.icons.filled.AlignHorizontalRight
|
|
|
+import androidx.compose.material.icons.filled.AspectRatio
|
|
|
+import androidx.compose.material.icons.filled.CallSplit
|
|
|
import androidx.compose.material.icons.filled.CleanHands
|
|
|
+import androidx.compose.material.icons.filled.Code
|
|
|
+import androidx.compose.material.icons.filled.CopyAll
|
|
|
+import androidx.compose.material.icons.filled.FormatAlignJustify
|
|
|
+import androidx.compose.material.icons.filled.FormatColorText
|
|
|
+import androidx.compose.material.icons.filled.FormatIndentIncrease
|
|
|
import androidx.compose.material.icons.filled.FormatItalic
|
|
|
+import androidx.compose.material.icons.filled.FormatLineSpacing
|
|
|
+import androidx.compose.material.icons.filled.FormatSize
|
|
|
import androidx.compose.material.icons.filled.FormatUnderlined
|
|
|
+import androidx.compose.material.icons.filled.Height
|
|
|
+import androidx.compose.material.icons.filled.Image
|
|
|
import androidx.compose.material.icons.filled.Layers
|
|
|
+import androidx.compose.material.icons.filled.LineWeight
|
|
|
+import androidx.compose.material.icons.filled.Minimize
|
|
|
+import androidx.compose.material.icons.filled.Palette
|
|
|
+import androidx.compose.material.icons.filled.Segment
|
|
|
+import androidx.compose.material.icons.filled.SpaceBar
|
|
|
import androidx.compose.material.icons.filled.TextFields
|
|
|
+import androidx.compose.material.icons.filled.Title
|
|
|
+import androidx.compose.material.icons.filled.Translate
|
|
|
import androidx.compose.material.icons.filled.Tune
|
|
|
+import androidx.compose.material.icons.filled.VerticalAlignBottom
|
|
|
+import androidx.compose.material.icons.filled.VerticalAlignTop
|
|
|
+import androidx.compose.material.icons.filled.ViewAgenda
|
|
|
+import androidx.compose.material.icons.filled.ViewHeadline
|
|
|
import androidx.compose.runtime.Composable
|
|
|
import androidx.compose.runtime.getValue
|
|
|
import androidx.compose.runtime.mutableFloatStateOf
|
|
|
@@ -29,6 +54,7 @@ import androidx.compose.runtime.remember
|
|
|
import androidx.compose.runtime.setValue
|
|
|
import androidx.compose.ui.Alignment
|
|
|
import androidx.compose.ui.Modifier
|
|
|
+import androidx.compose.ui.graphics.vector.ImageVector
|
|
|
import androidx.compose.ui.platform.LocalContext
|
|
|
import androidx.compose.ui.res.stringArrayResource
|
|
|
import androidx.compose.ui.res.stringResource
|
|
|
@@ -113,6 +139,7 @@ private fun FontWeightSetting(
|
|
|
selectedValue = value.toString(),
|
|
|
displayEntries = arrayOf(weightEntries[2], weightEntries[0], weightEntries[1]),
|
|
|
entryValues = arrayOf("2", "0", "1"),
|
|
|
+ imageVector = Icons.Default.LineWeight,
|
|
|
onValueChange = { onValueChange(it.toInt()) },
|
|
|
)
|
|
|
}
|
|
|
@@ -173,6 +200,7 @@ private fun TipPositionDropdown(
|
|
|
value: Int,
|
|
|
tipNames: List<String>,
|
|
|
tipValues: Array<Int>,
|
|
|
+ imageVector: ImageVector? = null,
|
|
|
onValueChange: (Int) -> Unit,
|
|
|
) {
|
|
|
TinyDropdownSettingItem(
|
|
|
@@ -180,6 +208,7 @@ private fun TipPositionDropdown(
|
|
|
selectedValue = value.toString(),
|
|
|
displayEntries = tipNames.toTypedArray(),
|
|
|
entryValues = tipValues.map { it.toString() }.toTypedArray(),
|
|
|
+ imageVector = imageVector,
|
|
|
onValueChange = { onValueChange(it.toInt()) },
|
|
|
)
|
|
|
}
|
|
|
@@ -199,24 +228,28 @@ private fun PaddingSliders(
|
|
|
title = stringResource(R.string.padding_top),
|
|
|
value = top,
|
|
|
valueRange = 0f..200f,
|
|
|
+ imageVector = Icons.Default.VerticalAlignTop,
|
|
|
onValueChange = onTopChange,
|
|
|
)
|
|
|
TinySliderSettingItem(
|
|
|
title = stringResource(R.string.padding_bottom),
|
|
|
value = bottom,
|
|
|
valueRange = 0f..200f,
|
|
|
+ imageVector = Icons.Default.VerticalAlignBottom,
|
|
|
onValueChange = onBottomChange,
|
|
|
)
|
|
|
TinySliderSettingItem(
|
|
|
title = stringResource(R.string.padding_left),
|
|
|
value = left,
|
|
|
valueRange = 0f..200f,
|
|
|
+ imageVector = Icons.Default.AlignHorizontalLeft,
|
|
|
onValueChange = onLeftChange,
|
|
|
)
|
|
|
TinySliderSettingItem(
|
|
|
title = stringResource(R.string.padding_right),
|
|
|
value = right,
|
|
|
valueRange = 0f..200f,
|
|
|
+ imageVector = Icons.Default.AlignHorizontalRight,
|
|
|
onValueChange = onRightChange,
|
|
|
)
|
|
|
}
|
|
|
@@ -278,6 +311,7 @@ internal fun TypographyBodyTab(
|
|
|
selectedValue = config.chineseConverterType.toString(),
|
|
|
displayEntries = chineseConvertEntries,
|
|
|
entryValues = chineseConvertValues,
|
|
|
+ imageVector = Icons.Default.Translate,
|
|
|
onValueChange = {
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.ChineseConverterType(it.toInt())))
|
|
|
},
|
|
|
@@ -288,11 +322,13 @@ internal fun TypographyBodyTab(
|
|
|
TinyColorSettingItem(
|
|
|
title = stringResource(R.string.text_color),
|
|
|
colorValue = config.textColor,
|
|
|
+ imageVector = Icons.Default.FormatColorText,
|
|
|
onClick = { onOpenColorPicker(TypographyColorTarget.Text) },
|
|
|
)
|
|
|
TinyColorSettingItem(
|
|
|
title = stringResource(R.string.text_accent_color),
|
|
|
colorValue = config.textAccentColor,
|
|
|
+ imageVector = Icons.Default.Palette,
|
|
|
onClick = { onOpenColorPicker(TypographyColorTarget.TextAccent) },
|
|
|
)
|
|
|
|
|
|
@@ -324,6 +360,7 @@ internal fun TypographyBodyTab(
|
|
|
value = indentCount.toFloat(),
|
|
|
valueRange = 0f..4f,
|
|
|
steps = 3,
|
|
|
+ imageVector = Icons.Default.FormatIndentIncrease,
|
|
|
onValueChange = { value ->
|
|
|
indentCount = value.toInt()
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.ParagraphIndent(" ".repeat(indentCount))))
|
|
|
@@ -334,6 +371,7 @@ internal fun TypographyBodyTab(
|
|
|
value = (letterSpacing * 100) + 50,
|
|
|
valueRange = 0f..100f,
|
|
|
steps = 99,
|
|
|
+ imageVector = Icons.Default.SpaceBar,
|
|
|
valueFormat = { ((it - 50) / 100f).toString() },
|
|
|
onValueChange = { value ->
|
|
|
letterSpacing = (value - 50) / 100f
|
|
|
@@ -345,6 +383,7 @@ internal fun TypographyBodyTab(
|
|
|
value = lineSpacing,
|
|
|
valueRange = 0f..20f,
|
|
|
steps = 19,
|
|
|
+ imageVector = Icons.Default.FormatLineSpacing,
|
|
|
valueFormat = { ((it - 10) / 10f).toString() },
|
|
|
onValueChange = { value ->
|
|
|
lineSpacing = value
|
|
|
@@ -356,6 +395,7 @@ internal fun TypographyBodyTab(
|
|
|
value = paragraphSpacing,
|
|
|
valueRange = 0f..20f,
|
|
|
steps = 19,
|
|
|
+ imageVector = Icons.Default.Segment,
|
|
|
valueFormat = { (it / 10f).toString() },
|
|
|
onValueChange = { value ->
|
|
|
paragraphSpacing = value
|
|
|
@@ -368,6 +408,7 @@ internal fun TypographyBodyTab(
|
|
|
TinySwitchSettingItem(
|
|
|
title = stringResource(R.string.text_full_justify),
|
|
|
checked = config.textFullJustify,
|
|
|
+ imageVector = Icons.Default.FormatAlignJustify,
|
|
|
onCheckedChange = {
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TextFullJustify(it)))
|
|
|
},
|
|
|
@@ -375,6 +416,7 @@ internal fun TypographyBodyTab(
|
|
|
TinySwitchSettingItem(
|
|
|
title = stringResource(R.string.text_bottom_justify),
|
|
|
checked = config.textBottomJustify,
|
|
|
+ imageVector = Icons.Default.VerticalAlignBottom,
|
|
|
onCheckedChange = {
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TextBottomJustify(it)))
|
|
|
},
|
|
|
@@ -399,6 +441,7 @@ internal fun TypographyBodyTab(
|
|
|
selectedValue = ReadBook.book?.getImageStyle() ?: Book.imgStyleDefault,
|
|
|
displayEntries = imgStyleEntries,
|
|
|
entryValues = imgStyleValues,
|
|
|
+ imageVector = Icons.Default.Image,
|
|
|
onValueChange = { style ->
|
|
|
onIntent(ReadBookIntent.MenuImageStyle(style))
|
|
|
},
|
|
|
@@ -455,6 +498,7 @@ internal fun TypographyTitleTab(
|
|
|
stringResource(R.string.title_hide),
|
|
|
),
|
|
|
entryValues = arrayOf("0", "1", "2"),
|
|
|
+ imageVector = Icons.Default.Title,
|
|
|
onValueChange = {
|
|
|
titleMode = it.toInt()
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleMode(titleMode)))
|
|
|
@@ -476,9 +520,10 @@ internal fun TypographyTitleTab(
|
|
|
},
|
|
|
)
|
|
|
TinyColorModeSettingItem(
|
|
|
- title = stringResource(R.string.title_color),
|
|
|
+ title = stringResource(R.string.color),
|
|
|
dayColor = if (config.titleColor != 0) config.titleColor else config.textColorDay,
|
|
|
nightColor = if (config.titleColorNight != 0) config.titleColorNight else config.textColorNight,
|
|
|
+ imageVector = Icons.Default.Palette,
|
|
|
onClickColor = { isNight ->
|
|
|
if (isNight) {
|
|
|
onOpenColorPicker(TypographyColorTarget.TitleNight)
|
|
|
@@ -488,10 +533,11 @@ internal fun TypographyTitleTab(
|
|
|
},
|
|
|
)
|
|
|
TinySliderSettingItem(
|
|
|
- title = stringResource(R.string.title_font_size),
|
|
|
+ title = stringResource(R.string.font_size),
|
|
|
value = titleSize.toFloat(),
|
|
|
valueRange = 8f..60f,
|
|
|
steps = 51,
|
|
|
+ imageVector = Icons.Default.FormatSize,
|
|
|
valueFormat = { "${it.toInt()}sp" },
|
|
|
onValueChange = { value ->
|
|
|
titleSize = value.toInt()
|
|
|
@@ -511,6 +557,7 @@ internal fun TypographyTitleTab(
|
|
|
stringResource(R.string.split_title_by_regex),
|
|
|
),
|
|
|
entryValues = arrayOf("0", "1", "2", "3"),
|
|
|
+ imageVector = Icons.Default.CallSplit,
|
|
|
onValueChange = {
|
|
|
titleSegType = it.toInt()
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleSegType(titleSegType)))
|
|
|
@@ -522,6 +569,7 @@ internal fun TypographyTitleTab(
|
|
|
value = titleSegDistance.toFloat(),
|
|
|
valueRange = 1f..20f,
|
|
|
steps = 18,
|
|
|
+ imageVector = Icons.Default.SpaceBar,
|
|
|
onValueChange = { value ->
|
|
|
titleSegDistance = value.toInt()
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleSegDistance(titleSegDistance)))
|
|
|
@@ -532,6 +580,7 @@ internal fun TypographyTitleTab(
|
|
|
TinyClickableSettingItem(
|
|
|
title = stringResource(R.string.rule_segment),
|
|
|
description = titleSegFlag.ifBlank { stringResource(R.string.split_title_mode) },
|
|
|
+ imageVector = Icons.Default.Code,
|
|
|
onClick = { showFlagDialog = true },
|
|
|
)
|
|
|
}
|
|
|
@@ -541,6 +590,7 @@ internal fun TypographyTitleTab(
|
|
|
valueRange = 0f..2f,
|
|
|
steps = 19,
|
|
|
stepSize = 0.1f,
|
|
|
+ imageVector = Icons.Default.AspectRatio,
|
|
|
valueFormat = { "%.1f".format(it) },
|
|
|
onValueChange = { value ->
|
|
|
titleSegScaling = (value * 10).roundToInt() / 10f
|
|
|
@@ -554,6 +604,7 @@ internal fun TypographyTitleTab(
|
|
|
title = stringResource(R.string.heading_spacing),
|
|
|
value = titleLineSpacingExtra.toFloat(),
|
|
|
valueRange = 0f..20f,
|
|
|
+ imageVector = Icons.Default.LineWeight,
|
|
|
onValueChange = { value ->
|
|
|
titleLineSpacingExtra = value.toInt()
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleLineSpacingExtra(titleLineSpacingExtra)))
|
|
|
@@ -563,6 +614,7 @@ internal fun TypographyTitleTab(
|
|
|
title = stringResource(R.string.subtitle_margin),
|
|
|
value = titleLineSpacingSub.toFloat(),
|
|
|
valueRange = -30f..30f,
|
|
|
+ imageVector = Icons.Default.Height,
|
|
|
onValueChange = { value ->
|
|
|
titleLineSpacingSub = value.toInt()
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleLineSpacingSub(titleLineSpacingSub)))
|
|
|
@@ -641,6 +693,7 @@ internal fun TypographyHeaderTab(
|
|
|
selectedValue = headerMode.toString(),
|
|
|
displayEntries = headerModes.values.toTypedArray(),
|
|
|
entryValues = headerModes.keys.map { it.toString() }.toTypedArray(),
|
|
|
+ imageVector = Icons.Default.ViewHeadline,
|
|
|
onValueChange = { onHeaderModeChange(it.toInt()) },
|
|
|
)
|
|
|
TipPositionDropdown(
|
|
|
@@ -648,6 +701,7 @@ internal fun TypographyHeaderTab(
|
|
|
value = headerLeft,
|
|
|
tipNames = tipNames,
|
|
|
tipValues = tipValues,
|
|
|
+ imageVector = Icons.Default.AlignHorizontalLeft,
|
|
|
onValueChange = { onTipChange(CustomTipTarget.HEADER_LEFT, it) },
|
|
|
)
|
|
|
TipPositionDropdown(
|
|
|
@@ -655,6 +709,7 @@ internal fun TypographyHeaderTab(
|
|
|
value = headerMiddle,
|
|
|
tipNames = tipNames,
|
|
|
tipValues = tipValues,
|
|
|
+ imageVector = Icons.Default.AlignHorizontalCenter,
|
|
|
onValueChange = { onTipChange(CustomTipTarget.HEADER_MIDDLE, it) },
|
|
|
)
|
|
|
TipPositionDropdown(
|
|
|
@@ -662,6 +717,7 @@ internal fun TypographyHeaderTab(
|
|
|
value = headerRight,
|
|
|
tipNames = tipNames,
|
|
|
tipValues = tipValues,
|
|
|
+ imageVector = Icons.Default.AlignHorizontalRight,
|
|
|
onValueChange = { onTipChange(CustomTipTarget.HEADER_RIGHT, it) },
|
|
|
)
|
|
|
|
|
|
@@ -670,6 +726,7 @@ internal fun TypographyHeaderTab(
|
|
|
TinySwitchSettingItem(
|
|
|
title = stringResource(R.string.showLine),
|
|
|
checked = showHeaderLine,
|
|
|
+ imageVector = Icons.Default.Minimize,
|
|
|
onCheckedChange = { onShowHeaderLineChange(it) },
|
|
|
)
|
|
|
TinyColorSettingItem(
|
|
|
@@ -679,6 +736,7 @@ internal fun TypographyHeaderTab(
|
|
|
0 -> ReadBookConfig.textColor
|
|
|
else -> config.tipDividerColor
|
|
|
},
|
|
|
+ imageVector = Icons.Default.Palette,
|
|
|
onClick = { onOpenColorPicker(TypographyColorTarget.Divider) },
|
|
|
)
|
|
|
|
|
|
@@ -690,18 +748,20 @@ internal fun TypographyHeaderTab(
|
|
|
onClick = onOpenHeaderFontSelect,
|
|
|
)
|
|
|
TinySliderSettingItem(
|
|
|
- title = stringResource(R.string.title_font_size),
|
|
|
+ title = stringResource(R.string.font_size),
|
|
|
value = config.headerFontSize.toFloat(),
|
|
|
valueRange = 0f..100f,
|
|
|
+ imageVector = Icons.Default.FormatSize,
|
|
|
onValueChange = { value ->
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.HeaderFontSize(value.toInt())))
|
|
|
onIntent(ReadBookIntent.SaveReadStyleConfig)
|
|
|
},
|
|
|
)
|
|
|
TinyColorModeSettingItem(
|
|
|
- title = stringResource(R.string.title_color),
|
|
|
+ title = stringResource(R.string.color),
|
|
|
dayColor = if (config.tipHeaderColor != 0) config.tipHeaderColor else config.textColorDay,
|
|
|
nightColor = if (config.tipHeaderColorNight != 0) config.tipHeaderColorNight else config.textColorNight,
|
|
|
+ imageVector = Icons.Default.FormatColorText,
|
|
|
onClickColor = { isNight ->
|
|
|
if (isNight) {
|
|
|
onOpenColorPicker(TypographyColorTarget.HeaderNight)
|
|
|
@@ -749,6 +809,7 @@ internal fun TypographyFooterTab(
|
|
|
selectedValue = footerMode.toString(),
|
|
|
displayEntries = footerModes.values.toTypedArray(),
|
|
|
entryValues = footerModes.keys.map { it.toString() }.toTypedArray(),
|
|
|
+ imageVector = Icons.Default.ViewAgenda,
|
|
|
onValueChange = { onFooterModeChange(it.toInt()) },
|
|
|
)
|
|
|
TipPositionDropdown(
|
|
|
@@ -756,6 +817,7 @@ internal fun TypographyFooterTab(
|
|
|
value = footerLeft,
|
|
|
tipNames = tipNames,
|
|
|
tipValues = tipValues,
|
|
|
+ imageVector = Icons.Default.AlignHorizontalLeft,
|
|
|
onValueChange = { onTipChange(CustomTipTarget.FOOTER_LEFT, it) },
|
|
|
)
|
|
|
TipPositionDropdown(
|
|
|
@@ -763,6 +825,7 @@ internal fun TypographyFooterTab(
|
|
|
value = footerMiddle,
|
|
|
tipNames = tipNames,
|
|
|
tipValues = tipValues,
|
|
|
+ imageVector = Icons.Default.AlignHorizontalCenter,
|
|
|
onValueChange = { onTipChange(CustomTipTarget.FOOTER_MIDDLE, it) },
|
|
|
)
|
|
|
TipPositionDropdown(
|
|
|
@@ -770,6 +833,7 @@ internal fun TypographyFooterTab(
|
|
|
value = footerRight,
|
|
|
tipNames = tipNames,
|
|
|
tipValues = tipValues,
|
|
|
+ imageVector = Icons.Default.AlignHorizontalRight,
|
|
|
onValueChange = { onTipChange(CustomTipTarget.FOOTER_RIGHT, it) },
|
|
|
)
|
|
|
|
|
|
@@ -778,6 +842,7 @@ internal fun TypographyFooterTab(
|
|
|
TinySwitchSettingItem(
|
|
|
title = stringResource(R.string.showLine),
|
|
|
checked = showFooterLine,
|
|
|
+ imageVector = Icons.Default.Minimize,
|
|
|
onCheckedChange = { onShowFooterLineChange(it) },
|
|
|
)
|
|
|
|
|
|
@@ -786,6 +851,7 @@ internal fun TypographyFooterTab(
|
|
|
TinySwitchSettingItem(
|
|
|
title = stringResource(R.string.apply_header_style),
|
|
|
checked = config.applyHeaderStyle,
|
|
|
+ imageVector = Icons.Default.CopyAll,
|
|
|
onCheckedChange = {
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.ApplyHeaderStyle(it)))
|
|
|
},
|
|
|
@@ -797,18 +863,20 @@ internal fun TypographyFooterTab(
|
|
|
onClick = onOpenFooterFontSelect,
|
|
|
)
|
|
|
TinySliderSettingItem(
|
|
|
- title = stringResource(R.string.title_font_size),
|
|
|
+ title = stringResource(R.string.font_size),
|
|
|
value = config.footerFontSize.toFloat(),
|
|
|
valueRange = 0f..100f,
|
|
|
+ imageVector = Icons.Default.FormatSize,
|
|
|
onValueChange = { value ->
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.FooterFontSize(value.toInt())))
|
|
|
onIntent(ReadBookIntent.SaveReadStyleConfig)
|
|
|
},
|
|
|
)
|
|
|
TinyColorModeSettingItem(
|
|
|
- title = stringResource(R.string.title_color),
|
|
|
+ title = stringResource(R.string.color),
|
|
|
dayColor = if (config.tipFooterColor != 0) config.tipFooterColor else config.textColorDay,
|
|
|
nightColor = if (config.tipFooterColorNight != 0) config.tipFooterColorNight else config.textColorNight,
|
|
|
+ imageVector = Icons.Default.FormatColorText,
|
|
|
onClickColor = { isNight ->
|
|
|
if (isNight) {
|
|
|
onOpenColorPicker(TypographyColorTarget.FooterNight)
|
|
|
@@ -885,6 +953,7 @@ internal fun TypographyMarginTab(
|
|
|
title = stringResource(R.string.title_margin_top),
|
|
|
value = titleTopSpacing.toFloat(),
|
|
|
valueRange = 0f..200f,
|
|
|
+ imageVector = Icons.Default.VerticalAlignTop,
|
|
|
onValueChange = { value ->
|
|
|
titleTopSpacing = value.toInt()
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleTopSpacing(titleTopSpacing)))
|
|
|
@@ -894,6 +963,7 @@ internal fun TypographyMarginTab(
|
|
|
title = stringResource(R.string.title_margin_bottom),
|
|
|
value = titleBottomSpacing.toFloat(),
|
|
|
valueRange = 0f..200f,
|
|
|
+ imageVector = Icons.Default.VerticalAlignBottom,
|
|
|
onValueChange = { value ->
|
|
|
titleBottomSpacing = value.toInt()
|
|
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleBottomSpacing(titleBottomSpacing)))
|