From c316ac985223d255e9490f6f6ff62efd5d7905fb Mon Sep 17 00:00:00 2001 From: Akash Yadav Date: Mon, 13 May 2024 00:56:40 +0530 Subject: [PATCH] fix: implement edge-to-edge layout for editor activity --- .idea/deploymentTargetSelector.xml | 8 + .../androidide/activities/AboutActivity.kt | 6 +- .../activities/ContributorsActivity.kt | 6 +- .../activities/CrashHandlerActivity.java | 7 +- .../androidide/activities/MainActivity.kt | 4 +- .../activities/PreferencesActivity.java | 118 ---------- .../activities/PreferencesActivity.kt | 101 ++++++++ .../activities/editor/BaseEditorActivity.kt | 24 +- .../activities/editor/EditorActivityKt.kt | 4 +- .../androidide/app/EdgeToEdgeIDEActivity.kt | 149 ++++++++++++ .../androidide/app/LimitlessIDEActivity.kt | 98 -------- .../fragments/RunTasksDialogFragment.kt | 4 - .../sidebar/EditorSidebarFragment.kt | 31 ++- .../itsaky/androidide/ui/EditorBottomSheet.kt | 64 +++-- app/src/main/res/layout/activity_editor.xml | 9 +- .../itsaky/androidide/app/BaseIDEActivity.kt | 10 +- .../androidide/utils/EdgeToEdgeUtils.java | 219 ++++++++++++++++++ .../com/itsaky/androidide/utils/InsetUtils.kt | 2 + gradle/libs.versions.toml | 10 +- .../androidide/preferences/IDEPreferences.kt | 3 +- .../src/main/res/values-night/styles.xml | 3 - resources/src/main/res/values/styles.xml | 5 - .../androidide/projects/ProjectManagerImpl.kt | 2 +- 23 files changed, 611 insertions(+), 276 deletions(-) delete mode 100755 app/src/main/java/com/itsaky/androidide/activities/PreferencesActivity.java create mode 100755 app/src/main/java/com/itsaky/androidide/activities/PreferencesActivity.kt create mode 100644 app/src/main/java/com/itsaky/androidide/app/EdgeToEdgeIDEActivity.kt delete mode 100644 app/src/main/java/com/itsaky/androidide/app/LimitlessIDEActivity.kt create mode 100644 common/src/main/java/com/itsaky/androidide/utils/EdgeToEdgeUtils.java diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index b268ef36c..cd404bed8 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,6 +4,14 @@ diff --git a/app/src/main/java/com/itsaky/androidide/activities/AboutActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/AboutActivity.kt index 259a34b94..6ea9f43ac 100755 --- a/app/src/main/java/com/itsaky/androidide/activities/AboutActivity.kt +++ b/app/src/main/java/com/itsaky/androidide/activities/AboutActivity.kt @@ -34,7 +34,7 @@ import com.itsaky.androidide.BuildConfig import com.itsaky.androidide.R import com.itsaky.androidide.adapters.SimpleIconTitleDescriptionAdapter import com.itsaky.androidide.app.BaseApplication -import com.itsaky.androidide.app.LimitlessIDEActivity +import com.itsaky.androidide.app.EdgeToEdgeIDEActivity import com.itsaky.androidide.app.configuration.IDEBuildConfigProvider import com.itsaky.androidide.buildinfo.BuildInfo import com.itsaky.androidide.databinding.ActivityAboutBinding @@ -44,7 +44,7 @@ import com.itsaky.androidide.utils.BuildInfoUtils import com.itsaky.androidide.utils.flashSuccess import com.itsaky.androidide.utils.resolveAttr -class AboutActivity : LimitlessIDEActivity() { +class AboutActivity : EdgeToEdgeIDEActivity() { private var _binding: ActivityAboutBinding? = null private val binding: ActivityAboutBinding @@ -76,7 +76,7 @@ class AboutActivity : LimitlessIDEActivity() { setSupportActionBar(toolbar) supportActionBar!!.setDisplayHomeAsUpEnabled(true) supportActionBar!!.setTitle(R.string.about) - toolbar.setNavigationOnClickListener { finish() } + toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() } aboutHeader.apply { ideVersion.text = createVersionText() diff --git a/app/src/main/java/com/itsaky/androidide/activities/ContributorsActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/ContributorsActivity.kt index 59ad4eb64..f0c82b5a8 100644 --- a/app/src/main/java/com/itsaky/androidide/activities/ContributorsActivity.kt +++ b/app/src/main/java/com/itsaky/androidide/activities/ContributorsActivity.kt @@ -24,7 +24,7 @@ import androidx.activity.viewModels import androidx.core.view.isVisible import com.itsaky.androidide.R import com.itsaky.androidide.adapters.ContributorsGridAdapter -import com.itsaky.androidide.app.LimitlessIDEActivity +import com.itsaky.androidide.app.EdgeToEdgeIDEActivity import com.itsaky.androidide.databinding.ActivityContributorsBinding import com.itsaky.androidide.utils.getConnectionInfo import com.itsaky.androidide.viewmodel.ContributorsViewModel @@ -32,7 +32,7 @@ import com.itsaky.androidide.viewmodel.ContributorsViewModel /** * @author Akash Yadav */ -class ContributorsActivity : LimitlessIDEActivity() { +class ContributorsActivity : EdgeToEdgeIDEActivity() { private var _binding: ActivityContributorsBinding? = null private val binding: ActivityContributorsBinding @@ -54,7 +54,7 @@ class ContributorsActivity : LimitlessIDEActivity() { setSupportActionBar(toolbar) supportActionBar!!.setTitle(R.string.title_contributors) supportActionBar!!.setDisplayHomeAsUpEnabled(true) - toolbar.setNavigationOnClickListener { finish() } + toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() } githubContributors.apply { sectionTitle.setText(R.string.title_github_contributors) diff --git a/app/src/main/java/com/itsaky/androidide/activities/CrashHandlerActivity.java b/app/src/main/java/com/itsaky/androidide/activities/CrashHandlerActivity.java index 15ecf9db3..79c9df5c1 100644 --- a/app/src/main/java/com/itsaky/androidide/activities/CrashHandlerActivity.java +++ b/app/src/main/java/com/itsaky/androidide/activities/CrashHandlerActivity.java @@ -19,6 +19,7 @@ package com.itsaky.androidide.activities; import android.os.Bundle; import android.view.View; +import androidx.annotation.NonNull; import com.itsaky.androidide.app.IDEActivity; import com.itsaky.androidide.databinding.ActivityCrashHandlerBinding; import com.itsaky.androidide.fragments.CrashReportFragment; @@ -50,16 +51,12 @@ public class CrashHandlerActivity extends IDEActivity { } @Override + @NonNull protected View bindLayout() { binding = ActivityCrashHandlerBinding.inflate(getLayoutInflater()); return binding.getRoot(); } - @Override - public void onBackPressed() { - finishAffinity(); - } - @Override protected void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt index 207ed662c..90be39090 100755 --- a/app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt +++ b/app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt @@ -29,7 +29,7 @@ import androidx.transition.TransitionManager import androidx.transition.doOnEnd import com.google.android.material.transition.MaterialSharedAxis import com.itsaky.androidide.activities.editor.EditorActivityKt -import com.itsaky.androidide.app.LimitlessIDEActivity +import com.itsaky.androidide.app.EdgeToEdgeIDEActivity import com.itsaky.androidide.databinding.ActivityMainBinding import com.itsaky.androidide.preferences.internal.GeneralPreferences import com.itsaky.androidide.projects.ProjectManagerImpl @@ -43,7 +43,7 @@ import com.itsaky.androidide.viewmodel.MainViewModel.Companion.SCREEN_TEMPLATE_D import com.itsaky.androidide.viewmodel.MainViewModel.Companion.SCREEN_TEMPLATE_LIST import java.io.File -class MainActivity : LimitlessIDEActivity() { +class MainActivity : EdgeToEdgeIDEActivity() { private val viewModel by viewModels() private var _binding: ActivityMainBinding? = null diff --git a/app/src/main/java/com/itsaky/androidide/activities/PreferencesActivity.java b/app/src/main/java/com/itsaky/androidide/activities/PreferencesActivity.java deleted file mode 100755 index 8cceb0def..000000000 --- a/app/src/main/java/com/itsaky/androidide/activities/PreferencesActivity.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of AndroidIDE. - * - * AndroidIDE is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AndroidIDE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with AndroidIDE. If not, see . - */ - -package com.itsaky.androidide.activities; - -import android.graphics.Rect; -import android.os.Bundle; -import android.view.View; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import com.itsaky.androidide.R; -import com.itsaky.androidide.app.LimitlessIDEActivity; -import com.itsaky.androidide.databinding.ActivityPreferencesBinding; -import com.itsaky.androidide.fragments.IDEPreferencesFragment; -import com.itsaky.androidide.preferences.IDEPreferences; -import com.itsaky.androidide.preferences.RootPrefExtsKt; -import java.util.ArrayList; - -public class PreferencesActivity extends LimitlessIDEActivity { - - private ActivityPreferencesBinding binding; - private IDEPreferencesFragment rootFragment; - - public PreferencesActivity() { - super(true); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setSupportActionBar(binding.toolbar); - getSupportActionBar().setTitle(R.string.ide_preferences); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - binding.toolbar.setNavigationOnClickListener(v -> onBackPressed()); - - if (savedInstanceState != null) { - return; - } - - final var prefs = IDEPreferences.INSTANCE; - prefs.getChildren().clear(); - - RootPrefExtsKt.addRootPreferences(prefs); - - final var args = new Bundle(); - args.putParcelableArrayList( - IDEPreferencesFragment.EXTRA_CHILDREN, - new ArrayList<>(prefs.getChildren()) - ); - - final var root = getRootFragment(); - root.setArguments(args); - loadFragment(root); - } - - @Override - public void onInsetsUpdated(@NonNull Rect insets) { - super.onInsetsUpdated(insets); - - View toolbar = binding.toolbar; - toolbar.setPadding( - toolbar.getPaddingLeft() + insets.left, - toolbar.getPaddingTop(), - toolbar.getPaddingRight() + insets.right, - toolbar.getPaddingBottom() - ); - - View fragmentContainer = binding.fragmentContainerParent; - fragmentContainer.setPadding( - fragmentContainer.getPaddingLeft() + insets.left, - fragmentContainer.getPaddingTop(), - fragmentContainer.getPaddingRight() + insets.right, - fragmentContainer.getPaddingBottom() - ); - } - - @Override - @NonNull - protected View bindLayout() { - binding = ActivityPreferencesBinding.inflate(getLayoutInflater()); - return binding.getRoot(); - } - - private IDEPreferencesFragment getRootFragment() { - return rootFragment == null ? rootFragment = new IDEPreferencesFragment() : rootFragment; - } - - private void loadFragment(Fragment fragment) { - super.loadFragment(fragment, binding.fragmentContainer.getId()); - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - binding = null; - } -} diff --git a/app/src/main/java/com/itsaky/androidide/activities/PreferencesActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/PreferencesActivity.kt new file mode 100755 index 000000000..de3c019a1 --- /dev/null +++ b/app/src/main/java/com/itsaky/androidide/activities/PreferencesActivity.kt @@ -0,0 +1,101 @@ +/* + * This file is part of AndroidIDE. + * + * AndroidIDE is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AndroidIDE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with AndroidIDE. If not, see . + */ +package com.itsaky.androidide.activities + +import android.graphics.Rect +import android.os.Bundle +import android.view.View +import androidx.fragment.app.Fragment +import com.itsaky.androidide.R +import com.itsaky.androidide.app.EdgeToEdgeIDEActivity +import com.itsaky.androidide.databinding.ActivityPreferencesBinding +import com.itsaky.androidide.fragments.IDEPreferencesFragment +import com.itsaky.androidide.preferences.addRootPreferences +import com.itsaky.androidide.preferences.IDEPreferences as prefs + +class PreferencesActivity : EdgeToEdgeIDEActivity() { + + private var _binding: ActivityPreferencesBinding? = null + private val binding: ActivityPreferencesBinding + get() = checkNotNull(_binding) { "Activity has been destroyed" } + + private val rootFragment by lazy { + IDEPreferencesFragment() + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setSupportActionBar(binding.toolbar) + supportActionBar!!.setTitle(R.string.ide_preferences) + supportActionBar!!.setDisplayHomeAsUpEnabled(true) + + binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() } + + if (savedInstanceState != null) { + return + } + + (prefs.children as MutableList?)?.clear() + + prefs.addRootPreferences() + + val args = Bundle() + args.putParcelableArrayList( + IDEPreferencesFragment.EXTRA_CHILDREN, + ArrayList(prefs.children) + ) + + rootFragment.arguments = args + loadFragment(rootFragment) + } + + override fun onInsetsUpdated(insets: Rect) { + super.onInsetsUpdated(insets) + + val toolbar: View = binding.toolbar + toolbar.setPadding( + toolbar.paddingLeft + insets.left, + toolbar.paddingTop, + toolbar.paddingRight + insets.right, + toolbar.paddingBottom + ) + + val fragmentContainer: View = binding.fragmentContainerParent + fragmentContainer.setPadding( + fragmentContainer.paddingLeft + insets.left, + fragmentContainer.paddingTop, + fragmentContainer.paddingRight + insets.right, + fragmentContainer.paddingBottom + ) + } + + override fun bindLayout(): View { + _binding = ActivityPreferencesBinding.inflate( + layoutInflater) + return binding.root + } + + private fun loadFragment(fragment: Fragment) { + super.loadFragment(fragment, binding.fragmentContainer.id) + } + + override fun onDestroy() { + super.onDestroy() + _binding = null + } +} diff --git a/app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt index 2df8af2f3..d62ea0077 100644 --- a/app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt +++ b/app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt @@ -20,6 +20,7 @@ package com.itsaky.androidide.activities.editor import android.content.Intent import android.content.pm.PackageInstaller.SessionCallback import android.graphics.Color +import android.graphics.Rect import android.graphics.drawable.GradientDrawable import android.os.Bundle import android.text.SpannableStringBuilder @@ -28,6 +29,7 @@ import android.text.TextUtils import android.text.method.LinkMovementMethod import android.text.style.ClickableSpan import android.view.View +import android.view.ViewGroup import android.view.ViewTreeObserver.OnGlobalLayoutListener import androidx.activity.OnBackPressedCallback import androidx.activity.result.ActivityResult @@ -38,6 +40,8 @@ import androidx.annotation.GravityInt import androidx.annotation.StringRes import androidx.appcompat.app.ActionBarDrawerToggle import androidx.core.view.GravityCompat +import androidx.core.view.updateLayoutParams +import androidx.core.view.updatePaddingRelative import com.blankj.utilcode.util.FileUtils import com.blankj.utilcode.util.KeyboardUtils import com.blankj.utilcode.util.ThreadUtils @@ -50,11 +54,12 @@ import com.itsaky.androidide.R.string import com.itsaky.androidide.actions.ActionItem.Location.EDITOR_FILE_TABS import com.itsaky.androidide.adapters.DiagnosticsAdapter import com.itsaky.androidide.adapters.SearchListAdapter -import com.itsaky.androidide.app.IDEActivity +import com.itsaky.androidide.app.EdgeToEdgeIDEActivity import com.itsaky.androidide.databinding.ActivityEditorBinding import com.itsaky.androidide.databinding.LayoutDiagnosticInfoBinding import com.itsaky.androidide.events.InstallationResultEvent import com.itsaky.androidide.fragments.SearchResultFragment +import com.itsaky.androidide.fragments.sidebar.EditorSidebarFragment import com.itsaky.androidide.fragments.sidebar.FileTreeFragment import com.itsaky.androidide.handlers.EditorActivityLifecyclerObserver import com.itsaky.androidide.handlers.LspHandler.registerLanguageServers @@ -96,7 +101,7 @@ import java.io.File * @author Akash Yadav */ @Suppress("MemberVisibilityCanBePrivate") -abstract class BaseEditorActivity : IDEActivity(), TabLayout.OnTabSelectedListener, +abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSelectedListener, DiagnosticClickListener { protected val mLifecycleObserver = EditorActivityLifecyclerObserver() @@ -194,6 +199,19 @@ abstract class BaseEditorActivity : IDEActivity(), TabLayout.OnTabSelectedListen return this.binding.root } + override fun onInsetsUpdated(insets: Rect) { + super.onInsetsUpdated(insets) + this._binding?.apply { + drawerSidebar.getFragment() + .onApplyWindowInsets(insets) + + editorToolbar.updatePaddingRelative( + start = editorToolbar.paddingStart + insets.left, + end = editorToolbar.paddingEnd + insets.right + ) + } + } + @Subscribe(threadMode = MAIN) open fun onInstallationResult(event: InstallationResultEvent) { val intent = event.intent @@ -544,7 +562,7 @@ abstract class BaseEditorActivity : IDEActivity(), TabLayout.OnTabSelectedListen binding.apply { viewContainer.viewTreeObserver.addOnGlobalLayoutListener(observer) - bottomSheet.setOffsetAnchor(editorToolbar) + bottomSheet.setOffsetAnchor(editorAppBarLayout) } } diff --git a/app/src/main/java/com/itsaky/androidide/activities/editor/EditorActivityKt.kt b/app/src/main/java/com/itsaky/androidide/activities/editor/EditorActivityKt.kt index 72e97a9fa..9e2845b58 100644 --- a/app/src/main/java/com/itsaky/androidide/activities/editor/EditorActivityKt.kt +++ b/app/src/main/java/com/itsaky/androidide/activities/editor/EditorActivityKt.kt @@ -20,4 +20,6 @@ package com.itsaky.androidide.activities.editor /** * @author Akash Yadav */ -class EditorActivityKt : EditorHandlerActivity() \ No newline at end of file +class EditorActivityKt : EditorHandlerActivity() + +// TODO: Should we adjust to the display cutout insets? \ No newline at end of file diff --git a/app/src/main/java/com/itsaky/androidide/app/EdgeToEdgeIDEActivity.kt b/app/src/main/java/com/itsaky/androidide/app/EdgeToEdgeIDEActivity.kt new file mode 100644 index 000000000..4d3384617 --- /dev/null +++ b/app/src/main/java/com/itsaky/androidide/app/EdgeToEdgeIDEActivity.kt @@ -0,0 +1,149 @@ +/* + * This file is part of AndroidIDE. + * + * AndroidIDE is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AndroidIDE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with AndroidIDE. If not, see . + */ + +package com.itsaky.androidide.app + +import android.annotation.SuppressLint +import android.content.res.Configuration +import android.graphics.Rect +import android.os.Build +import android.os.Bundle +import android.os.PersistableBundle +import android.view.WindowInsets +import android.view.WindowManager +import androidx.core.view.OnApplyWindowInsetsListener +import androidx.core.view.ViewCompat +import androidx.core.view.doOnAttach +import androidx.core.view.setPadding +import com.itsaky.androidide.utils.EdgeToEdgeUtils +import com.itsaky.androidide.utils.getInsets +import org.slf4j.LoggerFactory + +/** + * Same as IDEActivity but DecorFitsSystemWindows is set to false + * Useful for creating immersive edge-to-edge experiences. + * + * @author Smooth E + * @author Akash Yadav + */ +abstract class EdgeToEdgeIDEActivity : IDEActivity() { + + /** + * Whether edge-to-edge should be applied to the activity. + */ + protected open var edgeToEdgeEnabled = true + + /** + * Whether the decor view padding should be updated to match the system bars in landscape orientation. + */ + protected open var eteUpdateDecorViewPaddingInLandscape = true + + /** + * Style for the status bar. + */ + protected open val statusBarStyle = EdgeToEdgeUtils.DEFAULT_STATUS_BAR_STYLE!! + + /** + * Style for the navigation bar. + */ + protected open val navigationBarStyle = EdgeToEdgeUtils.DEFAULT_NAVIGATION_BAR_STYLE!! + + /** + * Original padding of the window's decor view. + */ + protected open var decorViewPadding: Rect? = null + + override var enableSystemBarTheming: Boolean + get() = false + set(@Suppress("UNUSED_PARAMETER") value) { + throw UnsupportedOperationException("Use edgeToEdgeEnabled and systemBarStyles instead") + } + + private val log = LoggerFactory.getLogger(EdgeToEdgeIDEActivity::class.java) + + @SuppressLint("WrongConstant") + private val onApplyWindowInsetsListener = OnApplyWindowInsetsListener { v, insets -> + if (!eteUpdateDecorViewPaddingInLandscape || + v.resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE + ) { + decorViewPadding?.also { p -> + // when switching from landscape to portrait, restore the original padding + v.setPadding(p.left, p.top, p.right, p.bottom) + } + return@OnApplyWindowInsetsListener insets + } + + if (decorViewPadding == null) { + Rect().apply { + left = v.paddingLeft + top = v.paddingTop + right = v.paddingRight + bottom = v.paddingBottom + }.also { paddings -> + decorViewPadding = paddings + } + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + v.setPadding( + insets.getInsets(WindowInsets.Type.systemBars()).left, + 0, + insets.getInsets(WindowInsets.Type.systemBars()).right, + insets.getInsets(WindowInsets.Type.systemBars()).bottom) + } else { + @Suppress("DEPRECATION") + v.setPadding( + insets.stableInsetLeft, + 0, + insets.stableInsetRight, + insets.stableInsetBottom) + } + + insets + } + + override fun onCreate(savedInstanceState: Bundle?) { + applyEdgeToEdge() + super.onCreate(savedInstanceState) + } + + override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) { + applyEdgeToEdge() + super.onCreate(savedInstanceState, persistentState) + } + + @SuppressLint("RestrictedApi") + private fun applyEdgeToEdge() { + this.window!!.apply { + addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + @Suppress("DEPRECATION") + clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) + } + + EdgeToEdgeUtils.applyEdgeToEdge(this, this.statusBarStyle, this.navigationBarStyle) + + ViewCompat.setOnApplyWindowInsetsListener( + this.window.decorView, + this.onApplyWindowInsetsListener + ) + + this.window.decorView.doOnAttach { decorView -> onInsetsUpdated(getInsets(decorView)) } + } + + /** Called whenever insets are updated */ + protected open fun onInsetsUpdated(insets: Rect) {} +} diff --git a/app/src/main/java/com/itsaky/androidide/app/LimitlessIDEActivity.kt b/app/src/main/java/com/itsaky/androidide/app/LimitlessIDEActivity.kt deleted file mode 100644 index 913ef64dc..000000000 --- a/app/src/main/java/com/itsaky/androidide/app/LimitlessIDEActivity.kt +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of AndroidIDE. - * - * AndroidIDE is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AndroidIDE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with AndroidIDE. If not, see . - */ - -package com.itsaky.androidide.app - -import android.content.res.Configuration -import android.graphics.Color -import android.graphics.Rect -import android.os.Build -import android.os.Bundle -import android.os.PersistableBundle -import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES -import androidx.core.view.WindowCompat -import androidx.core.view.doOnAttach -import com.itsaky.androidide.utils.NavigationBar -import com.itsaky.androidide.utils.getInsets -import com.itsaky.androidide.utils.resolveAttr - -/** - * Same as IDEActivity but DecorFitsSystemWindows is set to false - * Useful for creating immersive edge-to-edge experiences - * - * @author Smooth E - */ -abstract class LimitlessIDEActivity( - private val highlightNavigationBar: Boolean = false -) : IDEActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - makeLimitless() - installOnDecorViewAttachedListener() - } - - override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) { - super.onCreate(savedInstanceState, persistentState) - makeLimitless() - installOnDecorViewAttachedListener() - } - - private fun makeLimitless() { - WindowCompat.setDecorFitsSystemWindows(window, false) - - paintNavigationBar() - - // This removes a black strip on the side where the camera cutout is in landscape mode - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - window.attributes.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES - } - } - - private fun installOnDecorViewAttachedListener() { - window.decorView.doOnAttach { decorView -> onInsetsUpdated(getInsets(decorView)) } - } - - /** Called whenever insets are updated */ - open fun onInsetsUpdated(insets: Rect) { } - - private fun paintNavigationBar() { - window.statusBarColor = Color.TRANSPARENT - window.navigationBarColor = Color.TRANSPARENT - - if (!highlightNavigationBar) { - return - } - - val refrainHighlighting = - NavigationBar.getInteractionMode(this) == NavigationBar.MODE_GESTURES || - resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - - if (refrainHighlighting) { - return - } - - val navigationBarColor = resolveAttr(com.google.android.material.R.attr.colorSurface) - window.navigationBarColor = navigationBarColor - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - val dividerColor = resolveAttr(com.google.android.material.R.attr.colorOutlineVariant) - window.navigationBarDividerColor = dividerColor - } - } - -} diff --git a/app/src/main/java/com/itsaky/androidide/fragments/RunTasksDialogFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/RunTasksDialogFragment.kt index 86f6d55df..26fa094c8 100644 --- a/app/src/main/java/com/itsaky/androidide/fragments/RunTasksDialogFragment.kt +++ b/app/src/main/java/com/itsaky/androidide/fragments/RunTasksDialogFragment.kt @@ -89,10 +89,6 @@ class RunTasksDialogFragment : BottomSheetDialogFragment() { val dialog = object : BottomSheetDialog(requireContext(), theme) { override fun onAttachedToWindow() { super.onAttachedToWindow() - window?.apply { - WindowCompat.setDecorFitsSystemWindows(this, false) - updateSystemBarColors(navigationBarColor = Color.TRANSPARENT) - } findViewById(com.google.android.material.R.id.container)?.apply { doOnApplyWindowInsets { view, insets, _, margins -> insets.getInsets(statusBars() or navigationBars()).apply { diff --git a/app/src/main/java/com/itsaky/androidide/fragments/sidebar/EditorSidebarFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/sidebar/EditorSidebarFragment.kt index 6088df654..5fa152fd6 100644 --- a/app/src/main/java/com/itsaky/androidide/fragments/sidebar/EditorSidebarFragment.kt +++ b/app/src/main/java/com/itsaky/androidide/fragments/sidebar/EditorSidebarFragment.kt @@ -17,8 +17,16 @@ package com.itsaky.androidide.fragments.sidebar +import android.graphics.Rect import android.os.Bundle import android.view.View +import android.view.ViewGroup.MarginLayoutParams +import androidx.core.view.marginBottom +import androidx.core.view.marginTop +import androidx.core.view.updateLayoutParams +import androidx.core.view.updateMarginsRelative +import androidx.core.view.updatePadding +import androidx.core.view.updatePaddingRelative import com.itsaky.androidide.databinding.FragmentEditorSidebarBinding import com.itsaky.androidide.fragments.FragmentWithBinding import com.itsaky.androidide.utils.EditorSidebarActions @@ -32,14 +40,33 @@ class EditorSidebarFragment : FragmentWithBinding( FragmentEditorSidebarBinding::inflate ) { + internal fun onApplyWindowInsets(insets: Rect) { + _binding?.apply { + title.updateLayoutParams { + updateMarginsRelative( + top = title.marginTop + insets.top, + ) + } + fragmentContainer.updateLayoutParams { + updateMarginsRelative( + bottom = fragmentContainer.marginBottom + insets.bottom, + ) + } + navigation.updatePadding( + top = navigation.paddingTop + insets.top, + bottom = navigation.paddingBottom + insets.bottom, + left = navigation.paddingLeft + insets.left, + ) + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - EditorSidebarActions.setup(this) } /** - * Performs the action only if the binding is not null. + * Get the (nullable) binding object for this fragment. */ internal fun getBinding() = _binding } \ No newline at end of file diff --git a/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt b/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt index 35fa3184e..303168201 100644 --- a/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt +++ b/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt @@ -19,16 +19,20 @@ package com.itsaky.androidide.ui import android.app.Activity import android.content.Context +import android.graphics.Rect import android.text.TextUtils import android.util.AttributeSet import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.ViewTreeObserver import android.widget.RelativeLayout import androidx.annotation.GravityInt import androidx.appcompat.widget.TooltipCompat +import androidx.core.view.ViewCompat import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding +import androidx.core.view.updatePaddingRelative import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.transition.TransitionManager @@ -54,6 +58,7 @@ import com.itsaky.androidide.tasks.TaskExecutor.executeAsyncProvideError import com.itsaky.androidide.utils.IntentUtils.shareFile import com.itsaky.androidide.utils.Symbols.forFile import com.itsaky.androidide.utils.flashError +import com.itsaky.androidide.utils.getInsets import org.slf4j.LoggerFactory import java.io.File import java.io.IOException @@ -63,6 +68,7 @@ import java.nio.file.Path import java.nio.file.StandardOpenOption.CREATE_NEW import java.nio.file.StandardOpenOption.WRITE import java.util.concurrent.Callable +import kotlin.math.roundToInt /** * Bottom sheet shown in editor activity. @@ -84,12 +90,14 @@ constructor( @JvmField var binding: LayoutEditorBottomSheetBinding - val pagerAdapter: EditorBottomSheetTabAdapter + private var windowInsets: Rect? = null + companion object { private val log = LoggerFactory.getLogger(EditorBottomSheet::class.java) + private const val COLLAPSE_HEADER_AT_OFFSET = 0.5f const val CHILD_HEADER = 0 const val CHILD_SYMBOL_INPUT = 1 @@ -160,6 +168,11 @@ constructor( sheet.state = BottomSheetBehavior.STATE_EXPANDED } } + + ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets -> + this.windowInsets = getInsets(view) + insets + } } init { @@ -184,23 +197,52 @@ constructor( override fun onGlobalLayout() { val sheet = BottomSheetBehavior.from(this@EditorBottomSheet) val offset = view.height + SizeUtils.dp2px(1f) + val collapsedHeight = collapsedHeight + sheet.isFitToContents = false - sheet.halfExpandedRatio = 0.3f + sheet.skipCollapsed = true sheet.isGestureInsetBottomIgnored = false - sheet.peekHeight = binding.headerContainer.height + sheet.peekHeight = collapsedHeight.roundToInt() sheet.expandedOffset = offset view.viewTreeObserver.removeOnGlobalLayoutListener(this) - binding.root.updatePadding(bottom = offset + SizeUtils.dp2px(16f)) + val insetBottom = windowInsets?.bottom ?: 0 + binding.root.updatePadding(bottom = offset + insetBottom) + binding.headerContainer.apply { + updatePaddingRelative(bottom = paddingBottom + insetBottom) + updateLayoutParams { + height = (collapsedHeight + insetBottom).roundToInt() + } + } } } + view.viewTreeObserver.addOnGlobalLayoutListener(listener) } - fun onSlide(offset: Float) { - if (offset >= 0.5f) { - updateCollapsedHeight(((0.5f - offset) + 0.5f) * 2f) - } else updateCollapsedHeight(1f) + fun onSlide(sheetOffset: Float) { + val heightScale = if (sheetOffset >= COLLAPSE_HEADER_AT_OFFSET) { + ((COLLAPSE_HEADER_AT_OFFSET - sheetOffset) + COLLAPSE_HEADER_AT_OFFSET) * 2f + } else { + 1f + } + + val paddingScale = if (sheetOffset <= COLLAPSE_HEADER_AT_OFFSET) { + ((1f - sheetOffset) * 2f) - 1f + } else { + 0f + } + + val insetBottom = windowInsets?.bottom ?: 0 + val padding = insetBottom * paddingScale + binding.headerContainer.apply { + updateLayoutParams { + height = ((collapsedHeight + padding) * heightScale).roundToInt() + } + updatePaddingRelative( + bottom = padding.roundToInt() + ) + } } fun showChild(index: Int) { @@ -276,12 +318,6 @@ constructor( } } - private fun updateCollapsedHeight(offset: Float) { - binding.headerContainer.updateLayoutParams { - height = (collapsedHeight * offset).toInt() - } - } - private fun shareFile(file: File) { shareFile(context, file, "text/plain") } diff --git a/app/src/main/res/layout/activity_editor.xml b/app/src/main/res/layout/activity_editor.xml index 73ec0a634..78048cad5 100755 --- a/app/src/main/res/layout/activity_editor.xml +++ b/app/src/main/res/layout/activity_editor.xml @@ -6,8 +6,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:animateLayoutChanges="true" - tools:ignore="DuplicateIncludedIds" - tools:openDrawer="start"> + android:background="?attr/colorSurface" + tools:ignore="DuplicateIncludedIds"> @@ -55,8 +55,7 @@ android:id="@+id/editor_container" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginBottom="@dimen/editor_sheet_peek_height" - android:background="?attr/colorSurface" /> + android:layout_marginBottom="@dimen/editor_sheet_peek_height" /> . + */ + +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.itsaky.androidide.utils; + +import static android.graphics.Color.TRANSPARENT; +import static com.google.android.material.color.MaterialColors.isColorLight; + +import android.content.Context; +import android.graphics.Color; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.view.Window; +import androidx.activity.EdgeToEdge; +import androidx.activity.SystemBarStyle; +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.activity.ComponentActivity; +import androidx.core.graphics.ColorUtils; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsControllerCompat; +import com.google.android.material.color.MaterialColors; + +/** + * A util class that helps apply edge-to-edge mode to activity/dialog windows. + *

+ * AndroidIDE Changed: Allow to choose if the status bar and navigation bar's color should + * be changed or not. + * + * @see EdgeToEdgeUtils.java + */ +public class EdgeToEdgeUtils { + + private static final int EDGE_TO_EDGE_BAR_ALPHA = 128; + + public static final int DEFAULT_LIGHT_SCRIM = EdgeToEdge.getDefaultLightScrim(); + public static final int DEFAULT_DARK_SCRIM = EdgeToEdge.getDefaultDarkScrim(); + + public static final SystemBarStyle DEFAULT_STATUS_BAR_STYLE = SystemBarStyle.auto(TRANSPARENT, + TRANSPARENT); + public static final SystemBarStyle DEFAULT_NAVIGATION_BAR_STYLE = SystemBarStyle.auto( + DEFAULT_LIGHT_SCRIM, DEFAULT_DARK_SCRIM); + + private EdgeToEdgeUtils() { + } + + /** + * Enable edge-to-edge mode for the provided activity, using the built-in + * {@link EdgeToEdge#enable(androidx.activity.ComponentActivity, SystemBarStyle, + * SystemBarStyle)}. + * + * @param activity The activity to enable edge-to-edge mode for. + * @param statusBarStyle The status bar style to use. + * @param navigationBarStyle The navigation bar style to use. + */ + public static void applyEdgeToEdge( + ComponentActivity activity, + SystemBarStyle statusBarStyle, + SystemBarStyle navigationBarStyle + ) { + EdgeToEdge.enable(activity, statusBarStyle, navigationBarStyle); + } + + /** + * Applies or removes edge-to-edge mode to the provided {@link Window}. When edge-to-edge mode is + * applied, the activities, or the non-floating dialogs, that host the provided window will be + * drawn over the system bar area by default and the system bar colors will be adjusted according + * to the background color you provide. + */ + public static void applyEdgeToEdgeManually( + @NonNull Window window, + boolean edgeToEdgeEnabled, + @Nullable @ColorInt Integer statusBarColor, + @Nullable @ColorInt Integer navBarColor) { + applyEdgeToEdgeManually(window, edgeToEdgeEnabled, null, null, statusBarColor, + navBarColor); + } + + /** + * Applies or removes edge-to-edge mode to the provided {@link Window}. When edge-to-edge mode is + * applied, the activities, or the non-floating dialogs, that host the provided window will be + * drawn over the system bar area by default and the system bar colors will be adjusted according + * to the background color you provide. + * + * @param statusBarOverlapBackgroundColor The reference background color to decide the + * text/icon colors on status bars. {@code null} to use + * the default color from + * {@code ?android:attr/colorBackground}. + * @param navigationBarOverlapBackgroundColor The reference background color to decide the icon + * colors on navigation bars.{@code null} to use the + * default color from + * {@code ?android:attr/colorBackground}. + */ + public static void applyEdgeToEdgeManually( + @NonNull Window window, + boolean edgeToEdgeEnabled, + @Nullable @ColorInt Integer statusBarOverlapBackgroundColor, + @Nullable @ColorInt Integer navigationBarOverlapBackgroundColor, + @Nullable @ColorInt Integer statusBarColor, + @Nullable @ColorInt Integer navBarColor + ) { + + // If the overlapping background color is unknown or TRANSPARENT, use the default one. + boolean useDefaultBackgroundColorForStatusBar = + statusBarOverlapBackgroundColor == null || statusBarOverlapBackgroundColor == 0; + boolean useDefaultBackgroundColorForNavigationBar = + navigationBarOverlapBackgroundColor == null || navigationBarOverlapBackgroundColor == 0; + if (useDefaultBackgroundColorForStatusBar || useDefaultBackgroundColorForNavigationBar) { + int defaultBackgroundColor = + MaterialColors.getColor(window.getContext(), android.R.attr.colorBackground, Color.BLACK); + if (useDefaultBackgroundColorForStatusBar) { + statusBarOverlapBackgroundColor = defaultBackgroundColor; + } + if (useDefaultBackgroundColorForNavigationBar) { + navigationBarOverlapBackgroundColor = defaultBackgroundColor; + } + } + + WindowCompat.setDecorFitsSystemWindows(window, !edgeToEdgeEnabled); + + int color = statusBarColor != null ? statusBarColor + : getStatusBarColor(window.getContext(), edgeToEdgeEnabled); + window.setStatusBarColor(color); + setLightStatusBar( + window, + isUsingLightSystemBar(color, isColorLight(statusBarOverlapBackgroundColor))); + + color = navBarColor != null ? navBarColor + : getNavigationBarColor(window.getContext(), edgeToEdgeEnabled); + window.setNavigationBarColor(color); + setLightNavigationBar( + window, + isUsingLightSystemBar( + color, isColorLight(navigationBarOverlapBackgroundColor))); + } + + /** + * Changes the foreground color of the status bars to light or dark so that the items on the bar + * can be read clearly. + * + * @param window Window that hosts the status bars + * @param isLight {@code true} to make the foreground color light + */ + public static void setLightStatusBar(@NonNull Window window, boolean isLight) { + WindowInsetsControllerCompat insetsController = + WindowCompat.getInsetsController(window, window.getDecorView()); + insetsController.setAppearanceLightStatusBars(isLight); + } + + /** + * Changes the foreground color of the navigation bars to light or dark so that the items on the + * bar can be read clearly. + * + * @param window Window that hosts the status bars + * @param isLight {@code true} to make the foreground color light. + */ + public static void setLightNavigationBar(@NonNull Window window, boolean isLight) { + WindowInsetsControllerCompat insetsController = + WindowCompat.getInsetsController(window, window.getDecorView()); + insetsController.setAppearanceLightNavigationBars(isLight); + } + + private static int getStatusBarColor(Context context, boolean isEdgeToEdgeEnabled) { + if (isEdgeToEdgeEnabled) { + return TRANSPARENT; + } + return MaterialColors.getColor(context, android.R.attr.statusBarColor, Color.BLACK); + } + + private static int getNavigationBarColor(Context context, boolean isEdgeToEdgeEnabled) { + // Light navigation bars are only supported on O_MR1+. So we need to use a translucent black + // navigation bar instead to ensure the text/icon contrast of it. + if (isEdgeToEdgeEnabled && VERSION.SDK_INT < VERSION_CODES.O_MR1) { + int opaqueNavBarColor = + MaterialColors.getColor(context, android.R.attr.navigationBarColor, Color.BLACK); + return ColorUtils.setAlphaComponent(opaqueNavBarColor, EDGE_TO_EDGE_BAR_ALPHA); + } + if (isEdgeToEdgeEnabled) { + return TRANSPARENT; + } + return MaterialColors.getColor(context, android.R.attr.navigationBarColor, Color.BLACK); + } + + private static boolean isUsingLightSystemBar(int systemBarColor, boolean isLightBackground) { + return isColorLight(systemBarColor) || (systemBarColor == TRANSPARENT && isLightBackground); + } +} diff --git a/common/src/main/java/com/itsaky/androidide/utils/InsetUtils.kt b/common/src/main/java/com/itsaky/androidide/utils/InsetUtils.kt index 076514387..f446ed4fe 100644 --- a/common/src/main/java/com/itsaky/androidide/utils/InsetUtils.kt +++ b/common/src/main/java/com/itsaky/androidide/utils/InsetUtils.kt @@ -42,6 +42,7 @@ fun getInsets(view: View): Rect { val typeMask = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout() rootWindowInsets.getInsetsIgnoringVisibility(typeMask) } else { + @Suppress("DEPRECATION") view.rootWindowInsets.stableInsets } @@ -52,6 +53,7 @@ fun getInsets(view: View): Rect { receivedInsets.bottom ) } else { + @Suppress("DEPRECATION") insets = Rect( rootWindowInsets.stableInsetLeft, rootWindowInsets.stableInsetTop, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d8b3b3576..c7c6983fe 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ kotlin-coroutines = "1.8.0" tree-sitter = "4.3.1" editor = "0.23.4-ce8de8e-SNAPSHOT" glide = "4.16.0" -androidx-vectordrawable = "1.1.0" +androidx-vectordrawable = "1.2.0" androidx-navigation = "2.7.7" ksp = "1.9.22-1.0.17" antlr4 = "4.13.1" @@ -84,12 +84,12 @@ androidx-preference = { module = "androidx.preference:preference", version = "1. androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.3.2" } androidx-vectors = { module = "androidx.vectordrawable:vectordrawable", version.ref = "androidx-vectordrawable" } androidx-animated_vectors = { module = "androidx.vectordrawable:vectordrawable-animated", version.ref = "androidx-vectordrawable" } -androidx-core = { module = "androidx.core:core", version = "1.12.0" } -androidx-core-ktx = { module = "androidx.core:core-ktx", version = "1.12.0" } -androidx-fragment_ktx = { module = "androidx.fragment:fragment-ktx", version = "1.6.2" } +androidx-core = { module = "androidx.core:core", version = "1.13.1" } +androidx-core-ktx = { module = "androidx.core:core-ktx", version = "1.13.1" } +androidx-fragment_ktx = { module = "androidx.fragment:fragment-ktx", version = "1.7.0" } androidx-libDesugaring = { module = "com.android.tools:desugar_jdk_libs", version = "2.0.4" } androidx-splashscreen = { module = "androidx.core:core-splashscreen", version = "1.0.1" } -androidx-transition = { module = "androidx.transition:transition-ktx", version = "1.4.1" } +androidx-transition = { module = "androidx.transition:transition-ktx", version = "1.5.0" } androidx-nav-fragment = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "androidx-navigation" } androidx-nav-ui = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "androidx-navigation" } androidx-tracing = { module = "androidx.tracing:tracing", version = "1.2.0" } diff --git a/preferences/src/main/java/com/itsaky/androidide/preferences/IDEPreferences.kt b/preferences/src/main/java/com/itsaky/androidide/preferences/IDEPreferences.kt index 88a7e5a2f..9b51dd98c 100644 --- a/preferences/src/main/java/com/itsaky/androidide/preferences/IDEPreferences.kt +++ b/preferences/src/main/java/com/itsaky/androidide/preferences/IDEPreferences.kt @@ -25,7 +25,8 @@ import android.os.Parcelable * * @author Akash Yadav */ -object IDEPreferences : BaseIDEPreferences(){ +data object IDEPreferences : BaseIDEPreferences() { + override val children: List = mutableListOf() override fun describeContents(): Int = 0 override fun writeToParcel(dest: Parcel, flags: Int) {} diff --git a/resources/src/main/res/values-night/styles.xml b/resources/src/main/res/values-night/styles.xml index 1b88d9f6a..79177bcc9 100755 --- a/resources/src/main/res/values-night/styles.xml +++ b/resources/src/main/res/values-night/styles.xml @@ -20,9 +20,6 @@