+ * 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