From 748249fed577e562d917cf80e1dbdc8d01a3fa23 Mon Sep 17 00:00:00 2001 From: Tommaso Berlose Date: Sun, 5 Nov 2017 22:06:39 +0100 Subject: [PATCH] Text Shadow, Clock, Product Sans Font, Multiple Events and more --- app/build.gradle | 7 +- app/release/output.json | 2 +- app/src/main/AndroidManifest.xml | 11 + .../anotherwidget/object/Constants.kt | 5 + .../anotherwidget/object/Event.kt | 40 +- .../receiver/NewCalendarEventReceiver.kt | 3 + .../anotherwidget/receiver/UpdatesReceiver.kt | 7 +- .../ui/activity/ChooseApplicationActivity.kt | 29 +- .../anotherwidget/ui/activity/MainActivity.kt | 108 +++-- .../ui/activity/SupportDevActivity.kt | 99 +++++ .../ui/view/CustomTypefaceSpan.kt | 38 ++ .../anotherwidget/ui/widget/TheWidget.kt | 132 +++++-- .../anotherwidget/util/CalendarUtil.kt | 162 ++++---- .../anotherwidget/util/CrocodileService.kt | 51 +++ .../tommasoberlose/anotherwidget/util/Util.kt | 27 +- .../anotherwidget/util/WeatherUtil.kt | 19 +- .../res/drawable-hdpi/ic_action_close.png | Bin 0 -> 363 bytes .../main/res/drawable-hdpi/ic_action_dev.png | Bin 0 -> 888 bytes .../main/res/drawable-hdpi/ic_action_next.png | Bin 0 -> 307 bytes .../res/drawable-hdpi/ic_action_translate.png | Bin 0 -> 811 bytes .../res/drawable-mdpi/ic_action_close.png | Bin 0 -> 230 bytes .../main/res/drawable-mdpi/ic_action_dev.png | Bin 0 -> 560 bytes .../main/res/drawable-mdpi/ic_action_next.png | Bin 0 -> 277 bytes .../res/drawable-mdpi/ic_action_translate.png | Bin 0 -> 517 bytes .../res/drawable-xhdpi/ic_action_close.png | Bin 0 -> 380 bytes .../main/res/drawable-xhdpi/ic_action_dev.png | Bin 0 -> 1123 bytes .../res/drawable-xhdpi/ic_action_next.png | Bin 0 -> 563 bytes .../drawable-xhdpi/ic_action_translate.png | Bin 0 -> 904 bytes .../res/drawable-xxhdpi/ic_action_close.png | Bin 0 -> 611 bytes .../res/drawable-xxhdpi/ic_action_dev.png | Bin 0 -> 1879 bytes .../res/drawable-xxhdpi/ic_action_next.png | Bin 0 -> 416 bytes .../drawable-xxhdpi/ic_action_translate.png | Bin 0 -> 1620 bytes .../res/drawable/white_card_background.xml | 11 + .../layout/activity_choose_application.xml | 45 ++- app/src/main/res/layout/activity_main.xml | 48 +++ .../main/res/layout/activity_support_dev.xml | 368 ++++++++++++++++++ app/src/main/res/layout/main_menu_layout.xml | 1 - app/src/main/res/layout/the_widget.xml | 33 +- app/src/main/res/layout/the_widget_sans.xml | 13 +- app/src/main/res/values-it-rIT/strings.xml | 22 +- app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 23 +- app/src/main/res/xml-v21/the_widget_info.xml | 8 +- app/src/main/res/xml/the_widget_info.xml | 8 +- build.gradle | 4 +- 45 files changed, 1101 insertions(+), 224 deletions(-) create mode 100644 app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/SupportDevActivity.kt create mode 100644 app/src/main/java/com/tommasoberlose/anotherwidget/ui/view/CustomTypefaceSpan.kt create mode 100644 app/src/main/java/com/tommasoberlose/anotherwidget/util/CrocodileService.kt create mode 100644 app/src/main/res/drawable-hdpi/ic_action_close.png create mode 100644 app/src/main/res/drawable-hdpi/ic_action_dev.png create mode 100644 app/src/main/res/drawable-hdpi/ic_action_next.png create mode 100644 app/src/main/res/drawable-hdpi/ic_action_translate.png create mode 100644 app/src/main/res/drawable-mdpi/ic_action_close.png create mode 100644 app/src/main/res/drawable-mdpi/ic_action_dev.png create mode 100644 app/src/main/res/drawable-mdpi/ic_action_next.png create mode 100644 app/src/main/res/drawable-mdpi/ic_action_translate.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_close.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_dev.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_next.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_translate.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_close.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_dev.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_next.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_translate.png create mode 100644 app/src/main/res/drawable/white_card_background.xml create mode 100644 app/src/main/res/layout/activity_support_dev.xml diff --git a/app/build.gradle b/app/build.gradle index 641501b..512012e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,6 +8,8 @@ apply plugin: 'kotlin-kapt' apply plugin: 'io.fabric' +apply plugin: 'realm-android' + android { compileSdkVersion 26 buildToolsVersion "26.0.2" @@ -15,8 +17,8 @@ android { applicationId "com.tommasoberlose.anotherwidget" minSdkVersion 19 targetSdkVersion 26 - versionCode 22 - versionName "1.2" + versionCode 25 + versionName "1.3" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -53,4 +55,5 @@ dependencies { implementation 'com.pes.materialcolorpicker:library:1.0.4' implementation 'com.andkulikov:transitionseverywhere:1.7.6' implementation 'me.everything:providers-android:1.0.1' + compile 'com.anjlab.android.iab.v3:library:1.0.44' } diff --git a/app/release/output.json b/app/release/output.json index 70150de..64f65bc 100644 --- a/app/release/output.json +++ b/app/release/output.json @@ -1 +1 @@ -[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":22},"path":"app-release.apk","properties":{"packageId":"com.tommasoberlose.anotherwidget","split":"","minSdkVersion":"19"}}] \ No newline at end of file +[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":24},"path":"app-release.apk","properties":{"packageId":"com.tommasoberlose.anotherwidget","split":"","minSdkVersion":"19"}}] \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4025f72..2a7811a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/object/Constants.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/object/Constants.kt index ffc08ad..ec123ed 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/object/Constants.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/object/Constants.kt @@ -67,6 +67,10 @@ object Constants { val PREF_SHOW_DECLINED_EVENTS = "PREF_SHOW_DECLINED_EVENTS" val PREF_OPEN_WEATHER_API_KEY = "PREF_OPEN_WEATHER_API_KEY" val PREF_SECOND_ROW_INFORMATION = "PREF_SECOND_ROW_INFORMATION" + val PREF_CUSTOM_FONT = "PREF_CUSTOM_FONT" + val PREF_SHOW_NEXT_EVENT = "PREF_SHOW_NEXT_EVENT" + + val CUSTOM_FONT_PRODUCT_SANS = 1 val ACTION_EXTRA_OPEN_WEATHER_PROVIDER = "ACTION_EXTRA_OPEN_WEATHER_PROVIDER" @@ -80,6 +84,7 @@ object Constants { val ACTION_WEATHER_UPDATE = "com.tommasoberlose.anotherwidget.action.ACTION_WEATHER_UPDATE" val ACTION_SOMETHING_HAPPENED = "com.tommasoberlose.anotherwidget.action.ACTION_SOMETHING_HAPPENED" val ACTION_OPEN_WEATHER_INTENT = "com.tommasoberlose.anotherwidget.action.ACTION_OPEN_WEATHER_INTENT" + val ACTION_GO_TO_NEXT_EVENT = "com.tommasoberlose.anotherwidget.action.GO_TO_NEXT_EVENT" val WEATHER_PROVIDER_GOOGLE_AWARENESS = 1 val WEATHER_PROVIDER_OPEN_WEATHER = 2 diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/object/Event.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/object/Event.kt index 95a862f..0eb6744 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/object/Event.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/object/Event.kt @@ -1,6 +1,8 @@ package com.tommasoberlose.anotherwidget.`object` import android.database.Cursor +import io.realm.RealmObject +import io.realm.annotations.PrimaryKey import java.util.Date @@ -8,37 +10,15 @@ import java.util.Date * Created by tommaso on 05/10/17. */ -class Event { - var id: Int = 0 - var title: String = "" - var startDate: Long = 0 - var endDate: Long = 0 - var calendarID: Int = 0 - var allDay: Boolean = false - var address: String = "" - - constructor(id:Int, title:String, startDate:Long, endDate:Long, calendarID: Int, allDay: Boolean, address: String) { - this.id = id - this.title = title - this.startDate = startDate - this.endDate = endDate - this.calendarID = calendarID - this.allDay = allDay - this.address = address - } - - constructor(eventCursor: Cursor, instanceCursor: Cursor) { - id = instanceCursor.getInt(0) - startDate = instanceCursor.getLong(1) - endDate = instanceCursor.getLong(2) - - title = eventCursor.getString(0)?: "" - allDay = !eventCursor.getString(1).equals("0") - calendarID = eventCursor.getInt(2) - address = eventCursor.getString(3)?: "" - } +open class Event(var id: Int = 0, + var title: String = "", + var startDate: Long = 0, + var endDate: Long = 0, + var calendarID: Int = 0, + var allDay: Boolean = false, + var address: String = ""): RealmObject(){ override fun toString(): String { - return "Event:\nID" + id + "\nTITLE: " + title + "\nSTART DATE: " + Date(startDate) + "\nEND DATE: " + Date(endDate) + return "Event:\nID: " + id + "\nTITLE: " + title + "\nSTART DATE: " + Date(startDate) + "\nEND DATE: " + Date(endDate) + "\nCAL DAY: " + calendarID + "\nADDRESS: " + address } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receiver/NewCalendarEventReceiver.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receiver/NewCalendarEventReceiver.kt index 3477904..79838f9 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/receiver/NewCalendarEventReceiver.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/receiver/NewCalendarEventReceiver.kt @@ -4,6 +4,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log +import com.tommasoberlose.anotherwidget.`object`.Constants import com.tommasoberlose.anotherwidget.util.CalendarUtil import com.tommasoberlose.anotherwidget.util.Util @@ -12,6 +13,8 @@ class NewCalendarEventReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.action.equals(Intent.ACTION_PROVIDER_CHANGED)) { CalendarUtil.updateEventList(context) + } else if (intent.action == Constants.ACTION_GO_TO_NEXT_EVENT) { + CalendarUtil.goToNextEvent(context) } } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receiver/UpdatesReceiver.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receiver/UpdatesReceiver.kt index b7947d9..054e0e6 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/receiver/UpdatesReceiver.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/receiver/UpdatesReceiver.kt @@ -12,6 +12,7 @@ import android.util.Log import com.tommasoberlose.anotherwidget.`object`.Constants import com.tommasoberlose.anotherwidget.`object`.Event import com.tommasoberlose.anotherwidget.util.CalendarUtil +import com.tommasoberlose.anotherwidget.util.CrocodileService import com.tommasoberlose.anotherwidget.util.Util import java.sql.Time import java.util.* @@ -36,8 +37,10 @@ class UpdatesReceiver : BroadcastReceiver() { } fun setUpdates(context: Context) { - removeUpdates(context) CalendarUtil.updateEventList(context) + removeUpdates(context) + context.startService(Intent(context, CrocodileService::class.java)) + /* val now = Calendar.getInstance() now.set(Calendar.MILLISECOND, 0) now.set(Calendar.SECOND, 0) @@ -46,7 +49,7 @@ class UpdatesReceiver : BroadcastReceiver() { val i = Intent(context, UpdatesReceiver::class.java) i.action = Constants.ACTION_TIME_UPDATE val pi = PendingIntent.getBroadcast(context, 0, i, 0) - am.setRepeating(AlarmManager.RTC_WAKEUP, now.timeInMillis, (1000 * 60).toLong(), pi) + am.setRepeating(AlarmManager.RTC_WAKEUP, now.timeInMillis, (1000 * 60).toLong(), pi) */ } fun removeUpdates(context: Context) { diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/ChooseApplicationActivity.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/ChooseApplicationActivity.kt index 342c7cf..b5429b7 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/ChooseApplicationActivity.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/ChooseApplicationActivity.kt @@ -23,6 +23,7 @@ import android.support.v7.widget.LinearLayoutManager import android.text.Editable import android.text.TextWatcher import android.util.Log +import android.view.View import com.tommasoberlose.anotherwidget.`object`.AppInfoSavedEvent import com.tommasoberlose.anotherwidget.ui.adapter.ApplicationInfoAdapter @@ -41,6 +42,14 @@ class ChooseApplicationActivity : AppCompatActivity() { selectDefaultApp() } + action_back.setOnClickListener { + onBackPressed() + } + + action_none.setOnClickListener { + removeClickAction() + } + list_view.setHasFixedSize(true); val mLayoutManager = LinearLayoutManager(this); list_view.layoutManager = mLayoutManager; @@ -67,9 +76,25 @@ class ChooseApplicationActivity : AppCompatActivity() { fun selectDefaultApp() { val resultIntent = Intent() - resultIntent.putExtra(Constants.RESULT_APP_NAME, getString(R.string.default_name)) + resultIntent.putExtra(Constants.RESULT_APP_NAME, "") resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, "") - setResult(Activity.RESULT_OK, intent) + setResult(Activity.RESULT_OK, resultIntent) + finish() + } + + fun removeClickAction() { + val resultIntent = Intent() + resultIntent.putExtra(Constants.RESULT_APP_NAME, getString(R.string.action_none)) + resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, "_") + setResult(Activity.RESULT_OK, resultIntent) + finish() + } + + fun multiEventAction() { + val resultIntent = Intent() + resultIntent.putExtra(Constants.RESULT_APP_NAME, getString(R.string.action_go_to_next_event)) + resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, Constants.PREF_SHOW_NEXT_EVENT) + setResult(Activity.RESULT_OK, resultIntent) finish() } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/MainActivity.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/MainActivity.kt index 8f096ec..05fdd94 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/MainActivity.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/MainActivity.kt @@ -30,6 +30,9 @@ import android.os.Build import android.support.design.widget.BottomSheetDialog import android.support.v4.content.ContextCompat import android.text.Html +import android.text.Spannable +import android.text.SpannableString +import android.text.style.RelativeSizeSpan import android.util.Log import android.util.TypedValue import android.widget.Toast @@ -42,6 +45,7 @@ import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.key_time_wait_layout.view.* import kotlinx.android.synthetic.main.main_menu_layout.view.* import kotlinx.android.synthetic.main.the_widget.* +import kotlinx.android.synthetic.main.the_widget.view.* class MainActivity : AppCompatActivity() { @@ -113,6 +117,12 @@ class MainActivity : AppCompatActivity() { Util.updateWidget(this) mBottomSheetDialog.dismiss() } + + menuView.action_support.setOnClickListener { + startActivity(Intent(this, SupportDevActivity::class.java)) + mBottomSheetDialog.dismiss() + } + mBottomSheetDialog.setContentView(menuView) mBottomSheetDialog.show(); } @@ -193,28 +203,28 @@ class MainActivity : AppCompatActivity() { updateSettings() } else if (requestCode == Constants.CALENDAR_APP_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) { SP.edit() - .putString(Constants.PREF_CALENDAR_APP_NAME, data.getStringExtra(Constants.RESULT_APP_NAME)) + .putString(Constants.PREF_CALENDAR_APP_NAME, if (data.getStringExtra(Constants.RESULT_APP_NAME) != "") data.getStringExtra(Constants.RESULT_APP_NAME) else getString(R.string.default_calendar_app)) .putString(Constants.PREF_CALENDAR_APP_PACKAGE, data.getStringExtra(Constants.RESULT_APP_PACKAGE)) .commit() Util.updateWidget(this) updateSettings() } else if (requestCode == Constants.WEATHER_APP_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) { SP.edit() - .putString(Constants.PREF_WEATHER_APP_NAME, data.getStringExtra(Constants.RESULT_APP_NAME)) + .putString(Constants.PREF_WEATHER_APP_NAME, if (data.getStringExtra(Constants.RESULT_APP_NAME) != "") data.getStringExtra(Constants.RESULT_APP_NAME) else getString(R.string.default_weather_app)) .putString(Constants.PREF_WEATHER_APP_PACKAGE, data.getStringExtra(Constants.RESULT_APP_PACKAGE)) .commit() Util.updateWidget(this) updateSettings() } else if (requestCode == Constants.EVENT_APP_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) { SP.edit() - .putString(Constants.PREF_EVENT_APP_NAME, data.getStringExtra(Constants.RESULT_APP_NAME)) + .putString(Constants.PREF_EVENT_APP_NAME, if (data.getStringExtra(Constants.RESULT_APP_NAME) != "") data.getStringExtra(Constants.RESULT_APP_NAME) else getString(R.string.default_event_app)) .putString(Constants.PREF_EVENT_APP_PACKAGE, data.getStringExtra(Constants.RESULT_APP_PACKAGE)) .commit() Util.updateWidget(this) updateSettings() } else if (requestCode == Constants.CLOCK_APP_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) { SP.edit() - .putString(Constants.PREF_CLOCK_APP_NAME, data.getStringExtra(Constants.RESULT_APP_NAME)) + .putString(Constants.PREF_CLOCK_APP_NAME, if (data.getStringExtra(Constants.RESULT_APP_NAME) != "") data.getStringExtra(Constants.RESULT_APP_NAME) else getString(R.string.default_clock_app)) .putString(Constants.PREF_CLOCK_APP_PACKAGE, data.getStringExtra(Constants.RESULT_APP_PACKAGE)) .commit() Util.updateWidget(this) @@ -234,7 +244,15 @@ class MainActivity : AppCompatActivity() { time.visibility = View.VISIBLE } val now = Calendar.getInstance() - time.text = if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) Constants.badHourFormat.format(now.timeInMillis) else Constants.goodHourFormat.format(now.timeInMillis) + if (SP.getString(Constants.PREF_HOUR_FORMAT, "12") == "12") { + val textBadHour = SpannableString(Constants.badHourFormat.format(now.timeInMillis)) + textBadHour.setSpan(RelativeSizeSpan(0.4f), textBadHour.length - 2, + textBadHour.length, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + + time.text = textBadHour + } else { + time.text = Constants.goodHourFormat.format(now.timeInMillis) + } } fun updateCalendarView() { @@ -255,6 +273,13 @@ class MainActivity : AppCompatActivity() { if (e.id != 0) { next_event.text = e.title + + if (SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, false) && CalendarUtil.getEventsCount(this) > 1) { + multiple_events.visibility = View.VISIBLE + } else { + multiple_events.visibility = View.GONE + } + if (SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)) { next_event_difference_time.text = Util.getDifferenceText(this, now.timeInMillis, e.startDate) next_event_difference_time.visibility = View.VISIBLE @@ -324,6 +349,12 @@ class MainActivity : AppCompatActivity() { calendar_temp.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f)) time.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f)) + second_row_icon.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f + second_row_icon.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f + + multiple_events.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f + multiple_events.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f + val shadowRadius = when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) { 0 -> 0f 1 -> 5f @@ -352,17 +383,28 @@ class MainActivity : AppCompatActivity() { calendar_temp.setShadowLayer(shadowRadius, 0f, 0f, shadowColor) time.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor) - - val product_sans: Typeface = Typeface.createFromAsset(assets, "fonts/product_sans_regular.ttf") - empty_date.typeface = product_sans - divider1.typeface = product_sans - temp.typeface = product_sans - next_event.typeface = product_sans - next_event_difference_time.typeface = product_sans - next_event_date.typeface = product_sans - divider2.typeface = product_sans - calendar_temp.typeface = product_sans - time.typeface = product_sans + if (SP.getInt(Constants.PREF_CUSTOM_FONT, Constants.CUSTOM_FONT_PRODUCT_SANS) == Constants.CUSTOM_FONT_PRODUCT_SANS) { + val product_sans: Typeface = Typeface.createFromAsset(assets, "fonts/product_sans_regular.ttf") + empty_date.typeface = product_sans + divider1.typeface = product_sans + temp.typeface = product_sans + next_event.typeface = product_sans + next_event_difference_time.typeface = product_sans + next_event_date.typeface = product_sans + divider2.typeface = product_sans + calendar_temp.typeface = product_sans + time.typeface = product_sans + } else { + empty_date.typeface = Typeface.DEFAULT + divider1.typeface = Typeface.DEFAULT + temp.typeface = Typeface.DEFAULT + next_event.typeface = Typeface.DEFAULT + next_event_difference_time.typeface = Typeface.DEFAULT + next_event_date.typeface = Typeface.DEFAULT + divider2.typeface = Typeface.DEFAULT + calendar_temp.typeface = Typeface.DEFAULT + time.typeface = Typeface.DEFAULT + } } fun updateLocationView() { @@ -489,6 +531,13 @@ class MainActivity : AppCompatActivity() { updateSettings() } + show_multiple_events_label.text = if (SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, true)) getString(R.string.settings_visible) else getString(R.string.settings_not_visible) + action_show_multiple_events.setOnClickListener { + SP.edit().putBoolean(Constants.PREF_SHOW_NEXT_EVENT, !SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, true)).commit() + sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE)) + updateSettings() + } + show_diff_time_label.text = if (SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)) getString(R.string.settings_visible) else getString(R.string.settings_not_visible) action_show_diff_time.setOnClickListener { SP.edit().putBoolean(Constants.PREF_SHOW_DIFF_TIME, !SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)).commit() @@ -526,7 +575,7 @@ class MainActivity : AppCompatActivity() { main_text_size_label.text = String.format("%.0f%s", SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f), "sp") action_main_text_size.setOnClickListener { var fontSize = SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f) + 1 - if (fontSize > 30) { + if (fontSize > 36) { fontSize = 20f } SP.edit().putFloat(Constants.PREF_TEXT_MAIN_SIZE, fontSize).commit() @@ -538,13 +587,12 @@ class MainActivity : AppCompatActivity() { second_text_size_label.text = String.format("%.0f%s", SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f), "sp") action_second_text_size.setOnClickListener { var fontSize = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) + 1 - if (fontSize > 20) { + if (fontSize > 28) { fontSize = 12f } SP.edit().putFloat(Constants.PREF_TEXT_SECOND_SIZE, fontSize).commit() Util.updateWidget(this) updateSettings() - updateAppWidget() } clock_text_size_label.text = String.format("%.0f%s", SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f), "sp") @@ -556,7 +604,6 @@ class MainActivity : AppCompatActivity() { SP.edit().putFloat(Constants.PREF_TEXT_CLOCK_SIZE, fontSize).commit() Util.updateWidget(this) updateSettings() - updateAppWidget() } val textColor = try { @@ -621,14 +668,15 @@ class MainActivity : AppCompatActivity() { 3 -> 4 4 -> 5 5 -> 6 - 6 -> 0 + 6 -> 7 + 7 -> 0 else -> 1 }).commit() updateSettings() sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE)) } - text_shadow_label.text = getString(Util.getTextshadowString(SP.getInt(Constants.PREF_TEXT_SHADOW, 1))) + text_shadow_label.text = getString(Util.getTextShadowString(SP.getInt(Constants.PREF_TEXT_SHADOW, 1))) action_text_shadow.setOnClickListener { SP.edit().putInt(Constants.PREF_TEXT_SHADOW, when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) { 0 -> 1 @@ -641,6 +689,18 @@ class MainActivity : AppCompatActivity() { updateAppWidget() } + custom_font_label.text = getString(Util.getCustomFontLabel(SP.getInt(Constants.PREF_CUSTOM_FONT, Constants.CUSTOM_FONT_PRODUCT_SANS))) + action_custom_font.setOnClickListener { + SP.edit().putInt(Constants.PREF_CUSTOM_FONT, when (SP.getInt(Constants.PREF_CUSTOM_FONT, Constants.CUSTOM_FONT_PRODUCT_SANS)) { + 0 -> Constants.CUSTOM_FONT_PRODUCT_SANS + Constants.CUSTOM_FONT_PRODUCT_SANS -> 0 + else -> Constants.CUSTOM_FONT_PRODUCT_SANS + }).commit() + sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE)) + updateSettings() + updateAppWidget() + } + if (SP.getInt(Constants.PREF_WEATHER_PROVIDER, Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) == Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) { action_custom_location.visibility = View.GONE } else { @@ -675,7 +735,9 @@ class MainActivity : AppCompatActivity() { calendar_app_label.text = SP.getString(Constants.PREF_CALENDAR_APP_NAME, getString(R.string.default_calendar_app)) action_calendar_app.setOnClickListener { - startActivityForResult(Intent(this, ChooseApplicationActivity::class.java), Constants.CALENDAR_APP_REQUEST_CODE) + val i = Intent(this, ChooseApplicationActivity::class.java) + i.putExtra("requestCode", Constants.CALENDAR_APP_REQUEST_CODE) + startActivityForResult(i, Constants.CALENDAR_APP_REQUEST_CODE) } weather_app_label.text = SP.getString(Constants.PREF_WEATHER_APP_NAME, getString(R.string.default_weather_app)) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/SupportDevActivity.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/SupportDevActivity.kt new file mode 100644 index 0000000..39a9066 --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activity/SupportDevActivity.kt @@ -0,0 +1,99 @@ +package com.tommasoberlose.anotherwidget.ui.activity + +import android.content.Intent +import android.support.v7.app.AppCompatActivity +import android.os.Bundle +import android.view.View +import android.widget.Toast +import com.anjlab.android.iab.v3.BillingProcessor +import com.anjlab.android.iab.v3.TransactionDetails +import com.tommasoberlose.anotherwidget.R +import com.tommasoberlose.anotherwidget.util.Util +import kotlinx.android.synthetic.main.activity_support_dev.* + +class SupportDevActivity : AppCompatActivity(), BillingProcessor.IBillingHandler { + internal var bp: BillingProcessor? = null + + internal val BILLING_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAox5CcxuoLJ6CmNS7s6lVQzJ253njKKGF8MoQ/gQ5gEw2Fr03fBvtHpiVMpnjhNLw5NMeIpzRvkVqeQ7BfkC7c0BLCJUqf/fFA11ArQe8na6QKt5O4d+v4sbHtP7mm3GQNPOBaqRzcpFZaiAbfk6mnalo+tzM47GXrQFt5bNSrMctCs7bbChqJfH2cyMW0F8DHWEEeO5xElBmH3lh4FVpwIUTPYJIV3n0yhE3qqRA0WXkDej66g/uAt/rebmMZLmwNwIive5cObU4o41YyKRv2wSAicrv3W40LftzXAOOordIbmzDFN8ksh3VrnESqwCDGG97nZVbPG/+3LD0xHWiRwIDAQAB" + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_support_dev) + bp = BillingProcessor(this, BILLING_KEY, this) + + action_website.setOnClickListener { + Util.openURI(this, "http://tommasoberlose.com/") + } + + action_translate.setOnClickListener { + Util.openURI(this, "https://github.com/tommasoberlose/another-widget/blob/master/app/src/main/res/values/strings.xml") + } + } + + override fun onBillingInitialized() { + loader.visibility = View.GONE + val isAvailable = BillingProcessor.isIabServiceAvailable(this) + val isOneTimePurchaseSupported = bp!!.isOneTimePurchaseSupported + if (isAvailable && isOneTimePurchaseSupported) { + val coffee = bp!!.getPurchaseListingDetails("donation_coffee") + val donuts = bp!!.getPurchaseListingDetails("donation_donuts") + val breakfast = bp!!.getPurchaseListingDetails("donation_breakfast") + val lunch = bp!!.getPurchaseListingDetails("donation_lunch") + val dinner = bp!!.getPurchaseListingDetails("donation_dinner") + + import_donation_coffee.text = coffee.priceText + action_donation_coffee.setOnClickListener { + bp!!.purchase(this, "donation_coffee") + } + + import_donation_donuts.text = donuts.priceText + action_donation_donuts.setOnClickListener { + bp!!.purchase(this, "donation_donuts") + } + + import_donation_breakfast.text = breakfast.priceText + action_donation_breakfast.setOnClickListener { + bp!!.purchase(this, "donation_breakfast") + } + + import_donation_lunch.text = lunch.priceText + action_donation_lunch.setOnClickListener { + bp!!.purchase(this, "donation_lunch") + } + + import_donation_dinner.text = dinner.priceText + action_donation_dinner.setOnClickListener { + bp!!.purchase(this, "donation_dinner") + } + + products_list.visibility = View.VISIBLE + } else { + products_card.visibility = View.GONE + } + } + + override fun onPurchaseHistoryRestored() { + } + + override fun onProductPurchased(productId: String, details: TransactionDetails?) { + Toast.makeText(this, R.string.thanks, Toast.LENGTH_SHORT).show() + bp!!.consumePurchase(productId) + } + + override fun onBillingError(errorCode: Int, error: Throwable?) { + Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { + if (!bp!!.handleActivityResult(requestCode, resultCode, data)) { + super.onActivityResult(requestCode, resultCode, data) + } + } + + public override fun onDestroy() { + if (bp != null) { + bp!!.release() + } + super.onDestroy() + } +} diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/view/CustomTypefaceSpan.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/view/CustomTypefaceSpan.kt new file mode 100644 index 0000000..fc118af --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/view/CustomTypefaceSpan.kt @@ -0,0 +1,38 @@ +package com.tommasoberlose.anotherwidget.ui.view + +import android.graphics.Paint +import android.graphics.Typeface +import android.text.TextPaint +import android.text.style.TypefaceSpan + +class CustomTypefaceSpan(family: String, private val newType: Typeface) : TypefaceSpan(family) { + + override fun updateDrawState(ds: TextPaint) { + applyCustomTypeFace(ds, newType) + } + + override fun updateMeasureState(paint: TextPaint) { + applyCustomTypeFace(paint, newType) + } + + private fun applyCustomTypeFace(paint: Paint, tf: Typeface) { + val oldStyle: Int + val old = paint.typeface + if (old == null) { + oldStyle = 0 + } else { + oldStyle = old.style + } + + val fake = oldStyle and tf.style.inv() + if (fake and Typeface.BOLD != 0) { + paint.isFakeBoldText = true + } + + if (fake and Typeface.ITALIC != 0) { + paint.textSkewX = -0.25f + } + + paint.typeface = tf + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widget/TheWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widget/TheWidget.kt index 1340d55..67d0b34 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widget/TheWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widget/TheWidget.kt @@ -38,8 +38,13 @@ import android.os.Bundle import android.support.v4.content.ContextCompat.startActivity import android.provider.CalendarContract.Events import android.support.v4.content.ContextCompat +import android.text.Spannable +import android.text.SpannableString +import android.text.style.RelativeSizeSpan +import android.text.style.StyleSpan import android.util.DisplayMetrics import android.util.TypedValue +import com.tommasoberlose.anotherwidget.ui.view.CustomTypefaceSpan import kotlinx.android.synthetic.main.the_widget.* import kotlinx.android.synthetic.main.the_widget.view.* @@ -77,25 +82,21 @@ class TheWidget : AppWidgetProvider() { internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) { - val displayMetrics = Resources.getSystem().getDisplayMetrics() - val height = displayMetrics.heightPixels + val SP = PreferenceManager.getDefaultSharedPreferences(context) + val displayMetrics = Resources.getSystem().displayMetrics + val widgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId) + var height = widgetInfo.minHeight + if (SP.getBoolean(Constants.PREF_SHOW_CLOCK, false)) { + height += Util.convertSpToPixels(SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f), context).toInt() + Util.convertDpToPixel(8f, context).toInt() + } val width = displayMetrics.widthPixels - val widgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId) - generateWidgetView(context, appWidgetId, appWidgetManager, width - Util.convertDpToPixel(32f, context).toInt(), widgetInfo.minHeight) + generateWidgetView(context, appWidgetId, appWidgetManager, width - Util.convertDpToPixel(16f, context).toInt(), height) } fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int, h: Int) { var views = RemoteViews(context.packageName, R.layout.the_widget_sans) var v = View.inflate(context, R.layout.the_widget, null) - v = updateCalendarViewByLayout(context, v) - v = updateLocationViewByLayout(context, v) - v = updateClockViewByLayout(context, v) - views.setImageViewBitmap(R.id.bitmap_container, Util.getBitmapFromView(v, w, h)) - - views = updateCalendarView(context, views, appWidgetId) - views = updateLocationView(context, views, appWidgetId) - views = updateClockView(context, views, appWidgetId) val SP = PreferenceManager.getDefaultSharedPreferences(context) views.setTextColor(R.id.empty_date, Util.getFontColor(SP)) @@ -106,6 +107,7 @@ class TheWidget : AppWidgetProvider() { views.setTextColor(R.id.next_event_date, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context))) views.setTextColor(R.id.divider2, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context))) views.setTextColor(R.id.calendar_temp, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context))) + views.setTextColor(R.id.time, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context))) views.setTextViewTextSize(R.id.empty_date, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f)) views.setTextViewTextSize(R.id.divider1, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f)) @@ -115,6 +117,16 @@ class TheWidget : AppWidgetProvider() { views.setTextViewTextSize(R.id.next_event_date, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f)) views.setTextViewTextSize(R.id.divider2, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f)) views.setTextViewTextSize(R.id.calendar_temp, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f)) + views.setTextViewTextSize(R.id.time, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f)) + + v = updateCalendarViewByLayout(context, v) + v = updateLocationViewByLayout(context, v) + v = updateClockViewByLayout(context, v) + views.setImageViewBitmap(R.id.bitmap_container, Util.getBitmapFromView(v, w, h)) + + views = updateCalendarView(context, views, appWidgetId) + views = updateLocationView(context, views, appWidgetId) + views = updateClockView(context, views, appWidgetId) appWidgetManager.updateAppWidget(appWidgetId, views) } @@ -142,6 +154,19 @@ class TheWidget : AppWidgetProvider() { if (e.id != 0) { views.setTextViewText(R.id.next_event, e.title) + + if (SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, false) && CalendarUtil.getEventsCount(context) > 1) { + val multipleIntent = PendingIntent.getBroadcast(context, widgetID, Intent(Constants.ACTION_GO_TO_NEXT_EVENT), 0) + views.setViewVisibility(R.id.multiple_events, View.VISIBLE) + views.setOnClickPendingIntent(R.id.multiple_events, multipleIntent) + } else { + views.setViewVisibility(R.id.multiple_events, View.GONE) + } + + val pIntent = PendingIntent.getActivity(context, widgetID, Util.getEventIntent(context, e), 0) + views.setOnClickPendingIntent(R.id.next_event, pIntent) + views.setOnClickPendingIntent(R.id.next_event_difference_time, pIntent) + if (SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)) { views.setTextViewText(R.id.next_event_difference_time, Util.getDifferenceText(context, now.timeInMillis, e.startDate)) views.setViewVisibility(R.id.next_event_difference_time, View.VISIBLE) @@ -174,8 +199,12 @@ class TheWidget : AppWidgetProvider() { views.setImageViewBitmap(R.id.second_row_icon, result) if (!e.allDay) { - val startHour: String = if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) Constants.badHourFormat.format(e.startDate) else Constants.goodHourFormat.format(e.startDate) - val endHour: String = if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) Constants.badHourFormat.format(e.endDate) else Constants.goodHourFormat.format(e.endDate) + var startHour = Constants.goodHourFormat.format(e.startDate) + var endHour = Constants.goodHourFormat.format(e.endDate) + if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) { + startHour = Constants.badHourFormat.format(e.startDate) + endHour = Constants.badHourFormat.format(e.endDate) + } var dayDiff = TimeUnit.MILLISECONDS.toDays(e.endDate - e.startDate) val startCal = Calendar.getInstance() @@ -199,15 +228,11 @@ class TheWidget : AppWidgetProvider() { } else { views.setTextViewText(R.id.next_event_date, dateStringValue) } + views.setOnClickPendingIntent(R.id.next_event_date, pIntent) } views.setViewVisibility(R.id.empty_layout, View.GONE) views.setViewVisibility(R.id.calendar_layout, View.VISIBLE) - - val pIntent = PendingIntent.getActivity(context, widgetID, Util.getEventIntent(context, e), 0) - views.setOnClickPendingIntent(R.id.next_event, pIntent) - views.setOnClickPendingIntent(R.id.next_event_difference_time, pIntent) - views.setOnClickPendingIntent(R.id.next_event_date, pIntent) } } @@ -258,7 +283,18 @@ class TheWidget : AppWidgetProvider() { views.setViewVisibility(R.id.time, View.VISIBLE) } val now = Calendar.getInstance() - views.setTextViewText(R.id.time, if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) Constants.badHourFormat.format(now.timeInMillis) else Constants.goodHourFormat.format(now.timeInMillis)) + + + + if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) { + val textBadHour = SpannableString(Constants.badHourFormat.format(now.timeInMillis).replace(" ", "")) + textBadHour.setSpan(RelativeSizeSpan(0.4f), textBadHour.length - 2, + textBadHour.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE) + + views.setTextViewText(R.id.time, textBadHour) + } else { + views.setTextViewText(R.id.time, Constants.goodHourFormat.format(now.timeInMillis)) + } val clockPIntent = PendingIntent.getActivity(context, widgetID, Util.getClockIntent(context), 0) views.setOnClickPendingIntent(R.id.time, clockPIntent) @@ -285,6 +321,13 @@ class TheWidget : AppWidgetProvider() { if (e.id != 0) { v.next_event.text = e.title + + if (SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, false) && CalendarUtil.getEventsCount(context) > 1) { + v.multiple_events.visibility = View.VISIBLE + } else { + v.multiple_events.visibility = View.GONE + } + if (SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)) { v.next_event_difference_time.text = Util.getDifferenceText(context, now.timeInMillis, e.startDate) v.next_event_difference_time.visibility = View.VISIBLE @@ -301,8 +344,12 @@ class TheWidget : AppWidgetProvider() { } else { v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_action_calendar)) if (!e.allDay) { - val startHour: String = if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) Constants.badHourFormat.format(e.startDate) else Constants.goodHourFormat.format(e.startDate) - val endHour: String = if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) Constants.badHourFormat.format(e.endDate) else Constants.goodHourFormat.format(e.endDate) + var startHour = Constants.goodHourFormat.format(e.startDate) + var endHour = Constants.goodHourFormat.format(e.endDate) + if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) { + startHour = Constants.badHourFormat.format(e.startDate) + endHour = Constants.badHourFormat.format(e.endDate) + } var dayDiff = TimeUnit.MILLISECONDS.toDays(e.endDate - e.startDate) val startCal = Calendar.getInstance() @@ -321,6 +368,7 @@ class TheWidget : AppWidgetProvider() { multipleDay = String.format(" (+%s%s)", dayDiff, context.getString(R.string.day_char)) } v.next_event_date.text = String.format("%s - %s%s", startHour, endHour, multipleDay) + } else { v.next_event_date.text = dateStringValue } @@ -341,6 +389,7 @@ class TheWidget : AppWidgetProvider() { v.calendar_temp.setTextColor(Util.getFontColor(SP)) v.second_row_icon.setColorFilter(Util.getFontColor(SP)) v.time.setTextColor(Util.getFontColor(SP)) + v.multiple_events.setColorFilter(Util.getFontColor(SP)) v.empty_date.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f)) @@ -353,6 +402,12 @@ class TheWidget : AppWidgetProvider() { v.calendar_temp.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f)) v.time.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f)) + v.second_row_icon.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f + v.second_row_icon.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f + + v.multiple_events.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f + v.multiple_events.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f + val shadowRadius = when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) { 0 -> 0f 1 -> 5f @@ -381,17 +436,18 @@ class TheWidget : AppWidgetProvider() { v.calendar_temp.setShadowLayer(shadowRadius, 0f, 0f, shadowColor) v.time.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor) - - val product_sans: Typeface = Typeface.createFromAsset(context.assets, "fonts/product_sans_regular.ttf") - v.empty_date.typeface = product_sans - v.divider1.typeface = product_sans - v.temp.typeface = product_sans - v.next_event.typeface = product_sans - v.next_event_difference_time.typeface = product_sans - v.next_event_date.typeface = product_sans - v.divider2.typeface = product_sans - v.calendar_temp.typeface = product_sans - v.time.typeface = product_sans + if (SP.getInt(Constants.PREF_CUSTOM_FONT, Constants.CUSTOM_FONT_PRODUCT_SANS) == Constants.CUSTOM_FONT_PRODUCT_SANS) { + val product_sans: Typeface = Typeface.createFromAsset(context.assets, "fonts/product_sans_regular.ttf") + v.empty_date.typeface = product_sans + v.divider1.typeface = product_sans + v.temp.typeface = product_sans + v.next_event.typeface = product_sans + v.next_event_difference_time.typeface = product_sans + v.next_event_date.typeface = product_sans + v.divider2.typeface = product_sans + v.calendar_temp.typeface = product_sans + v.time.typeface = product_sans + } return v } @@ -434,7 +490,15 @@ class TheWidget : AppWidgetProvider() { v.time.visibility = View.VISIBLE } val now = Calendar.getInstance() - v.time.text = if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) Constants.badHourFormat.format(now.timeInMillis) else Constants.goodHourFormat.format(now.timeInMillis) + if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) { + val textBadHour = SpannableString(Constants.badHourFormat.format(now.timeInMillis).replace(" ", "")) + textBadHour.setSpan(RelativeSizeSpan(0.4f), textBadHour.length - 2, + textBadHour.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE); + + v.time.text = textBadHour + } else { + v.time.text = Constants.goodHourFormat.format(now.timeInMillis) + } return v } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/util/CalendarUtil.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/util/CalendarUtil.kt index cf2f972..43c66a9 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/util/CalendarUtil.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/util/CalendarUtil.kt @@ -4,6 +4,7 @@ import android.Manifest import android.annotation.SuppressLint import android.content.ContentUris import android.content.Context +import android.content.Intent import android.content.SharedPreferences import android.net.Uri import android.preference.PreferenceManager @@ -15,11 +16,13 @@ import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.`object`.CalendarSelector import com.tommasoberlose.anotherwidget.`object`.Constants import com.tommasoberlose.anotherwidget.`object`.Event +import io.realm.Realm import me.everything.providers.android.calendar.CalendarProvider import me.everything.providers.android.contacts.ContactsProvider import java.util.* import java.util.concurrent.TimeUnit import kotlin.Comparator +import kotlin.collections.ArrayList /** * Created by tommaso on 08/10/17. @@ -41,7 +44,8 @@ object CalendarUtil { 3 -> limit.add(Calendar.DAY_OF_MONTH, 1) 4 -> limit.add(Calendar.DAY_OF_MONTH, 3) 5 -> limit.add(Calendar.DAY_OF_MONTH, 7) - 6 -> limit.add(Calendar.HOUR, 1) + 6 -> limit.add(Calendar.MINUTE, 30) + 7 -> limit.add(Calendar.HOUR, 1) else -> limit.add(Calendar.HOUR, 6) } @@ -58,7 +62,15 @@ object CalendarUtil { for (instance in instances) { val e = provider.getEvent(instance.eventId) if (e != null && (SP.getBoolean(Constants.PREF_CALENDAR_ALL_DAY, false) || !e.allDay) && !(SP.getString(Constants.PREF_CALENDAR_FILTER, "").contains(" " + e.calendarId + ",")) && (SP.getBoolean(Constants.PREF_SHOW_DECLINED_EVENTS, true) || !e.selfAttendeeStatus.equals(CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED))) { - eventList.add(Event(e.id.toInt(), e.title, e.dTStart, e.dTend, e.calendarId.toInt(), e.allDay, e.eventLocation)) + if (e.allDay) { + val start = Calendar.getInstance() + start.timeInMillis = instance.begin + val end = Calendar.getInstance() + end.timeInMillis = instance.end + instance.begin = start.timeInMillis - start.timeZone.getOffset(start.timeInMillis) + instance.end = end.timeInMillis - end.timeZone.getOffset(end.timeInMillis) + } + eventList.add(Event(e.id.toInt(), e.title, instance.begin, instance.end, e.calendarId.toInt(), e.allDay, e.eventLocation?: "")) } } @@ -67,33 +79,17 @@ object CalendarUtil { } else { eventList.sortWith(Comparator { event: Event, event1: Event -> if (event.allDay && event1.allDay) { - 0 + event.startDate.compareTo(event1.startDate) + } else if (event.allDay) { + 1 + } else if (event1.allDay) { + -1 } else { - if (event.allDay) { - Log.d("AW1", event.title + " " + event.startDate + " - " + event1.title + " " + event1.startDate) - if (TimeUnit.MILLISECONDS.toMinutes(event1.startDate - now.timeInMillis) > 31 || now.timeInMillis > event1.endDate) { - 1 - } else { - -1 - } - } else if (event1.allDay) { - Log.d("AW2", event.title + " " + event.startDate + " - " + event1.title + " " + event1.startDate) - if (TimeUnit.MILLISECONDS.toMinutes(event.startDate - now.timeInMillis) > 31 || now.timeInMillis > event.endDate) { - -1 - } else { - 1 - } - } else { - if (event.startDate > event1.startDate) { - 1 - } else if (event.startDate < event1.startDate) { - -1 - } - 0 - } + event1.startDate.compareTo(event.startDate) } }) - saveNextEventData(context, eventList.get(0)) + saveEvents(context, eventList) + saveNextEventData(context, eventList[0]) } } } else { @@ -111,58 +107,15 @@ object CalendarUtil { val provider = CalendarProvider(context) return provider.calendars.list -/* - try { - val calendarCursor = context.contentResolver.query(Uri.parse("content://com.android.calendar/calendars"), - arrayOf(CalendarContract.Calendars._ID, CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CalendarContract.Calendars.ACCOUNT_NAME), - null, - null, - null) + } - if (calendarCursor != null && calendarCursor.count > 0) { - - calendarCursor.moveToFirst() - - for (j in 0 until calendarCursor.count) { - val id = calendarCursor.getInt(0) - val name = calendarCursor.getString(1) - val account = calendarCursor.getString(2) - calendarList.add(CalendarSelector(id, name, account)) - calendarCursor.moveToNext() - } - - calendarCursor.close() - } else { - Toast.makeText(context, R.string.error_no_calendar, Toast.LENGTH_SHORT).show() - } - } catch (ignored: Exception) { - ignored.printStackTrace() - try { - val calendarCursor = context.contentResolver.query(CalendarContract.Calendars.CONTENT_URI, - arrayOf(CalendarContract.Calendars._ID, CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CalendarContract.Calendars.ACCOUNT_NAME), - null, - null, - null) - - if (calendarCursor != null && calendarCursor.count > 0) { - - calendarCursor.moveToFirst() - - for (j in 0 until calendarCursor.count) { - calendarList.add(CalendarSelector(calendarCursor.getInt(0), calendarCursor.getString(1), calendarCursor.getString(2))) - calendarCursor.moveToNext() - } - - calendarCursor.close() - } - } catch (ignore: Exception) { - ignore.printStackTrace() - } finally { - return calendarList - } - } finally { - return calendarList - }*/ + fun saveEvents(context: Context, eventList: ArrayList) { + Realm.init(context) + val db = Realm.getDefaultInstance() + db.executeTransaction { realm -> + realm.where(Event::class.java).findAll().deleteAllFromRealm() + realm.copyToRealm(eventList) + } } @SuppressLint("ApplySharedPref") @@ -185,18 +138,59 @@ object CalendarUtil { val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) SP.edit() .putInt(Constants.PREF_NEXT_EVENT_ID, event.id) - .putString(Constants.PREF_NEXT_EVENT_NAME, event.title) - .putLong(Constants.PREF_NEXT_EVENT_START_DATE, event.startDate) - .putLong(Constants.PREF_NEXT_EVENT_END_DATE, event.endDate) - .putBoolean(Constants.PREF_NEXT_EVENT_ALL_DAY, event.allDay) - .putInt(Constants.PREF_NEXT_EVENT_CALENDAR_ID, event.calendarID) - .putString(Constants.PREF_NEXT_EVENT_LOCATION, event.address) .commit() Util.updateWidget(context) } fun getNextEvent(context: Context): Event { val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) - return Event(SP.getInt(Constants.PREF_NEXT_EVENT_ID, 0), SP.getString(Constants.PREF_NEXT_EVENT_NAME, ""), SP.getLong(Constants.PREF_NEXT_EVENT_START_DATE, 0), SP.getLong(Constants.PREF_NEXT_EVENT_END_DATE, 0), SP.getInt(Constants.PREF_NEXT_EVENT_CALENDAR_ID, 0), SP.getBoolean(Constants.PREF_NEXT_EVENT_ALL_DAY, false), SP.getString(Constants.PREF_NEXT_EVENT_LOCATION, "")) + Realm.init(context) + val db = Realm.getDefaultInstance() + val nextEvent = db.where(Event::class.java).equalTo("id", SP.getInt(Constants.PREF_NEXT_EVENT_ID, 0)).findFirst() + return if (nextEvent != null) { + nextEvent + } else { + val eventList = db.where(Event::class.java).findAll() + eventList[0]?: Event() + } + } + + @SuppressLint("ApplySharedPref") + fun goToNextEvent(context: Context) { + Realm.init(context) + val db = Realm.getDefaultInstance() + val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) + val eventList = db.where(Event::class.java).findAll() + + var found = false + for (e in eventList) { + if (e.id == SP.getInt(Constants.PREF_NEXT_EVENT_ID, 0)) { + if (eventList.indexOf(e) < eventList.size - 1) { + SP.edit() + .putInt(Constants.PREF_NEXT_EVENT_ID, eventList[eventList.indexOf(e) + 1]?.id ?: 0) + .commit() + } else { + SP.edit() + .putInt(Constants.PREF_NEXT_EVENT_ID, eventList[0]?.id ?: 0) + .commit() + } + found = true + break + } + } + + if (!found) { + SP.edit() + .putInt(Constants.PREF_NEXT_EVENT_ID, eventList[0]?.id ?: 0) + .commit() + } + + context.sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE)) + } + + fun getEventsCount(context: Context): Int { + Realm.init(context) + val db = Realm.getDefaultInstance() + return db.where(Event::class.java).findAll().size } } \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/util/CrocodileService.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/util/CrocodileService.kt new file mode 100644 index 0000000..8a8092a --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/util/CrocodileService.kt @@ -0,0 +1,51 @@ +package com.tommasoberlose.anotherwidget.util + +import android.app.Service +import android.content.Intent +import android.os.IBinder +import android.content.BroadcastReceiver +import android.content.Context +import com.tommasoberlose.anotherwidget.`object`.Constants +import android.content.IntentFilter +import android.util.Log + + +class CrocodileService : Service() { + + private val receiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action == Intent.ACTION_TIME_TICK && isScreenOn) { + sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE)) + } else if (intent.action == Intent.ACTION_SCREEN_OFF) { + isScreenOn = false + } else if (intent.action == Intent.ACTION_SCREEN_ON) { + isScreenOn = true + sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE)) + } + } + } + + private var isScreenOn = true + + override fun onCreate() { + super.onCreate() + val filter = IntentFilter() + filter.addAction(Intent.ACTION_TIME_TICK) + filter.addAction(Intent.ACTION_SCREEN_OFF) + filter.addAction(Intent.ACTION_SCREEN_ON) + registerReceiver(receiver, filter) + } + + override fun onDestroy() { + unregisterReceiver(receiver) + super.onDestroy() + } + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + return Service.START_NOT_STICKY + } + + override fun onBind(intent: Intent): IBinder? { + return null + } +} diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/util/Util.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/util/Util.kt index 44ab9a7..1f27951 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/util/Util.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/util/Util.kt @@ -149,7 +149,6 @@ object Util { val measuredHeight = View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.UNSPECIFIED) view.measure(measuredWidth, measuredHeight) view.layout(0,0, measuredWidth, measuredHeight) - Log.d("AW", "W: " + view.measuredWidth +" - H: " + view.measuredHeight) val returnedBitmap = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight, Bitmap.Config.ARGB_8888) //Bind a canvas to it val canvas = Canvas(returnedBitmap) @@ -222,6 +221,7 @@ object Util { 4 -> R.string.settings_show_until_subtitle_4 5 -> R.string.settings_show_until_subtitle_5 6 -> R.string.settings_show_until_subtitle_6 + 7 -> R.string.settings_show_until_subtitle_7 else -> R.string.settings_show_until_subtitle_1 } } @@ -235,7 +235,7 @@ object Util { } } - fun getTextshadowString(shadow: Int): Int { + fun getTextShadowString(shadow: Int): Int { return when (shadow) { 0 -> R.string.settings_text_shadow_subtitle_none 1 -> R.string.settings_text_shadow_subtitle_low @@ -244,12 +244,23 @@ object Util { } } + fun getCustomFontLabel(shadow: Int): Int { + return when (shadow) { + 0 -> R.string.custom_font_subtitle_0 + 1 -> R.string.custom_font_subtitle_1 + else -> R.string.custom_font_subtitle_1 + } + } + fun getCalendarIntent(context: Context): Intent { val SP = PreferenceManager.getDefaultSharedPreferences(context) + if (SP.getString(Constants.PREF_CALENDAR_APP_PACKAGE, "").equals("")) { val calIntent = Intent(Intent.ACTION_MAIN) calIntent.addCategory(Intent.CATEGORY_APP_CALENDAR) return calIntent + } else if (SP.getString(Constants.PREF_CALENDAR_APP_PACKAGE, "").equals("_")) { + return Intent() } else { val pm: PackageManager = context.packageManager return try { @@ -273,6 +284,8 @@ object Util { weatherIntent.data = Uri.parse("dynact://velour/weather/ProxyActivity") weatherIntent.component = ComponentName("com.google.android.googlequicksearchbox", "com.google.android.apps.gsa.velour.DynamicActivityTrampoline") return weatherIntent + } else if (SP.getString(Constants.PREF_WEATHER_APP_PACKAGE, "").equals("_")) { + return Intent() } else { val pm: PackageManager = context.packageManager return try { @@ -298,6 +311,8 @@ object Util { intent.putExtra("beginTime", e.startDate); intent.putExtra("endTime", e.endDate); return intent + } else if (SP.getString(Constants.PREF_EVENT_APP_PACKAGE, "") == ("_")) { + return Intent() } else { val pm: PackageManager = context.packageManager return try { @@ -321,6 +336,8 @@ object Util { val clockIntent = Intent(AlarmClock.ACTION_SHOW_ALARMS) clockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) return clockIntent + } else if (SP.getString(Constants.PREF_CLOCK_APP_PACKAGE, "").equals("_")) { + return Intent() } else { val pm: PackageManager = context.packageManager return try { @@ -498,7 +515,10 @@ object Util { } else if (eventDate.dayOfYear == nowDate.dayOfYear) { return String.format("%s", context.getString(R.string.today)) } else { - val days = TimeUnit.MILLISECONDS.toDays(difference) + var days = TimeUnit.MILLISECONDS.toDays(difference) + if (eventDate.hourOfDay < nowDate.hourOfDay || (eventDate.hourOfDay == nowDate.hourOfDay && eventDate.minuteOfHour <= nowDate.minuteOfHour)) { + days++ + } return String.format("%s %s%s", context.getString(R.string.in_code), days, context.getString(R.string.day_char)) } @@ -536,6 +556,7 @@ object Util { @SuppressLint("ApplySharedPref") fun updateSettingsByDefault(context: Context) { + context.startService(Intent(context, CrocodileService::class.java)) val SP = PreferenceManager.getDefaultSharedPreferences(context) val editor = SP.edit() if (SP.contains(Constants.PREF_SHOW_EVENT_LOCATION)) { diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/util/WeatherUtil.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/util/WeatherUtil.kt index e9b2565..2f2bfcc 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/util/WeatherUtil.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/util/WeatherUtil.kt @@ -2,6 +2,7 @@ package com.tommasoberlose.anotherwidget.util import android.Manifest import android.annotation.SuppressLint +import android.app.UiModeManager import android.content.Context import android.content.SharedPreferences import android.location.* @@ -21,6 +22,7 @@ import android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS import android.content.Intent import android.location.LocationManager import android.support.annotation.NonNull +import android.support.v7.app.AppCompatDelegate import android.util.Log import com.google.android.gms.awareness.Awareness import com.google.android.gms.awareness.snapshot.WeatherResponse @@ -83,7 +85,7 @@ object WeatherUtil { val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) SP.edit() .putFloat(Constants.PREF_WEATHER_TEMP, weather.getTemperature(if (SP.getString(Constants.PREF_WEATHER_TEMP_UNIT, "F").equals("F")) Weather.FAHRENHEIT else Weather.CELSIUS)) - .putString(Constants.PREF_WEATHER_ICON, getIconCodeFromAwareness(weather.conditions)) + .putString(Constants.PREF_WEATHER_ICON, getIconCodeFromAwareness(context, weather.conditions)) .putString(Constants.PREF_WEATHER_REAL_TEMP_UNIT, SP.getString(Constants.PREF_WEATHER_TEMP_UNIT, "F")) .commit() Util.updateWidget(context) @@ -161,7 +163,7 @@ object WeatherUtil { Util.updateWidget(context) } - fun getIconCodeFromAwareness(conditions: IntArray): String { + fun getIconCodeFromAwareness(context: Context, conditions: IntArray): String { var icon = "" return if (conditions.contains(Weather.CONDITION_UNKNOWN)) { "" @@ -186,10 +188,15 @@ object WeatherUtil { icon = "82" } - return if (Calendar.getInstance().get(Calendar.HOUR_OF_DAY) >= 19 || Calendar.getInstance().get(Calendar.HOUR_OF_DAY) < 7) { - icon + "n" - } else { - icon + "d" + val uiManager = context.getSystemService(Context.UI_MODE_SERVICE) as UiModeManager + return when { + uiManager.nightMode == UiModeManager.MODE_NIGHT_YES -> icon + "n" + uiManager.nightMode == UiModeManager.MODE_NIGHT_NO -> icon + "d" + else -> return if (Calendar.getInstance().get(Calendar.HOUR_OF_DAY) >= 19 || Calendar.getInstance().get(Calendar.HOUR_OF_DAY) < 7) { + icon + "n" + } else { + icon + "d" + } } } } diff --git a/app/src/main/res/drawable-hdpi/ic_action_close.png b/app/src/main/res/drawable-hdpi/ic_action_close.png new file mode 100644 index 0000000000000000000000000000000000000000..75e65bc9c7c7f1791b65c3a2635abc3ead693dca GIT binary patch literal 363 zcmV-x0hIoUP)yZ zpN?328K5E$>*(g0&m6;o5_E6I8Gy-*|w<4~Zst^3PT6UK}SX z*zu&l2bw}~VrSow?7=BJYf6pw~Y%s;#6e^SYCl8nUBaY97mXgKk)%81A|8#oP! zW0jhGM?~V)O4tWgp)jg>fEG}@Z_kA~LFFYW6&$-We-*caH&NUM0J-w$ppGKq6PZ$9DyPa&5 zkRucc8-z09GvOPshu^JZjanP+2I8ZH1;Q?&ZiyYjJYl30#M6WoLahzr9LmQMAr%(+ z0-@@FIEPBP$smcx@Yat5Ab)}*e2u7U@3lnOF+s@@F{_?wQV64K#7_=zuT>`xOm z9R^Uds@Synfza{87R{XMdwx0!V%|nJD*}g`5}BhlXCaA4J_Fbh$to?%3pIMsGA+jm zPY7Rq1d)?$bkE>GN$N5o?n9c@d~k_y9|iIQgkT@(_J#14@Qm=9?O&8^P%@}ZA;3N> zftDra`TY&XVO`?v9W(lkCN7+I_g^j-7?-l-O;lORjCXKg%CG?TjN_>~n8?KwgJ0^i zw%8Lz5a$2TTSD7JxENwwTPkP25LQs;ro;7lt3wQ<=gjD8i$hjnGr_RK^;||bBmvAZ zqcwq2+(vq&g~}pYk78zB$SyLY@3w7&BMD71K@qnSal$8NINgB&u4_itsML6o8NWBm zmwWO9=#jh}7Hk}xAsjLXvmpj>S2NIz+B$i}oTyImTnOYR(0_UNUTMcsR@1w0D-{Wl z{0IgY-UX-Ib$CT{t@0{}AV9vXnLi4C9Y5Ao&uy3KM83|WFRJ@aohGuXyRcGcV%Cp3 zL2ZhfoUdbAi@7W+&2HV4#7^53J9NF*@FnX_$Pc;B(Kynn*;S*e*lVhHf|8^VcoIM7 zK>8`+hhgSkb@t{B2U~Kpa18yf3GY{x+DwI2XtJmihYl{R4)E49k+2_B>_tuQBtZo? zfMeb8-^w_;*g4D-TbS(jfhul0O1O8*2b$*&0_yYJ^$d13+1~TNKYszVD}fnIhvHBG O0000(;`Pri-<-q)68>rseD9K>(*Pub@K28#fQ1O)t^rt?>;Qm|;!CRlaXafEKDP!C zcjrM6767LgXR0Bru23}y%ST)V!umG~Lon0<2!f@MsUesuu?nIZzz=(mw-EFIpCDQS zm|MO=a|@3+ejA<%Koy<^Kpma|019sn0Eaj4$k6Z<9T^gyq9a4Xn|EYrcpt0yWX=eH zX}EjS08B&xNdqttEjW5)OEZ@Fyv0snTe9@Q<#M@b^#J(YuO>nZDWd=Y002ovPDHLk FV1nG2csc+8 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_action_translate.png b/app/src/main/res/drawable-hdpi/ic_action_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..8a837ef5c2803f79b91e30c20b738a707386cd40 GIT binary patch literal 811 zcmV+`1JwM9P){zZs2CzXka!Yrf*}cbPh?$)f(VMQ z$gc4bHLI)tX{~|^6h%*WPj}Cb1Jm%4%}jO8_w`m+RnHa*`N&7QquFd089K5?z7y~X zuuiCEN(7MI0oVZiC7_66F2IpYy92ru0(QFi3K7dS7R$Ey&d4MF(6zXJs$L=}6n+RY zt;BjRAkzX8Obl&+SB&Ud*6PH#Sm_5@tJHHsz<63jwu_!;tHqoFz%NGr1%^~w0?vuN zecxivL$Uhj)9yImGBUpb!y5ZhK!e%8PCd&2feT_q%YZEkyKR6KVSDy}*pNu9B8W{X z>@EwNC#F3Uv@bF|=%@&dpFEV{^O$JvFw}+&J`aoi^$jqXq=*@@!fyb30NsH1;@&k2 ze|Hs?`Bu_xcUe4e8Sqqbt=-_OgE~Y+X;=#Bt zMlF3TY6Q$BE#N@J*Z&c)-(vn=u>k1nGy5O!?MjM#KgDU(>b(Q>8GKBNId=f}#I=h_ zkUvDLERT{>1ZJduji2Yt7E^NxQ?l?;3EDq_vxADTLGo7t(+VN0DiM_Xx!uYpQEK|Q zu)$E|OB(WRgz1QsIAF;AlkDD06e6+0#?tRIk9S9vxDUHQ z#I3`|;BUzDw@{x});~y=fSI+D-rECBI002ovPDHLkV1iwNhk*b9 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_action_close.png b/app/src/main/res/drawable-mdpi/ic_action_close.png new file mode 100644 index 0000000000000000000000000000000000000000..a1816d4c66c05fb2234d32c8319b197f9a5a4b0b GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJwVp1HAr-gYPIcsJFyLXSZT(`b zR587w|J}l0%cT_KmSjy{_BBDQY57|n-n`xCQjGR$9J^8f(3W4K(B_=Z2c}AP%{vzv zrTreXC{!q{7r)OUB|c}W@FOPseF3}L-Uz%Z@axF>Fh}6(Lx06t2j!i%G~aK@;P!tr z=dSRq4+q|I=3021^5TuVG$ZT7D@BX{JF7T6Pp)Y7usN>qrgPEribc#05n=7+I_td$#vd#(Ua0X9TKbLh*2~7aH`CXC# literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_action_dev.png b/app/src/main/res/drawable-mdpi/ic_action_dev.png new file mode 100644 index 0000000000000000000000000000000000000000..32efd39a861e58fdbec9dbe6937dc509ded68170 GIT binary patch literal 560 zcmV-00?+-4P)QHqD1sBbnQ|HO}i9mhoD0# z{ZIB?7-M+s+vh%?Hy?aJ-ptN-+?}1>=W@*+8_#e!^ne&h6H)PQ+M+>F0WI)rLKBq1 znv=plPy+*nu#rBf0`H{a3DDCJHqr%gyW)B9GlBSsZ;;g$Pb$PeZ6*=dS#z^#{{Uf{ zT06_(9VdahBFHiMY)~?~NmQ-GLyBsD0CR?I`K*~hU%5qLyf7K~Dwam#zX;C3mqrq0 zRRV3v0MU3>EoN>7l)&Q{{i10W#4mBa2g{l}XbEhAJ+b}34p;|wEUrg3aGNER#}AP)M0JY?O*}Uv(DL4IbO0XvkoSZXK^bk$1rOo;&!v(fVk+E zFBDV64q6T1#dPIB0yivPZJYrC!%25Cf%qwl)03SiW&=}na{bSQ&T`PSU$gPza+A=_ zzF2-E*@RFv=phj_vv>-a#Ir1o}9FZ0u)^5T0Wp8eNLWc yVd@hdg>aiLHKA#LCHd*>$PnVUfA-O8=lKHzn9n1f1!@8S0000kX^vZt1>X5PlU(Rz~I1m$O!t+^cf3>sc3YpG;R| zy+ok1yD_3Ez+=K22ClA>HHwB`WE`ACL>Mz??^*0H! ZGrU*dvAFPEX*STG44$rjF6*2UngGj%WS;;4 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_action_translate.png b/app/src/main/res/drawable-mdpi/ic_action_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..7188f7098747c6f90c79baa2d7afee3755f8dddb GIT binary patch literal 517 zcmV+g0{Z=lP)0^&9Tcpj1i<`SVkf)odIA{kCC+%|L^ zKta^81Mz;Sh2;a0Fny7HtVeCb^`Lp)35c1n$TI=)DyZelXyH3gB;R>qk@rKAccX;^ zKt5a!wO}U@^C8Iz0P!xU+)`{IL@h@c0`Y06MeR^AMj-Bnik-q1_dqcrr1Bt>Qb&{^ z1vRL^ibLWT;VIb8AURTu5(lsW@ggL{PC?lVftVGCo@HodLIS0sAO^&TkPJKk#3DG< zsw1g`Mc*1q9gv5mq|3sgwiqe2ijdUnl52SZk|77tLLwJUEh`Z3hRRI=VqqXY3FTLk zYB3{{Z(x?|0 zqyh_Sc?B-Zu{fd;Des?v>ZwM{MSG#*lZYw(st8$*<_LW(c|RMe{RqOdi7FG&;_x6T zDHluL$AuFJ8I(nax=`1RUT< zY&IjSOd!Gmy-0?#6Hx0!^+pWTP*5Bj5gA>uG@&)x;ROKz=o`MQp{6cL00000NkvXX Hu0mjfBwEt` literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_action_close.png b/app/src/main/res/drawable-xhdpi/ic_action_close.png new file mode 100644 index 0000000000000000000000000000000000000000..ffbdaa6ed2fdb34ba1a2771f0fe47e083171adf1 GIT binary patch literal 380 zcmV-?0fYXDP)Mm|RbbMj|KFe`sX1oQGoBDj&? z6TzK)N(8s^2@(9tM@H~1zaxS_`Gg35Kc|r&wgb+dq avC0=)0YW3ghy3&a0000=s__| zO$)I^DmN>&|7kk|XJJ`puJdtcb~f(74@B=dbI!SU&gba!dCObg@|L&suXsG352yjO z0(t>MfHA-*{!D(?0tf?w|AWF=sPG_Q95i+hlI)`J_i7khLfcnHw^GlQh)~( zUZ#!EtEzl~WXM|p9A@y$2J{;YjR6${+?Ck$7oePj_hrq6QvzKo_57NI*KZQo<0NsE znhmfb)lUGTT8YhWN*cQX@Lr=4s%34AS2KsCv%eJU3WR} zI1Y#aX3(do8emRTfMQO@Ur66ibN!Kx*(6EE?qHvgG*Y90alkPCp8UO>k#+6~HCo}} z^Bl^P)VRpP)?67w-mnOhHV4JY(P*%^H<`^iHZ7{z-zI)$SsBooUQo&k;o%VqgQ*N^ z%}-P09};0OPGK-1C`29LF^1D~5=uzZ!}HH6@{g(-ASytAn?m1dkp3lweoXZUyyB!i z0oY}f$3?p7k;fa=BS5RxW;tmuIYf|)y6N3=f)NUX7*A0F&zyBo;EVx!5(a-$Xj?@c z5KVv(2Q8^0-%@C&ISr^vU&@fZM#KO|8BAI@>GN@H6~mf;RHQMXLeEIzNGhB!8itls zB0(B+09pi?mti!_==KCGR{jV^i&VJ>Wti17jzPp?19U2%{}g9LoB4kR9JEmRLkxLW zrRx_Uyw9*`dj`Gz9u=mAfNcuX?>6-Uu!BVFFmEZ}IKx|BG|NueP#WV=ongq>=f(!) z*4GAOgKi59(94jG_=8-xHo59B2e^_(<*zxU%}s7@|7z#>^x5=kEOL~lGm?-{CuE+lr{FoE%!mI?Mn7002ovPDHLkV1jo4{b~RJ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_action_next.png b/app/src/main/res/drawable-xhdpi/ic_action_next.png new file mode 100644 index 0000000000000000000000000000000000000000..8c83b277a5038e173c796357b4a018e36bdba6c5 GIT binary patch literal 563 zcmV-30?hr1P)LXlY3k8i>5RiMP^ItP(2=O=% zXJO}d{^YB7_Rr4j-p!OsDwRs5QmIrc6vy!aXn+8GfEkD!V@9#{K?_tkH-8D9zl_9I_hFu>KE&*IaV zz+pfn88twF0e5tFzxigsca;Vw;2d;7=!*f#=G(N!E~tT9Fyef3xN5-9<`>r40cCo{ zjf!r-Be+OeuS_Q)EV2PZ(EH5?jR`3y;omhu z%0tLnO^{-MwVEL5DQu-CNc;hS+MtCJbm>;0zq6#FMKgST|rxf2sdm6AEcS zo|@o;0k7T}u#f`Xt*3ycB6tdpGKyfwi6XeE{{>6eVArKuUISl9v9+V6?3~14xS81cN&!EX+K!pa6lVRy8<(HE=PcfR! zUxP!=iSatU;m5R)lcTXT+uUT^yh^1~sZ^@M>I*VMaT@zs5kLR{002ovPDHLkV1h?; B`l$c_ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_action_translate.png b/app/src/main/res/drawable-xhdpi/ic_action_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..73a606b27bbe5218fb65ab9ab8cf6c1f31acc793 GIT binary patch literal 904 zcmV;319$w1P)m^JM1Z=%_{B5?IDsVXDu%oOUH~tE7vO)f%;yNf z<9VqUx&VJ7rpiLphR=`I@ zfU#zox}TBc#}#5+LZ1JmBBE^(E+7Qh_q0jXAd9;5`cIAhDt;G4j9$O+D1pGuuErv;P zv7RCQegL`^#v3MP(7er=FhwMFG1TV@(PvU|tSS+QEvnmW39y;?6n+B+0V7Dgzri;_ zEehilh}rfJqc&&3UZSjB=hGbX{0_x2&I`84HQS3~KY#0@z5Fl0(FE~V1##Id+h<#Z za}olKC5YQ2c~CO#f<3OpBv?-v^Exq;qQ6_SwwYoB6NyGKqZqf9*n3P7pIo0U^0NwO zdL>QoXN&80z*Flr0WWfHBskc-CNo_L?_Y>H$jz=M;N)+{kX#n53A1q`#CZQP{`WS* zen+z+e_KGFP1Bu8MIgNYeYk*vpUauo1f2X`5&2MmkqBk1DkQxBYNXGhOltyF@(Ln! zOM3qSB=(z3Y64#OS5(PMh_EW@{Vx?xsLa*`y5t2SOh|hFX(DE4sx<)w+5&i}OP&yc zRdfXj@Ba?i5fd|=nt+pkWQsf@!edGAzbA+{V!S5cK3g?SJ|aS|r1!5N_Yq+%89gW9 zZ~jSIFAY2Cz1X_JrfeiP8I2_V3kl*v=x zU+2f{vRHEFoIp{4VN*6n+(FE{E!j5+qD{e_z6QtbY0G)ZIY>?_X27I6-2T zox3|w^#045F?*f7JCO8#mgs&1v0poRcOc>YFAT+=bn5PaNb(lqt>RJkI0VrtRba0000VAAq*aSW-r^>)s|tV0eWuCY_} zxLLXXvMdx3X!*DBfm^}jbH1@(*;^bOU)-wSq;KFPWtGt}x3av5@6OzA^UrF>UF2u_ z08K*zTP)|F=f5&1U-A63si|rq#i@}|^So~S+50r*XHbUIjX%jND%EeZXxB)I6=Xe4 zs4R~8d?%

z*0A=f@}I=KJrq%)C4~-aYHysTfY#w?`g%xr4}f_pk?xQ)^Qd*OiD| z^waVFUJevE^y%(mPUGdbUM}0|q$SF$+mx0U86hTncg0-qteI!?bwBKN7oPNL#qzRQ z=g)@byWV}dBI2#aixm}bE3RG4*z!2geevZ!b=lr9Yq=7Ws<%(B2;MrmLV3&NK=%yw z#eEn2++-Kd?XhyQmMm>4`}CUQZOS#lTZIdhw>)-m&p194s=(TO!FlItXC#)KdiK5Y z#3ae)5UZbG8}uJChdWulU7*Z<%hA1aYjKEVvreFO>5o0X4NnMd{rp<-^k<2bmA6*1 z*{xZ)Sn<}*%lYmvUfBOT>EzD2wRrjczGKT5i_|YzytoCZoo`EXpG*e3tmOqhtD*(6 zB~Kiz7hj+Fyzt7soHr8mJeS2rc;=O0O zXFCboO*zK8{zb;}AJ^7gx1aT(D#l>Z;u6{1-oD!MlZD`0=9&G}1#2vH*t zBPA#T#qwQR+R!3YKvA*1_J2BOlg}mRS#I~;?!LG0y`AKfG==WY&g|~&%+BnKL@Zgd zWXX~xOO`BIvc#iICR0jSLWmP8fjE9wY9*vr*i5(^2h|eBQ#ot{9owL5gG_7!ZcxCfzS&ngRPhW z!aBBXg<0@1Y!joJgL$^wUc-;f6;uo(IO$71)WA zpb38!;kY8BsvC2JBZOp7gx^Z|%?E{sqHM`u?GgbPvu}_ z?|9h-eYMB8b!{;GZrO^9s+eCPF?;5a))6!4_AZJ;N_Lj)aHX;)gUp#v_u2vqc|O!1M4qV)_0G{_iwL2J5|w z{d~!meI(#SWBiUIhdnAfNjVTabBdZHAt4%TFGn7SRV>Z30#QJ=PrlEbqDY8{#=Dav zn^UqKu)Xgpr<3lmmi?g0rr=3Ps&Ej7rckmKI|Zzagp_FPFLF+Z*Q5e-I1v&cA+tWQq#8-3SUe6@R1&K zVnUU&3MiBs!u~BG(SB)xlLTAZJuidP(*eS|Tuu zwuV>%yLGLu+)lpWbkZXcmAoJzpkWi+M<1VX+U{4Ofc?C{n?&0!oD@f9W10+Z|0G8? z?J5+oiPOnMvGIQTyE3Gvq@N+2Uddykw)O?X(Hm5Gd%WbTHIjB_C$@{HXzvH)gGLqb zucdwZ+cyL*WYm-~2_)lohAaj>=?x^B53GQAq_<_)&pvSWPMlXBEr{WW%iupaM1uREADz&jO?l zx&-rs5&;r^4Pjhh@9%JfnS=l{3&_!$Xa{E-D1+%5+NDThp8n&l3icTh2N)WjnylB`ZR zcm?K+F^_$N`EiGJ1ZxcveuKjoA8!~piC~l`9oCPfyo?>8R&2=O+ef#Jt^Og#UU#U3 zYyhv@txz`XRua|qPHTzBicLgwdnJr#iYw~t({-~3!M}nJ{1j8febYB}Z?FmHGsRb# zvkZn#T>Zr)_+alFy@n|6h(x*VujE*8lS<>svi+##o9Z963(qd?8pz#5~uMb zXRzv=5y0DCq=9w|x3J9x_mha&v%3s?756?2b!8+hgzL?H8r~pv`hHPI*uSV3N6O1F z7am!f$7~U`+RPaSW-r_4cl#*WmyOmIryZ zjn>uH=8tTcDW|!}QB9SF8?WU}VtLzn#20k5zyn;f*aT z&=Cv_;%|e$F6LrzU^|ff`dabb(EFTzE$2z`?bhq0t_40>^hKG(|FifyJ07Djw4U_%r&cCXB{#8`uDx7*mPOB15+6~py0&Wr|f!r V_iVoUvtgmvv4FO#s90oRRwkA|fIp zA|fK~C5=X-3-n>oz8sy6_lTwZIiMeO0`zi@*3b!JDSr-l1oSV^yE%$Z=o3qc1H=I$ z;s9}gh&UifTs{l5H;^s_{afLHDbV==`-5Zej2)MsQN-o06%G8K!U1)qe>&)-!T~?ZiJD&r ztYRSLRk4!ay45%XKl8*={v5Cv^oGI#V*)>Z9Z+T9=LNBnKjROAUR43w6p!yLBbhCI`tz1d972j8_-EdPIlon_#nsuQad^c-N?Iun)6P*Nwn#6ZSv&=)n@ zSr#dvo{f(7s|y+qm@K-|VnPuY zzu!Wv&*1UP6s~g6GtEK&)*74{uS#_l3~FFG!pRWma~iO9PPKO!_HEq20SA*!^q}L< z5^UUM*w9xsR?Cp1KFw#?+07=&Ku4-V30l1XZKUop;exg{Tl8T#We4=oQK78^u#VL2 zus=16KAcMWu!o|KUo8gygGu>9qaVvGC&5k7r&G_82PwJH9W*9va~=0#Z-JG#qZP{5 z2Mq>%z{4s$&y-2(Ois|1@;>mP#jM-u3jd*QSR|3&n;rAvy(2$;;!reV}`KPnFC)YaP)}^j^NrFrj2iM zPUdh`e#bofe3@qcm?`Wqdx!}ftx;^ghq>5a(T@!pheKVljo(YN$O?9t6{X{Z>v_}^ zs{6CCzoHMA6I^6+f`ORE#|-zVK{B=7B$?8Lqt6u2zs~gOeU0#y%VRdhocTvx!Hy*y z-O0mYGTtA$vA^Q|L(JGt2Ztg0>FT(_%&!!Q7!+`XvHFahXO=Rs_?r&fK{F?KD)feX z(iiL)!qJH0evb3=hQYhvE(LdpJ~=w+8+J6|2q9##BKE()#QyUP-m8-nOb=oF6QN*7 z1CGAW8?*-J=UbxF_i1WBVSSu)0@`p-g@zqwB`i{0=k}+6EdDEZBMNtj{-km`7VKE` z*Oc?)O8sz$@V^TNWr0fU`iLdx$CVCuc*5LjY}hgAZ!Mw&{G1a|Qd3nVLzR*ke_2H1 z`{fR0RzkgOu#@TI-pCH{%N=?Ej!FYNnsxtB>X$o2aD*A@TVG9m?}%^h+GKef>1 zVrX+^OMg#bU0i0NS_uZ$sGzD`+NPkE;;Uy2Lo`NpRau4Fzr7l zlHd+`8vNl#u0axPwQgVkp5Bz6E zt!66ZC#CSNl>_o>HT@w6OgVw7b~LB$e<~; + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_choose_application.xml b/app/src/main/res/layout/activity_choose_application.xml index c208812..b596008 100644 --- a/app/src/main/res/layout/activity_choose_application.xml +++ b/app/src/main/res/layout/activity_choose_application.xml @@ -1,10 +1,9 @@ - - + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 73787e3..a5f2a9c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -153,6 +153,30 @@ android:id="@+id/font_color_label" style="@style/AnotherWidget.Settings.Subtitle"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/main_menu_layout.xml b/app/src/main/res/layout/main_menu_layout.xml index 17b61a3..072fa40 100644 --- a/app/src/main/res/layout/main_menu_layout.xml +++ b/app/src/main/res/layout/main_menu_layout.xml @@ -123,7 +123,6 @@ android:clickable="true" android:focusable="true" android:padding="16dp" - android:visibility="gone" android:id="@+id/action_support" android:orientation="horizontal"> - + android:gravity="center"> + + + diff --git a/app/src/main/res/layout/the_widget_sans.xml b/app/src/main/res/layout/the_widget_sans.xml index 87915ad..24e8686 100644 --- a/app/src/main/res/layout/the_widget_sans.xml +++ b/app/src/main/res/layout/the_widget_sans.xml @@ -6,15 +6,16 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" + android:scaleType="centerCrop" android:id="@+id/bitmap_container"/> - + android:alpha="0" + android:layout_centerInParent="true"> + \ No newline at end of file diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index ee92a6b..bbbdbae 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -120,7 +120,6 @@ Beta Font Product Sans L\'utilizzo del Product Sans disabilita i tap sugli elementi del widget. Ci sto attualmente lavorando. - 1 Ora dopo Tempo rimanente all\'evento Event Rifiutati Visibile @@ -129,4 +128,25 @@ App Calendario di Default Meteo Google App Orologio di Default + 1 Ora dopo + 30 Minuti dopo + Predefinita + Disabilita + Font Dispositivo + Product Sans + Font Widget + Mostra Evento\nSuccessivo + Contatore Eventi Multipli + Supporta lo Sviluppatore con + Aiuta con le Traduzioni + Apri una pull request su GitHub + Scopri i miei progetti + Stesso sviluppatore, più possibilità + Ops, sembra che qualcosa non abbia funzionato! + Grazie per il supporto! + Un Caffè Italiano + Qualche Ciambella + Una Cena Costosa + Una Colazione Inglese + Una Pranzo Veloce \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 96e532b..e5ddaad 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -11,4 +11,5 @@ #CCFFFFFF #80FFFFFF #204A85 + #222222 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6b055f1..7995ed3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -124,7 +124,6 @@ Beta Product Sans Font Using Product Sans disabled the possibilty to tap widget elements. I\'m working on it. - 1 hour later Time left for the event Visible Not Visible @@ -133,4 +132,26 @@ Google Calendar Event Details Default Calendar App Default Clock App + 1 hour later + 30 Minutes later + Default + Disabled + Widget Font + Device Font + Product Sans + Show Next\nEvent + Multiple Events Counter + Another Developer + Support the Developer with + Help with translations + Open a pull request on GitHub + Find out my projects + Same developer, more possibilities + Ops, something went wrong! + Thanks for support me! + An Italian Coffee + Some Glazed Donuts + An Expensive Dinner + An English Breakfast + A Quick Lunch diff --git a/app/src/main/res/xml-v21/the_widget_info.xml b/app/src/main/res/xml-v21/the_widget_info.xml index 6480405..5918086 100644 --- a/app/src/main/res/xml-v21/the_widget_info.xml +++ b/app/src/main/res/xml-v21/the_widget_info.xml @@ -2,11 +2,11 @@