Skip to content

Commit

Permalink
Allow changing icon size in widgets #451
Browse files Browse the repository at this point in the history
  • Loading branch information
Waboodoo committed Dec 12, 2024
1 parent 1006b7f commit 931e010
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ fun MainScreen(
showLabel = result.showLabel,
showIcon = result.showIcon,
labelColor = result.labelColor,
iconScale = result.iconScale,
)
}
RESULT_WIDGET_SETTINGS_CANCELLED -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,10 @@ constructor(
showLabel: Boolean,
showIcon: Boolean,
labelColor: String?,
iconScale: Float,
) {
val widgetId = initData.widgetId ?: return
widgetManager.createWidget(widgetId, shortcutId, showLabel, showIcon, labelColor)
widgetManager.createWidget(widgetId, shortcutId, showLabel, showIcon, labelColor, iconScale)
widgetManager.updateWidgets(context, shortcutId)
finish(
intent = WidgetManager.getIntent(widgetId),
Expand Down Expand Up @@ -514,9 +515,15 @@ constructor(
private fun getShortcutById(shortcutId: ShortcutId): Shortcut? =
categories.findShortcut(shortcutId)

fun onWidgetSettingsSubmitted(shortcutId: ShortcutId, showLabel: Boolean, showIcon: Boolean, labelColor: String?) = runAction {
fun onWidgetSettingsSubmitted(
shortcutId: ShortcutId,
showLabel: Boolean,
showIcon: Boolean,
labelColor: String?,
iconScale: Float,
) = runAction {
logInfo("Widget settings submitted")
returnForHomeScreenWidgetPlacement(shortcutId, showLabel, showIcon, labelColor)
returnForHomeScreenWidgetPlacement(shortcutId, showLabel, showIcon, labelColor, iconScale)
}

fun onShortcutEdited() = runAction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.rememberScrollState
Expand All @@ -24,22 +26,27 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import ch.rmy.android.http_shortcuts.R
import ch.rmy.android.http_shortcuts.components.Checkbox
import ch.rmy.android.http_shortcuts.components.OrderedOptionsSlider
import ch.rmy.android.http_shortcuts.components.SettingsButton
import ch.rmy.android.http_shortcuts.components.ShortcutIcon
import ch.rmy.android.http_shortcuts.components.Spacing
import ch.rmy.android.http_shortcuts.icons.ShortcutIcon as ShortcutIconModel

private val ICON_SCALE_OPTIONS = arrayOf(0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1f)

@Composable
fun WidgetSettingsContent(
showLabel: Boolean,
showIcon: Boolean,
labelColor: Color,
labelColorText: String,
iconScale: Float,
shortcutName: String,
shortcutIcon: ShortcutIconModel,
onShowLabelChanged: (Boolean) -> Unit,
onShowIconChanged: (Boolean) -> Unit,
onLabelColorButtonClicked: () -> Unit,
onIconScaleChanged: (Float) -> Unit,
) {
Column(
modifier = Modifier
Expand All @@ -57,31 +64,51 @@ fun WidgetSettingsContent(
showLabel = showLabel,
showIcon = showIcon,
labelColor = labelColor,
iconScale = iconScale,
shortcutName = shortcutName,
shortcutIcon = shortcutIcon,
)
}

HorizontalDivider()

Checkbox(
checked = showLabel,
enabled = showIcon,
label = stringResource(R.string.label_show_widget_label),
onCheckedChange = onShowLabelChanged,
)

HorizontalDivider()

Checkbox(
checked = showIcon,
enabled = showLabel,
label = stringResource(R.string.label_show_widget_icon),
onCheckedChange = onShowIconChanged,
)

Column(
verticalArrangement = Arrangement.spacedBy(Spacing.SMALL),
modifier = Modifier.padding(Spacing.MEDIUM),
) {
Text(
text = stringResource(R.string.label_widget_icon_size),
)
OrderedOptionsSlider(
modifier = Modifier
.fillMaxWidth(),
options = ICON_SCALE_OPTIONS,
enabled = showIcon,
value = iconScale,
onValueChange = {
onIconScaleChanged(it)
},
)

Spacer(modifier = Modifier.height(Spacing.TINY))
}

HorizontalDivider()

Checkbox(
checked = showLabel,
enabled = showIcon,
label = stringResource(R.string.label_show_widget_label),
onCheckedChange = onShowLabelChanged,
)

SettingsButton(
enabled = showLabel,
title = stringResource(R.string.label_widget_label_color),
Expand All @@ -98,19 +125,24 @@ private fun WidgetPreview(
showLabel: Boolean,
showIcon: Boolean,
labelColor: Color,
iconScale: Float = 1f,
shortcutName: String,
shortcutIcon: ShortcutIconModel,
) {
Column(
modifier = Modifier
.background(colorResource(R.color.widget_preview_background), RoundedCornerShape(Spacing.TINY))
.sizeIn(minWidth = 100.dp, minHeight = 100.dp)
.sizeIn(minWidth = 100.dp, minHeight = 120.dp)
.padding(Spacing.SMALL),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(Spacing.SMALL, Alignment.CenterVertically)
) {
if (showIcon) {
ShortcutIcon(shortcutIcon)
ShortcutIcon(
shortcutIcon,
size = 44.dp * iconScale,
)
Spacer(modifier = Modifier.height(22.dp * (1f - iconScale)))
}

if (showLabel) {
Expand Down Expand Up @@ -144,6 +176,7 @@ private fun WidgetPreview_Preview2() {
WidgetPreview(
showLabel = true,
showIcon = true,
iconScale = 0.5f,
labelColor = Color.Red,
shortcutName = "Shortcut with a rather long text",
shortcutIcon = ShortcutIconModel.NoIcon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ fun WidgetSettingsScreen(
showIcon = viewState.showIcon,
labelColor = Color(viewState.labelColor),
labelColorText = viewState.labelColorFormatted,
iconScale = viewState.iconScale,
shortcutName = viewState.shortcutName,
shortcutIcon = viewState.shortcutIcon,
onShowLabelChanged = viewModel::onShowLabelChanged,
onShowIconChanged = viewModel::onShowIconChanged,
onLabelColorButtonClicked = viewModel::onLabelColorButtonClicked,
onIconScaleChanged = viewModel::onIconScaleChanged,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ constructor(
showLabel = widget?.showLabel != false,
showIcon = widget?.showIcon != false,
labelColor = widget?.labelColorInt() ?: Color.WHITE,
iconScale = widget?.iconScale ?: 1f,
shortcutIcon = shortcutIcon,
shortcutName = shortcutName,
)
Expand Down Expand Up @@ -74,13 +75,20 @@ constructor(
}
}

fun onIconScaleChanged(scale: Float) = runAction {
updateViewState {
copy(iconScale = scale)
}
}

fun onCreateButtonClicked() = runAction {
closeScreen(
result = NavigationDestination.Widget.Result(
shortcutId = shortcutId,
labelColor = viewState.labelColorFormatted,
showLabel = viewState.showLabel,
showIcon = viewState.showIcon,
iconScale = viewState.iconScale,
),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ data class WidgetSettingsViewState(
val showLabel: Boolean,
val showIcon: Boolean,
val labelColor: Int,
val iconScale: Float,
val shortcutName: String,
val shortcutIcon: ShortcutIcon,
val colorDialogVisible: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import androidx.compose.ui.Modifier
fun <T : Comparable<T>> OrderedOptionsSlider(
options: Array<T>,
value: T,
enabled: Boolean = true,
onValueChange: (T) -> Unit,
modifier: Modifier = Modifier,
) {
Slider(
modifier = modifier,
valueRange = 0f..(options.lastIndex.toFloat()),
enabled = enabled,
value = (
options.indexOfFirst { it >= value }
.takeUnless { it == -1 }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ch.rmy.android.http_shortcuts.components

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
Expand All @@ -9,6 +11,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import ch.rmy.android.http_shortcuts.R
Expand Down Expand Up @@ -40,15 +43,25 @@ fun ShortcutIcon(
.build()
}

val modifier = Modifier
.size(size)
.then(modifier)
.runIf(shortcutIcon.isCircular) {
clip(CircleShape)
}

val inPreview = LocalInspectionMode.current
if (inPreview) {
Box(
modifier = modifier.background(Color.Cyan),
)
return
}

AsyncImage(
model = model,
contentDescription = contentDescription,
colorFilter = tint?.let { ColorFilter.tint(tint) },
modifier = Modifier
.size(size)
.then(modifier)
.runIf(shortcutIcon.isCircular) {
clip(CircleShape)
},
modifier = modifier,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ constructor(
showLabel: Boolean,
showIcon: Boolean,
labelColor: String?,
iconScale: Float,
) {
commitTransaction {
copyOrUpdate(
Expand All @@ -31,6 +32,7 @@ constructor(
showLabel = showLabel,
showIcon = showIcon,
labelColor = labelColor,
iconScale = iconScale,
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ class DatabaseMigration : AutomaticSchemaMigration {
}
}

if (oldVersion < 84 && oldVersion >= 36) {
migrationContext.enumerate("Widget") { _, newWidget ->
newWidget?.set("iconScale", 1f)
}
}

// update version number
newRealm.query("Base")
.first()
Expand All @@ -281,7 +287,7 @@ class DatabaseMigration : AutomaticSchemaMigration {
}

companion object {
const val VERSION = 83L
const val VERSION = 84L
const val COMPATIBILITY_VERSION = 78L
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ class Widget() : RealmObject {
labelColor: String? = null,
showLabel: Boolean = true,
showIcon: Boolean = true,
iconScale: Float = 1f,
) : this() {
this.widgetId = widgetId
this.shortcut = shortcut
this.labelColor = labelColor
this.showLabel = showLabel
this.showIcon = showIcon
this.iconScale = iconScale
}

@PrimaryKey
Expand All @@ -25,6 +27,7 @@ class Widget() : RealmObject {
var labelColor: String? = null
var showLabel: Boolean = true
var showIcon: Boolean = true
var iconScale: Float = 1f

companion object {
const val FIELD_WIDGET_ID = "widgetId"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ sealed interface NavigationDestination {
val labelColor: String,
val showLabel: Boolean,
val showIcon: Boolean,
val iconScale: Float,
) : Serializable

const val RESULT_WIDGET_SETTINGS_CANCELLED = "widget-settings-cancelled"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ constructor(
showLabel: Boolean,
showIcon: Boolean,
labelColor: String?,
iconScale: Float,
) {
widgetsRepository.createWidget(widgetId, shortcutId, showLabel, showIcon, labelColor)
widgetsRepository.createWidget(widgetId, shortcutId, showLabel, showIcon, labelColor, iconScale)
}

suspend fun updateWidgets(context: Context, widgetIds: List<Int>) {
Expand Down Expand Up @@ -73,6 +74,8 @@ constructor(
views.setInt(R.id.widget_label, "setLines", 2)
}
views.setImageViewIcon(R.id.widget_icon, IconUtil.getIcon(context, shortcut.icon, adaptive = false))
views.setFloat(R.id.widget_icon, "setScaleX", widget.iconScale)
views.setFloat(R.id.widget_icon, "setScaleY", widget.iconScale)
} else {
views.setInt(R.id.widget_label, "setMaxLines", 4)
views.setViewVisibility(R.id.widget_icon, View.GONE)
Expand Down
2 changes: 2 additions & 0 deletions HTTPShortcuts/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,8 @@
<string name="label_widget">Customizable Widget</string>
<!-- Label: Shown when configuring a widget, next to checkbox, allows to show/hide the label of a widget -->
<string name="label_show_widget_label">Show Label</string>
<!-- Label: Shown when configuring a widget, above a slider, to choose the size of the widget's icon -->
<string name="label_widget_icon_size">Icon Size</string>
<!-- Label: Shown when configuring a widget, next to checkbox, allows to show/hide the icon of a widget -->
<string name="label_show_widget_icon">Show Icon</string>
<!-- Action label: Shown on button to confirm the creation of a widget, after configuring it -->
Expand Down

0 comments on commit 931e010

Please sign in to comment.