From 748e3c6090bdc9ce59e280309f902ae1ac295556 Mon Sep 17 00:00:00 2001 From: Yuri Volkov Date: Mon, 8 Jan 2024 18:15:50 +0300 Subject: [PATCH] #88 "Text shadow" option added to Colors section with these values: "No shadow" (default, nothing changes for existing widgets), "Dark shadow" and "Light shadow". For simplicity the same shadow applies to all parts of the widget. --- README.md | 16 ++- app/build.gradle | 4 +- .../todoagenda/EnvironmentChangedReceiver.kt | 4 +- .../todoagenda/RemoteViewsFactory.kt | 5 +- .../prefs/ApplicationPreferences.kt | 15 +++ .../todoagenda/prefs/InstanceSettings.kt | 24 +++- .../prefs/colors/ColorsPreferencesFragment.kt | 15 ++- .../todoagenda/widget/DayHeaderVisualizer.kt | 3 +- .../todoagenda/widget/EventEntryLayout.kt | 7 +- .../andstatus/todoagenda/widget/LastEntry.kt | 11 +- .../todoagenda/widget/LastEntryVisualizer.kt | 2 +- .../andstatus/todoagenda/widget/TextShadow.kt | 23 ++++ .../widget/WidgetEntryVisualizer.kt | 2 +- .../todoagenda/widget/WidgetHeaderLayout.kt | 9 +- .../todoagenda/widget/WidgetLayout.kt | 33 +++++ ...day_header_separator_above_shadow_dark.xml | 43 +++++++ ...ay_header_separator_above_shadow_light.xml | 43 +++++++ ...day_header_separator_below_shadow_dark.xml | 43 +++++++ ...ay_header_separator_below_shadow_light.xml | 43 +++++++ .../event_entry_one_line_shadow_dark.xml | 118 ++++++++++++++++++ .../event_entry_one_line_shadow_light.xml | 118 ++++++++++++++++++ .../res/layout/event_entry_shadow_dark.xml | 83 ++++++++++++ .../res/layout/event_entry_shadow_light.xml | 83 ++++++++++++ .../layout/item_empty_list_shadow_dark.xml | 15 +++ .../layout/item_empty_list_shadow_light.xml | 15 +++ .../main/res/layout/item_last_shadow_dark.xml | 14 +++ .../res/layout/item_last_shadow_light.xml | 14 +++ .../item_no_permissions_shadow_dark.xml | 15 +++ .../item_no_permissions_shadow_light.xml | 15 +++ .../layout/item_not_loaded_shadow_dark.xml | 14 +++ .../layout/item_not_loaded_shadow_light.xml | 14 +++ .../widget_header_one_row_shadow_dark.xml | 69 ++++++++++ .../widget_header_one_row_shadow_light.xml | 69 ++++++++++ .../widget_header_two_rows_shadow_dark.xml | 76 +++++++++++ .../widget_header_two_rows_shadow_light.xml | 76 +++++++++++ .../res/layout/widget_initial_shadow_dark.xml | 74 +++++++++++ .../layout/widget_initial_shadow_light.xml | 74 +++++++++++ app/src/main/res/values-ru/strings.xml | 4 + app/src/main/res/values/arrays.xml | 10 ++ app/src/main/res/values/colors.xml | 6 +- app/src/main/res/values/strings.xml | 4 + app/src/main/res/xml/preferences_colors.xml | 7 ++ 42 files changed, 1299 insertions(+), 33 deletions(-) create mode 100644 app/src/main/kotlin/org/andstatus/todoagenda/widget/TextShadow.kt create mode 100644 app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetLayout.kt create mode 100644 app/src/main/res/layout/day_header_separator_above_shadow_dark.xml create mode 100644 app/src/main/res/layout/day_header_separator_above_shadow_light.xml create mode 100644 app/src/main/res/layout/day_header_separator_below_shadow_dark.xml create mode 100644 app/src/main/res/layout/day_header_separator_below_shadow_light.xml create mode 100644 app/src/main/res/layout/event_entry_one_line_shadow_dark.xml create mode 100644 app/src/main/res/layout/event_entry_one_line_shadow_light.xml create mode 100644 app/src/main/res/layout/event_entry_shadow_dark.xml create mode 100644 app/src/main/res/layout/event_entry_shadow_light.xml create mode 100644 app/src/main/res/layout/item_empty_list_shadow_dark.xml create mode 100644 app/src/main/res/layout/item_empty_list_shadow_light.xml create mode 100644 app/src/main/res/layout/item_last_shadow_dark.xml create mode 100644 app/src/main/res/layout/item_last_shadow_light.xml create mode 100644 app/src/main/res/layout/item_no_permissions_shadow_dark.xml create mode 100644 app/src/main/res/layout/item_no_permissions_shadow_light.xml create mode 100644 app/src/main/res/layout/item_not_loaded_shadow_dark.xml create mode 100644 app/src/main/res/layout/item_not_loaded_shadow_light.xml create mode 100644 app/src/main/res/layout/widget_header_one_row_shadow_dark.xml create mode 100644 app/src/main/res/layout/widget_header_one_row_shadow_light.xml create mode 100644 app/src/main/res/layout/widget_header_two_rows_shadow_dark.xml create mode 100644 app/src/main/res/layout/widget_header_two_rows_shadow_light.xml create mode 100644 app/src/main/res/layout/widget_initial_shadow_dark.xml create mode 100644 app/src/main/res/layout/widget_initial_shadow_light.xml diff --git a/README.md b/README.md index c1bfa525..6470fe42 100644 --- a/README.md +++ b/README.md @@ -85,12 +85,16 @@ In particular, see these solutions: ## Changelog - + +### 2024-01-08 v4.9.0 Text shadow and Event description +* "Text shadow" option added to Colors section with these values: "No shadow" (default, nothing changes for existing widgets), + "Dark shadow" and "Light shadow". For simplicity the same shadow applies to all parts of the widget. + [#88](https://github.com/andstatus/todoagenda/issues/88) +* Event details -> "Description" option added to show Calendar event Description. + [#78](https://github.com/andstatus/todoagenda/issues/78) +* Added settings to limit maximum number of lines for an event's title and for details (i.e. for time, + location and description). [#109](https://github.com/andstatus/todoagenda/issues/109). diff --git a/app/build.gradle b/app/build.gradle index a7d615a5..58c67f29 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { } defaultConfig { - versionCode 704 - versionName '4.8.0' + versionCode 705 + versionName '4.9.0' minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/EnvironmentChangedReceiver.kt b/app/src/main/kotlin/org/andstatus/todoagenda/EnvironmentChangedReceiver.kt index d469c955..b41fe6dd 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/EnvironmentChangedReceiver.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/EnvironmentChangedReceiver.kt @@ -17,6 +17,7 @@ import org.andstatus.todoagenda.util.CalendarIntentUtil import org.andstatus.todoagenda.util.DateUtil import org.andstatus.todoagenda.util.PermissionsUtil import org.andstatus.todoagenda.widget.WidgetEntry +import org.andstatus.todoagenda.widget.WidgetLayout import org.joda.time.DateTime import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicReference @@ -118,7 +119,8 @@ class EnvironmentChangedReceiver : BroadcastReceiver() { private fun gotoPosition(context: Context, widgetId: Int, position: Int) { if (widgetId == 0 || position < 0) return val appWidgetManager = AppWidgetManager.getInstance(context) - val rv = RemoteViews(context.packageName, R.layout.widget_initial) + val settings = AllSettings.instanceFromId(context, widgetId) + val rv = RemoteViews(context.packageName, WidgetLayout.WIDGET_INITIAL.shadowed(settings.textShadow)) Log.d(TAG, "gotoPosition, Scrolling widget $widgetId to position $position") rv.setScrollPosition(R.id.event_list, position) appWidgetManager.updateAppWidget(widgetId, rv) diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/RemoteViewsFactory.kt b/app/src/main/kotlin/org/andstatus/todoagenda/RemoteViewsFactory.kt index b6afa792..fb78feb2 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/RemoteViewsFactory.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/RemoteViewsFactory.kt @@ -29,6 +29,7 @@ import org.andstatus.todoagenda.widget.WidgetEntry import org.andstatus.todoagenda.widget.WidgetEntryPosition import org.andstatus.todoagenda.widget.WidgetEntryVisualizer import org.andstatus.todoagenda.widget.WidgetHeaderLayout +import org.andstatus.todoagenda.widget.WidgetLayout import org.joda.time.DateTime import java.util.Locale import java.util.concurrent.ConcurrentHashMap @@ -295,7 +296,7 @@ class RemoteViewsFactory(val context: Context, private val widgetId: Int, create return } val settings = AllSettings.instanceFromId(context, widgetId) - val rv = RemoteViews(context.packageName, R.layout.widget_initial) + val rv = RemoteViews(context.packageName, WidgetLayout.WIDGET_INITIAL.shadowed(settings.textShadow)) settings.clock().updateZone() configureWidgetHeader(settings, rv) configureWidgetEntriesList(settings, rv) @@ -311,7 +312,7 @@ class RemoteViewsFactory(val context: Context, private val widgetId: Int, create if (settings.widgetHeaderLayout != WidgetHeaderLayout.HIDDEN) { val headerView = RemoteViews( settings.context.packageName, - settings.widgetHeaderLayout.layoutId + settings.widgetHeaderLayout.widgetLayout?.shadowed(settings.textShadow) ?: 0 ) rv.addView(R.id.header_parent, headerView) RemoteViewsUtil.setBackgroundColor( diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/prefs/ApplicationPreferences.kt b/app/src/main/kotlin/org/andstatus/todoagenda/prefs/ApplicationPreferences.kt index 8fc39b82..13a77fd8 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/prefs/ApplicationPreferences.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/prefs/ApplicationPreferences.kt @@ -3,6 +3,7 @@ package org.andstatus.todoagenda.prefs import android.content.Context import android.text.TextUtils import androidx.preference.PreferenceManager +import org.andstatus.todoagenda.prefs.InstanceSettings.Companion.PREF_TEXT_SHADOW import org.andstatus.todoagenda.prefs.colors.BackgroundColorPref import org.andstatus.todoagenda.prefs.colors.ColorThemeType import org.andstatus.todoagenda.prefs.colors.TextColorPref @@ -11,6 +12,7 @@ import org.andstatus.todoagenda.prefs.colors.ThemeColors import org.andstatus.todoagenda.prefs.dateformat.DateFormatValue import org.andstatus.todoagenda.util.StringUtil import org.andstatus.todoagenda.widget.EventEntryLayout +import org.andstatus.todoagenda.widget.TextShadow import org.andstatus.todoagenda.widget.WidgetHeaderLayout object ApplicationPreferences { @@ -34,6 +36,7 @@ object ApplicationPreferences { setFillAllDayEvents(context, settings.fillAllDayEvents) setHideBasedOnKeywords(context, settings.hideBasedOnKeywords) setShowBasedOnKeywords(context, settings.showBasedOnKeywords) + val colors = settings.colors() setString(context, PREF_COLOR_THEME_TYPE, colors.colorThemeType.value) setBoolean(context, PREF_DIFFERENT_COLORS_FOR_DARK, colors.colorThemeType != ColorThemeType.SINGLE) @@ -45,6 +48,8 @@ object ApplicationPreferences { setString(context, pref.shadingPreferenceName, colors.getTextShadingStored(pref).shading.themeName) setInt(context, pref.colorPreferenceName, colors.getTextColorStored(pref).color) } + setString(context, PREF_TEXT_SHADOW, settings.textShadow.value) + setShowDaysWithoutEvents(context, settings.showDaysWithoutEvents) setShowDayHeaders(context, settings.showDayHeaders) setDateFormat(context, InstanceSettings.PREF_DAY_HEADER_DATE_FORMAT, settings.dayHeaderDateFormat) @@ -209,6 +214,16 @@ object ApplicationPreferences { ) } + fun getTextShadow(context: Context): TextShadow { + return TextShadow.fromValue( + getString( + context, + PREF_TEXT_SHADOW, + TextShadow.NO_SHADOW.value + ) + ) + } + fun getHorizontalLineBelowDayHeader(context: Context?): Boolean { return getBoolean(context, InstanceSettings.PREF_HORIZONTAL_LINE_BELOW_DAY_HEADER, false) } diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/prefs/InstanceSettings.kt b/app/src/main/kotlin/org/andstatus/todoagenda/prefs/InstanceSettings.kt index a2126006..9fb540dc 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/prefs/InstanceSettings.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/prefs/InstanceSettings.kt @@ -15,6 +15,7 @@ import org.andstatus.todoagenda.util.MyClock import org.andstatus.todoagenda.util.StringUtil import org.andstatus.todoagenda.widget.Alignment import org.andstatus.todoagenda.widget.EventEntryLayout +import org.andstatus.todoagenda.widget.TextShadow import org.andstatus.todoagenda.widget.WidgetHeaderLayout import org.joda.time.DateTime import org.json.JSONException @@ -67,6 +68,11 @@ class InstanceSettings(private val contextIn: Context?, val widgetId: Int, propo // Colors private var defaultColors: ThemeColors private var darkColors: ThemeColors = ThemeColors.EMPTY + var textShadow: TextShadow = TextShadow.NO_SHADOW + private set + + // ---------------------------------------------------------------------------------- + // ,,, var showEndTime = PREF_SHOW_END_TIME_DEFAULT private set var showLocation = PREF_SHOW_LOCATION_DEFAULT @@ -165,6 +171,10 @@ class InstanceSettings(private val contextIn: Context?, val widgetId: Int, propo PREF_DARK_THEME ) ) else ThemeColors.EMPTY + if (json.has(PREF_TEXT_SHADOW)) { + textShadow = TextShadow.fromValue(json.getString(PREF_TEXT_SHADOW)) + } + if (json.has(PREF_SHOW_DAYS_WITHOUT_EVENTS)) { showDaysWithoutEvents = json.getBoolean(PREF_SHOW_DAYS_WITHOUT_EVENTS) } @@ -326,6 +336,8 @@ class InstanceSettings(private val contextIn: Context?, val widgetId: Int, propo ) } } + textShadow = ApplicationPreferences.getTextShadow(context) + showDaysWithoutEvents = ApplicationPreferences.getShowDaysWithoutEvents(context) showDayHeaders = ApplicationPreferences.getShowDayHeaders(context) dayHeaderDateFormat = ApplicationPreferences.getDayHeaderDateFormat(context) @@ -372,7 +384,11 @@ class InstanceSettings(private val contextIn: Context?, val widgetId: Int, propo } init { - widgetInstanceName = if (contextIn == null) "(empty)" else AllSettings.uniqueInstanceName(context, widgetId, proposedInstanceName) + widgetInstanceName = if (contextIn == null) "(empty)" else AllSettings.uniqueInstanceName( + context, + widgetId, + proposedInstanceName + ) defaultColors = if (contextIn == null) ThemeColors.EMPTY else ThemeColors(context, ColorThemeType.SINGLE) } @@ -419,6 +435,7 @@ class InstanceSettings(private val contextIn: Context?, val widgetId: Int, propo if (!darkColors.isEmpty) { json.put(PREF_DARK_THEME, darkColors.toJson(JSONObject())) } + json.put(PREF_TEXT_SHADOW, textShadow.value) json.put(PREF_SHOW_DAYS_WITHOUT_EVENTS, showDaysWithoutEvents) json.put(PREF_SHOW_DAY_HEADERS, showDayHeaders) json.put(PREF_DAY_HEADER_DATE_FORMAT, dayHeaderDateFormat.save()) @@ -634,6 +651,11 @@ ${toJson()}""" const val PREF_MAXLINES_DETAILS_DEFAULT = 5 const val PREF_DARK_THEME = "darkTheme" + // ---------------------------------------------------------------------------------- + // Color + const val PREF_TEXT_SHADOW = "textShadow" + val PREF_TEXT_SHADOW_DEFAULT = TextShadow.NO_SHADOW.name + // ---------------------------------------------------------------------------------- // Event details const val PREF_SHOW_END_TIME = "showEndTime" diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/prefs/colors/ColorsPreferencesFragment.kt b/app/src/main/kotlin/org/andstatus/todoagenda/prefs/colors/ColorsPreferencesFragment.kt index edd20e66..e482bade 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/prefs/colors/ColorsPreferencesFragment.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/prefs/colors/ColorsPreferencesFragment.kt @@ -15,7 +15,9 @@ import org.andstatus.todoagenda.R import org.andstatus.todoagenda.WidgetConfigurationActivity import org.andstatus.todoagenda.prefs.ApplicationPreferences import org.andstatus.todoagenda.prefs.InstanceSettings +import org.andstatus.todoagenda.prefs.InstanceSettings.Companion.PREF_TEXT_SHADOW import org.andstatus.todoagenda.prefs.MyPreferenceFragment +import org.andstatus.todoagenda.widget.TextShadow import org.andstatus.todoagenda.widget.TimeSection import java.util.Arrays import java.util.stream.Collectors @@ -41,6 +43,7 @@ class ColorsPreferencesFragment : MyPreferenceFragment(), OnSharedPreferenceChan removeUnavailablePreferences() preferenceManager.sharedPreferences!!.registerOnSharedPreferenceChangeListener(this) showTextSources() + showTextShadow() } private fun showTextSources() { @@ -133,10 +136,17 @@ class ColorsPreferencesFragment : MyPreferenceFragment(), OnSharedPreferenceChan } } + private fun showTextShadow() { + findPreference(PREF_TEXT_SHADOW)?.let { preference -> + TextShadow.fromValue(preference.value).let { textShadow -> + preference.summary = requireActivity().getString(textShadow.titleResId) + } + } + } + private fun showShadings() { for (shadingPref in TextColorPref.entries) { - val preference = findPreference(shadingPref.shadingPreferenceName) - if (preference != null) { + findPreference(shadingPref.shadingPreferenceName)?.let { preference -> val shading: Shading = Shading.fromThemeName(preference.value, shadingPref.defaultShading) preference.summary = requireActivity().getString(shading.titleResId) } @@ -180,6 +190,7 @@ class ColorsPreferencesFragment : MyPreferenceFragment(), OnSharedPreferenceChan else -> { saveSettings() showTextSources() + showTextShadow() } } } diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/widget/DayHeaderVisualizer.kt b/app/src/main/kotlin/org/andstatus/todoagenda/widget/DayHeaderVisualizer.kt index e52ccf4f..2f8eed87 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/widget/DayHeaderVisualizer.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/widget/DayHeaderVisualizer.kt @@ -28,7 +28,8 @@ class DayHeaderVisualizer(context: Context, widgetId: Int) : val entry = eventEntry as DayHeader val rv = RemoteViews( context.packageName, - if (horizontalLineBelowDayHeader) R.layout.day_header_separator_below else R.layout.day_header_separator_above + if (horizontalLineBelowDayHeader) WidgetLayout.DAY_HEADER_SEPARATOR_BELOW.shadowed(settings.textShadow) + else WidgetLayout.DAY_HEADER_SEPARATOR_ABOVE.shadowed(settings.textShadow) ) rv.setInt(R.id.day_header_title_wrapper, "setGravity", alignment.gravity) val textColorPref: TextColorPref = TextColorPref.forDayHeader(entry) diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/widget/EventEntryLayout.kt b/app/src/main/kotlin/org/andstatus/todoagenda/widget/EventEntryLayout.kt index 3df3947c..681b700c 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/widget/EventEntryLayout.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/widget/EventEntryLayout.kt @@ -1,6 +1,5 @@ package org.andstatus.todoagenda.widget -import androidx.annotation.LayoutRes import androidx.annotation.StringRes import org.andstatus.todoagenda.R @@ -8,12 +7,12 @@ import org.andstatus.todoagenda.R * @author yvolk@yurivolkov.com */ enum class EventEntryLayout( - @field:LayoutRes @param:LayoutRes val layoutId: Int, + val widgetLayout: WidgetLayout, val value: String, @field:StringRes val summaryResId: Int ) { - DEFAULT(R.layout.event_entry, "DEFAULT", R.string.default_multiline_layout), - ONE_LINE(R.layout.event_entry_one_line, "ONE_LINE", R.string.single_line_layout); + DEFAULT(WidgetLayout.EVENT_ENTRY_DEFAULT, "DEFAULT", R.string.default_multiline_layout), + ONE_LINE(WidgetLayout.EVENT_ENTRY_ONE_LINE, "ONE_LINE", R.string.single_line_layout); companion object { const val SPACE_PIPE_SPACE = " | " diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/widget/LastEntry.kt b/app/src/main/kotlin/org/andstatus/todoagenda/widget/LastEntry.kt index 19db6463..452d869c 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/widget/LastEntry.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/widget/LastEntry.kt @@ -1,6 +1,5 @@ package org.andstatus.todoagenda.widget -import org.andstatus.todoagenda.R import org.andstatus.todoagenda.prefs.InstanceSettings import org.andstatus.todoagenda.prefs.OrderedEventSource import org.andstatus.todoagenda.util.PermissionsUtil @@ -13,11 +12,11 @@ class LastEntry(settings: InstanceSettings, val type: LastEntryType, date: DateT override val source: OrderedEventSource get() = OrderedEventSource.LAST_ENTRY - enum class LastEntryType(val layoutId: Int) { - NOT_LOADED(R.layout.item_not_loaded), - NO_PERMISSIONS(R.layout.item_no_permissions), - EMPTY(R.layout.item_empty_list), - LAST(R.layout.item_last) + enum class LastEntryType(val widgetLayout: WidgetLayout) { + NOT_LOADED(WidgetLayout.ITEM_NOT_LOADED), + NO_PERMISSIONS(WidgetLayout.ITEM_NO_PERMISSIONS), + EMPTY(WidgetLayout.ITEM_EMPTY_LIST), + LAST(WidgetLayout.ITEM_LAST) } companion object { diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/widget/LastEntryVisualizer.kt b/app/src/main/kotlin/org/andstatus/todoagenda/widget/LastEntryVisualizer.kt index 7af34692..dfdbbdc5 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/widget/LastEntryVisualizer.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/widget/LastEntryVisualizer.kt @@ -22,7 +22,7 @@ class LastEntryVisualizer(context: Context, widgetId: Int) : override fun getRemoteViews(eventEntry: WidgetEntry<*>, position: Int): RemoteViews { val entry = eventEntry as LastEntry Log.d(TAG, "lastEntry: " + entry.type) - val rv = RemoteViews(context.packageName, entry.type.layoutId) + val rv = RemoteViews(context.packageName, entry.type.widgetLayout.shadowed(settings.textShadow)) val viewId = R.id.event_entry if (position < 0) { rv.setOnClickPendingIntent( diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/widget/TextShadow.kt b/app/src/main/kotlin/org/andstatus/todoagenda/widget/TextShadow.kt new file mode 100644 index 00000000..7c6d2471 --- /dev/null +++ b/app/src/main/kotlin/org/andstatus/todoagenda/widget/TextShadow.kt @@ -0,0 +1,23 @@ +package org.andstatus.todoagenda.widget + +import androidx.annotation.StringRes +import org.andstatus.todoagenda.R + +enum class TextShadow(val value: String, + @field:StringRes val titleResId: Int, + ) { + NO_SHADOW("no", R.string.text_shadow_no_shadow), + DARK_SHADOW("dark", R.string.text_shadow_dark), + LIGHT_SHADOW("light", R.string.text_shadow_light); + + companion object { + fun fromValue(value: String?): TextShadow { + for (item in entries) { + if (item.value == value) { + return item + } + } + return NO_SHADOW + } + } +} diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetEntryVisualizer.kt b/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetEntryVisualizer.kt index 2992d5fd..0d4e180f 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetEntryVisualizer.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetEntryVisualizer.kt @@ -14,7 +14,7 @@ import org.andstatus.todoagenda.util.RemoteViewsUtil abstract class WidgetEntryVisualizer>(protected val eventProvider: EventProvider) { open fun getRemoteViews(entry: WidgetEntry<*>, position: Int): RemoteViews { - val rv = RemoteViews(context.packageName, settings.eventEntryLayout.layoutId) + val rv = RemoteViews(context.packageName, settings.eventEntryLayout.widgetLayout.shadowed(settings.textShadow)) setTitle(entry, rv) setDetails(entry, rv) setDate(entry, rv) diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetHeaderLayout.kt b/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetHeaderLayout.kt index 7f3e180d..480cf67f 100644 --- a/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetHeaderLayout.kt +++ b/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetHeaderLayout.kt @@ -1,6 +1,5 @@ package org.andstatus.todoagenda.widget -import androidx.annotation.LayoutRes import androidx.annotation.StringRes import org.andstatus.todoagenda.R @@ -8,13 +7,13 @@ import org.andstatus.todoagenda.R * @author yvolk@yurivolkov.com */ enum class WidgetHeaderLayout( - @field:LayoutRes @param:LayoutRes val layoutId: Int, + val widgetLayout: WidgetLayout?, val value: String, @field:StringRes @param:StringRes val summaryResId: Int ) { - ONE_ROW(R.layout.widget_header_one_row, "ONE_ROW", R.string.single_line_layout), - TWO_ROWS(R.layout.widget_header_two_rows, "TWO_ROWS", R.string.two_rows_layout), - HIDDEN(0, "HIDDEN", R.string.hidden); + ONE_ROW(WidgetLayout.WIDGET_HEADER_ONE_ROW, "ONE_ROW", R.string.single_line_layout), + TWO_ROWS(WidgetLayout.WIDGET_HEADER_TWO_ROWS, "TWO_ROWS", R.string.two_rows_layout), + HIDDEN(null, "HIDDEN", R.string.hidden); companion object { var defaultValue = ONE_ROW diff --git a/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetLayout.kt b/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetLayout.kt new file mode 100644 index 00000000..b5e30287 --- /dev/null +++ b/app/src/main/kotlin/org/andstatus/todoagenda/widget/WidgetLayout.kt @@ -0,0 +1,33 @@ +package org.andstatus.todoagenda.widget + +import androidx.annotation.LayoutRes +import org.andstatus.todoagenda.R + +enum class WidgetLayout( + @field:LayoutRes @param:LayoutRes val noShadowLayoutId: Int, + @field:LayoutRes @param:LayoutRes val darkShadowLayoutId: Int, + @field:LayoutRes @param:LayoutRes val lightShadowLayoutId: Int, +) { + DAY_HEADER_SEPARATOR_ABOVE(R.layout.day_header_separator_above, R.layout.day_header_separator_above_shadow_dark, R.layout.day_header_separator_above_shadow_light), + DAY_HEADER_SEPARATOR_BELOW(R.layout.day_header_separator_below, R.layout.day_header_separator_below_shadow_dark, R.layout.day_header_separator_below_shadow_light), + EVENT_ENTRY_DEFAULT(R.layout.event_entry, R.layout.event_entry_shadow_dark, R.layout.event_entry_shadow_light), + EVENT_ENTRY_ONE_LINE(R.layout.event_entry_one_line, R.layout.event_entry_one_line_shadow_dark, R.layout.event_entry_one_line_shadow_light), + ITEM_EMPTY_LIST(R.layout.item_empty_list, R.layout.item_empty_list_shadow_dark, R.layout.item_empty_list_shadow_light), + ITEM_LAST(R.layout.item_last, R.layout.item_last_shadow_dark, R.layout.item_last_shadow_light), + ITEM_NO_PERMISSIONS(R.layout.item_no_permissions, R.layout.item_no_permissions_shadow_dark, R.layout.item_no_permissions_shadow_light), + ITEM_NOT_LOADED(R.layout.item_not_loaded, R.layout.item_not_loaded_shadow_dark, R.layout.item_not_loaded_shadow_light), + WIDGET_INITIAL(R.layout.widget_initial, R.layout.widget_initial_shadow_dark, R.layout.widget_initial_shadow_light), + WIDGET_HEADER_ONE_ROW(R.layout.widget_header_one_row, R.layout.widget_header_one_row_shadow_dark, R.layout.widget_header_one_row_shadow_light), + WIDGET_HEADER_TWO_ROWS(R.layout.widget_header_two_rows, R.layout.widget_header_two_rows_shadow_dark, R.layout.widget_header_two_rows_shadow_light), + + ; + + fun shadowed(textShadow: TextShadow?): Int = + when(textShadow) { + TextShadow.NO_SHADOW -> noShadowLayoutId + TextShadow.DARK_SHADOW -> darkShadowLayoutId + TextShadow.LIGHT_SHADOW -> lightShadowLayoutId + else -> noShadowLayoutId + } + +} diff --git a/app/src/main/res/layout/day_header_separator_above_shadow_dark.xml b/app/src/main/res/layout/day_header_separator_above_shadow_dark.xml new file mode 100644 index 00000000..75e778ce --- /dev/null +++ b/app/src/main/res/layout/day_header_separator_above_shadow_dark.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/day_header_separator_above_shadow_light.xml b/app/src/main/res/layout/day_header_separator_above_shadow_light.xml new file mode 100644 index 00000000..8c685c08 --- /dev/null +++ b/app/src/main/res/layout/day_header_separator_above_shadow_light.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/day_header_separator_below_shadow_dark.xml b/app/src/main/res/layout/day_header_separator_below_shadow_dark.xml new file mode 100644 index 00000000..b96e38f1 --- /dev/null +++ b/app/src/main/res/layout/day_header_separator_below_shadow_dark.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/day_header_separator_below_shadow_light.xml b/app/src/main/res/layout/day_header_separator_below_shadow_light.xml new file mode 100644 index 00000000..369dde09 --- /dev/null +++ b/app/src/main/res/layout/day_header_separator_below_shadow_light.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/event_entry_one_line_shadow_dark.xml b/app/src/main/res/layout/event_entry_one_line_shadow_dark.xml new file mode 100644 index 00000000..f289c0ca --- /dev/null +++ b/app/src/main/res/layout/event_entry_one_line_shadow_dark.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/event_entry_one_line_shadow_light.xml b/app/src/main/res/layout/event_entry_one_line_shadow_light.xml new file mode 100644 index 00000000..59082099 --- /dev/null +++ b/app/src/main/res/layout/event_entry_one_line_shadow_light.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/event_entry_shadow_dark.xml b/app/src/main/res/layout/event_entry_shadow_dark.xml new file mode 100644 index 00000000..34ee6bf8 --- /dev/null +++ b/app/src/main/res/layout/event_entry_shadow_dark.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/event_entry_shadow_light.xml b/app/src/main/res/layout/event_entry_shadow_light.xml new file mode 100644 index 00000000..5f284886 --- /dev/null +++ b/app/src/main/res/layout/event_entry_shadow_light.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_empty_list_shadow_dark.xml b/app/src/main/res/layout/item_empty_list_shadow_dark.xml new file mode 100644 index 00000000..d0ca5850 --- /dev/null +++ b/app/src/main/res/layout/item_empty_list_shadow_dark.xml @@ -0,0 +1,15 @@ + + + diff --git a/app/src/main/res/layout/item_empty_list_shadow_light.xml b/app/src/main/res/layout/item_empty_list_shadow_light.xml new file mode 100644 index 00000000..405bfe20 --- /dev/null +++ b/app/src/main/res/layout/item_empty_list_shadow_light.xml @@ -0,0 +1,15 @@ + + + diff --git a/app/src/main/res/layout/item_last_shadow_dark.xml b/app/src/main/res/layout/item_last_shadow_dark.xml new file mode 100644 index 00000000..01be15aa --- /dev/null +++ b/app/src/main/res/layout/item_last_shadow_dark.xml @@ -0,0 +1,14 @@ + + + diff --git a/app/src/main/res/layout/item_last_shadow_light.xml b/app/src/main/res/layout/item_last_shadow_light.xml new file mode 100644 index 00000000..550d1be1 --- /dev/null +++ b/app/src/main/res/layout/item_last_shadow_light.xml @@ -0,0 +1,14 @@ + + + diff --git a/app/src/main/res/layout/item_no_permissions_shadow_dark.xml b/app/src/main/res/layout/item_no_permissions_shadow_dark.xml new file mode 100644 index 00000000..88ea027e --- /dev/null +++ b/app/src/main/res/layout/item_no_permissions_shadow_dark.xml @@ -0,0 +1,15 @@ + + + diff --git a/app/src/main/res/layout/item_no_permissions_shadow_light.xml b/app/src/main/res/layout/item_no_permissions_shadow_light.xml new file mode 100644 index 00000000..1a09dcdb --- /dev/null +++ b/app/src/main/res/layout/item_no_permissions_shadow_light.xml @@ -0,0 +1,15 @@ + + + diff --git a/app/src/main/res/layout/item_not_loaded_shadow_dark.xml b/app/src/main/res/layout/item_not_loaded_shadow_dark.xml new file mode 100644 index 00000000..1313f06c --- /dev/null +++ b/app/src/main/res/layout/item_not_loaded_shadow_dark.xml @@ -0,0 +1,14 @@ + + + diff --git a/app/src/main/res/layout/item_not_loaded_shadow_light.xml b/app/src/main/res/layout/item_not_loaded_shadow_light.xml new file mode 100644 index 00000000..c67c209e --- /dev/null +++ b/app/src/main/res/layout/item_not_loaded_shadow_light.xml @@ -0,0 +1,14 @@ + + + diff --git a/app/src/main/res/layout/widget_header_one_row_shadow_dark.xml b/app/src/main/res/layout/widget_header_one_row_shadow_dark.xml new file mode 100644 index 00000000..495086dd --- /dev/null +++ b/app/src/main/res/layout/widget_header_one_row_shadow_dark.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/widget_header_one_row_shadow_light.xml b/app/src/main/res/layout/widget_header_one_row_shadow_light.xml new file mode 100644 index 00000000..7ecfdb8b --- /dev/null +++ b/app/src/main/res/layout/widget_header_one_row_shadow_light.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/widget_header_two_rows_shadow_dark.xml b/app/src/main/res/layout/widget_header_two_rows_shadow_dark.xml new file mode 100644 index 00000000..cff365b5 --- /dev/null +++ b/app/src/main/res/layout/widget_header_two_rows_shadow_dark.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/widget_header_two_rows_shadow_light.xml b/app/src/main/res/layout/widget_header_two_rows_shadow_light.xml new file mode 100644 index 00000000..a9291813 --- /dev/null +++ b/app/src/main/res/layout/widget_header_two_rows_shadow_light.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/widget_initial_shadow_dark.xml b/app/src/main/res/layout/widget_initial_shadow_dark.xml new file mode 100644 index 00000000..87177daf --- /dev/null +++ b/app/src/main/res/layout/widget_initial_shadow_dark.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/widget_initial_shadow_light.xml b/app/src/main/res/layout/widget_initial_shadow_light.xml new file mode 100644 index 00000000..0309317c --- /dev/null +++ b/app/src/main/res/layout/widget_initial_shadow_light.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index d4bb17fb..6d5405fa 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -126,6 +126,10 @@ Светлый Тёмный Чёрный + Тень текста + Без тени + Тёмная тень + Светлая тень Подробности о событии Укажите, какую информацию о событиях показывать diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index d9820db4..c2f2b44c 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -274,4 +274,14 @@ top_day bottom_day + + @string/text_shadow_no_shadow + @string/text_shadow_dark + @string/text_shadow_light + + + no + dark + light + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 13d79c93..ced393b5 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -46,4 +46,8 @@ #2196f3 #9e9e9e - \ No newline at end of file + + #FF000000 + #FFFFFFFF + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index badaf9d2..8fd57439 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -139,6 +139,10 @@ Text shading should be set for each part of the widget Custom text colors Text color should be set for each part of the widget + Text shadow + No shadow + Dark shadow + Light shadow Background color Adjust the color of the background Past events background color diff --git a/app/src/main/res/xml/preferences_colors.xml b/app/src/main/res/xml/preferences_colors.xml index 389c7b7e..62dc591f 100644 --- a/app/src/main/res/xml/preferences_colors.xml +++ b/app/src/main/res/xml/preferences_colors.xml @@ -18,6 +18,13 @@ android:summary="@string/text_color_source_auto_desc" android:title="@string/text_color_source" /> + +