aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/intro
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/intro')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt51
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt112
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt135
3 files changed, 298 insertions, 0 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt
new file mode 100644
index 00000000..d1d64712
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt
@@ -0,0 +1,51 @@
+package com.pitchedapps.frost.intro
+
+import android.os.Bundle
+import android.view.View
+import ca.allanwang.kau.utils.bindViewResettable
+import ca.allanwang.kau.utils.scaleXY
+import com.pitchedapps.frost.R
+import com.pitchedapps.frost.activities.IntroActivity
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.Theme
+
+/**
+ * Created by Allan Wang on 2017-07-28.
+ */
+class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) {
+
+ val light: View by bindViewResettable(R.id.intro_theme_light)
+ val dark: View by bindViewResettable(R.id.intro_theme_dark)
+ val amoled: View by bindViewResettable(R.id.intro_theme_amoled)
+ val glass: View by bindViewResettable(R.id.intro_theme_glass)
+
+ val themeList
+ get() = listOf(light, dark, amoled, glass)
+
+ override fun viewArray(): Array<Array<out View>>
+ = arrayOf(arrayOf(title), arrayOf(light, dark), arrayOf(amoled, glass))
+
+ override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ light.setThemeClick(Theme.LIGHT)
+ dark.setThemeClick(Theme.DARK)
+ amoled.setThemeClick(Theme.AMOLED)
+ glass.setThemeClick(Theme.GLASS)
+ val currentTheme = Prefs.theme - 1
+ if (currentTheme in 0..3)
+ themeList.forEachIndexed { index, v -> v.scaleXY = if (index == currentTheme) 1.6f else 0.8f }
+ }
+
+ private fun View.setThemeClick(theme: Theme) {
+ setOnClickListener {
+ v ->
+ Prefs.theme = theme.ordinal
+ (activity as IntroActivity).apply {
+ ripple.ripple(Prefs.bgColor, v.x + v.pivotX, v.y + v.pivotY)
+ theme()
+ }
+ themeList.forEach { it.animate().scaleXY(if (it == this) 1.6f else 0.8f).start() }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt
new file mode 100644
index 00000000..d19a488d
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt
@@ -0,0 +1,112 @@
+package com.pitchedapps.frost.intro
+
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.LayerDrawable
+import android.os.Bundle
+import android.view.View
+import ca.allanwang.kau.utils.colorToForeground
+import ca.allanwang.kau.utils.tint
+import ca.allanwang.kau.utils.withAlpha
+import com.pitchedapps.frost.R
+import com.pitchedapps.frost.utils.Prefs
+
+/**
+ * Created by Allan Wang on 2017-07-28.
+ */
+abstract class BaseImageIntroFragment(val titleRes: Int, val imageRes: Int, val descRes: Int) : BaseIntroFragment(R.layout.intro_image) {
+
+ val imageDrawable: LayerDrawable by lazyResettableRegistered { image.drawable as LayerDrawable }
+ val phone: Drawable by lazyResettableRegistered { imageDrawable.findDrawableByLayerId(R.id.intro_phone) }
+ val screen: Drawable by lazyResettableRegistered { imageDrawable.findDrawableByLayerId(R.id.intro_phone_screen) }
+
+ override fun viewArray(): Array<Array<out View>>
+ = arrayOf(arrayOf(title), arrayOf(desc))
+
+ override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
+ title.setText(titleRes)
+ image.setImageResource(imageRes)
+ desc.setText(descRes)
+ super.onViewCreated(view, savedInstanceState)
+ }
+
+ override fun themeFragmentImpl() {
+ super.themeFragmentImpl()
+ title.setTextColor(Prefs.textColor)
+ desc.setTextColor(Prefs.textColor)
+ phone.tint(Prefs.textColor)
+ screen.tint(Prefs.bgColor)
+ }
+
+ fun themeImageComponent(color: Int, vararg id: Int) {
+ id.forEach { imageDrawable.findDrawableByLayerId(it).tint(color) }
+ }
+
+ override fun onPageScrolledImpl(positionOffset: Float) {
+ super.onPageScrolledImpl(positionOffset)
+ val alpha = ((1 - Math.abs(positionOffset)) * 255).toInt()
+ //apply alpha to all layers except the phone base
+ (0 until imageDrawable.numberOfLayers).forEach {
+ val d = imageDrawable.getDrawable(it)
+ if (d != phone) d.alpha = alpha
+ }
+ }
+
+ fun firstImageFragmentTransition(offset: Float) {
+ if (offset < 0)
+ image.alpha = 1 + offset
+ }
+
+ fun lastImageFragmentTransition(offset: Float) {
+ if (offset > 0)
+ image.alpha = 1 - offset
+ }
+}
+
+class IntroAccountFragment : BaseImageIntroFragment(
+ R.string.intro_multiple_accounts, R.drawable.intro_phone_nav, R.string.intro_multiple_accounts_desc
+) {
+
+ override fun themeFragmentImpl() {
+ super.themeFragmentImpl()
+ themeImageComponent(Prefs.iconColor, R.id.intro_phone_avatar_1, R.id.intro_phone_avatar_2)
+ themeImageComponent(Prefs.bgColor.colorToForeground(), R.id.intro_phone_nav)
+ themeImageComponent(Prefs.headerColor, R.id.intro_phone_header)
+ }
+
+ override fun onPageScrolledImpl(positionOffset: Float) {
+ super.onPageScrolledImpl(positionOffset)
+ firstImageFragmentTransition(positionOffset)
+ }
+}
+
+class IntroTabTouchFragment : BaseImageIntroFragment(
+ R.string.intro_easy_navigation, R.drawable.intro_phone_tab, R.string.intro_easy_navigation_desc
+) {
+
+ override fun themeFragmentImpl() {
+ super.themeFragmentImpl()
+ themeImageComponent(Prefs.iconColor, R.id.intro_phone_icon_1, R.id.intro_phone_icon_2, R.id.intro_phone_icon_3, R.id.intro_phone_icon_4)
+ themeImageComponent(Prefs.headerColor, R.id.intro_phone_tab)
+ themeImageComponent(Prefs.textColor.withAlpha(80), R.id.intro_phone_icon_ripple)
+ }
+}
+
+class IntroTabContextFragment : BaseImageIntroFragment(
+ R.string.intro_context_aware, R.drawable.intro_phone_long_press, R.string.intro_context_aware_desc
+) {
+
+ override fun themeFragmentImpl() {
+ super.themeFragmentImpl()
+ themeImageComponent(Prefs.headerColor, R.id.intro_phone_toolbar)
+ themeImageComponent(Prefs.bgColor.colorToForeground(0.1f), R.id.intro_phone_image)
+ themeImageComponent(Prefs.bgColor.colorToForeground(0.2f), R.id.intro_phone_like, R.id.intro_phone_share)
+ themeImageComponent(Prefs.bgColor.colorToForeground(0.3f), R.id.intro_phone_comment)
+ themeImageComponent(Prefs.bgColor.colorToForeground(0.1f), R.id.intro_phone_card_1, R.id.intro_phone_card_2)
+ themeImageComponent(Prefs.textColor, R.id.intro_phone_image_indicator, R.id.intro_phone_comment_indicator, R.id.intro_phone_card_indicator)
+ }
+
+ override fun onPageScrolledImpl(positionOffset: Float) {
+ super.onPageScrolledImpl(positionOffset)
+ lastImageFragmentTransition(positionOffset)
+ }
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt
new file mode 100644
index 00000000..552fad3b
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt
@@ -0,0 +1,135 @@
+package com.pitchedapps.frost.intro
+
+import android.annotation.SuppressLint
+import android.content.res.ColorStateList
+import android.os.Bundle
+import android.support.constraint.ConstraintLayout
+import android.support.v4.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import ca.allanwang.kau.kotlin.LazyResettableRegistry
+import ca.allanwang.kau.utils.Kotterknife
+import ca.allanwang.kau.utils.bindViewResettable
+import ca.allanwang.kau.utils.setOnSingleTapListener
+import com.pitchedapps.frost.R
+import com.pitchedapps.frost.activities.IntroActivity
+import com.pitchedapps.frost.utils.Prefs
+import org.jetbrains.anko.childrenSequence
+
+/**
+ * Created by Allan Wang on 2017-07-28.
+ *
+ * Contains the base, start, and end fragments
+ */
+
+/**
+ * The core intro fragment for all other fragments
+ */
+abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() {
+
+ val screenWidth
+ get() = resources.displayMetrics.widthPixels
+
+ val lazyRegistry = LazyResettableRegistry()
+
+ protected fun translate(offset: Float, views: Array<Array<out View>>) {
+ val maxTranslation = offset * screenWidth
+ val increment = maxTranslation / views.size
+ views.forEachIndexed { i, group ->
+ group.forEach {
+ it.translationX = if (offset > 0) -maxTranslation + i * increment else -(i + 1) * increment
+ it.alpha = 1 - Math.abs(offset)
+ }
+ }
+ }
+
+ fun <T : Any> lazyResettableRegistered(initializer: () -> T) = lazyRegistry.lazy(initializer)
+
+ /*
+ * Note that these ids aren't actually inside all layouts
+ * However, they are in most of them, so they are added here
+ * for convenience
+ */
+ protected val title: TextView by bindViewResettable(R.id.intro_title)
+ protected val image: ImageView by bindViewResettable(R.id.intro_image)
+ protected val desc: TextView by bindViewResettable(R.id.intro_desc)
+
+ protected fun defaultViewArray(): Array<Array<out View>> = arrayOf(arrayOf(title), arrayOf(image), arrayOf(desc))
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ val view = inflater.inflate(layoutRes, container, false)
+ return view
+ }
+
+ override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ themeFragment()
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ Kotterknife.reset(this)
+ lazyRegistry.invalidateAll()
+ }
+
+ fun themeFragment() {
+ if (view != null) themeFragmentImpl()
+ }
+
+ protected open fun themeFragmentImpl() {
+ view?.childrenSequence()?.forEach { (it as? TextView)?.setTextColor(Prefs.textColor) }
+ }
+
+ protected val viewArray: Array<Array<out View>> by lazyResettableRegistered { viewArray() }
+
+ protected abstract fun viewArray(): Array<Array<out View>>
+
+ fun onPageScrolled(positionOffset: Float) {
+ if (view != null) onPageScrolledImpl(positionOffset)
+ }
+
+ protected open fun onPageScrolledImpl(positionOffset: Float) {
+ translate(positionOffset, viewArray)
+ }
+
+ fun onPageSelected() {
+ if (view != null) onPageSelectedImpl()
+ }
+
+ protected open fun onPageSelectedImpl() {
+
+ }
+}
+
+class IntroFragmentWelcome : BaseIntroFragment(R.layout.intro_welcome) {
+
+ override fun viewArray(): Array<Array<out View>> = defaultViewArray()
+
+ override fun themeFragmentImpl() {
+ super.themeFragmentImpl()
+ image.imageTintList = ColorStateList.valueOf(Prefs.textColor)
+ }
+}
+
+class IntroFragmentEnd : BaseIntroFragment(R.layout.intro_end) {
+
+ val container: ConstraintLayout by bindViewResettable(R.id.intro_end_container)
+
+ override fun viewArray(): Array<Array<out View>> = defaultViewArray()
+
+ override fun themeFragmentImpl() {
+ super.themeFragmentImpl()
+ image.imageTintList = ColorStateList.valueOf(Prefs.textColor)
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ container.setOnSingleTapListener { _, event ->
+ (activity as IntroActivity).finish(event.x, event.y)
+ }
+ }
+} \ No newline at end of file