Moved UI designer to :uidesigner module

This commit is contained in:
Akash Yadav
2022-11-15 17:58:49 +05:30
parent de46f8b966
commit 7abfaf0700
24 changed files with 314 additions and 112 deletions
+1
View File
@@ -154,6 +154,7 @@ dependencies {
implementation project (':preferences')
implementation project (':resources')
implementation project (':treeview')
implementation project (':uidesigner')
implementation project (':xml-inflater')
implementation fileTree (dir: 'libs', include: ['*.jar'])
+1 -1
View File
@@ -50,7 +50,7 @@
android:configChanges="orientation|screenSize|uiMode"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".UIDesignerActivity"
android:name=".uidesigner.UIDesignerActivity"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".PreferencesActivity"
Binary file not shown.
@@ -26,7 +26,6 @@ import static com.itsaky.androidide.resources.R.color;
import static com.itsaky.androidide.resources.R.drawable;
import static com.itsaky.androidide.resources.R.string;
import static com.itsaky.toaster.ToastUtilsKt.toast;
import static com.itsaky.toaster.ToastUtilsKt.toastInfo;
import android.annotation.SuppressLint;
import android.content.ComponentName;
@@ -110,6 +109,7 @@ import com.itsaky.androidide.projects.builder.BuildService;
import com.itsaky.androidide.services.GradleBuildService;
import com.itsaky.androidide.services.LogReceiver;
import com.itsaky.androidide.shell.ShellServer;
import com.itsaky.androidide.uidesigner.UIDesignerActivity;
import com.itsaky.androidide.utils.DialogUtils;
import com.itsaky.androidide.utils.EditorActivityActions;
import com.itsaky.androidide.utils.ILogger;
@@ -706,8 +706,8 @@ public class EditorActivity extends IDEActivity
}
public void previewLayout() {
toastInfo(R.string.msg_feature_unimplemented);
// startActivity(new Intent(this, UIDesignerActivity.class));
// toastInfo(R.string.msg_feature_unimplemented);
startActivity(new Intent(this, UIDesignerActivity.class));
}
public boolean saveAll(boolean notify) {
@@ -755,8 +755,8 @@ public class EditorActivity extends IDEActivity
frag.save();
final boolean isGradle =
frag.getFile().getName().endsWith(".gradle")
|| frag.getFile().getName().endsWith(".gradle.kts");
frag.getFile().getName().endsWith(".gradle")
|| frag.getFile().getName().endsWith(".gradle.kts");
final boolean isXml = frag.getFile().getName().endsWith(".xml");
if (!result.gradleSaved) {
+14 -88
View File
@@ -1,97 +1,23 @@
/**
* ********************************************************************************** This file is
* part of AndroidIDE.
/*
* 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 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.
* 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 <https:></https:>//www.gnu.org/licenses/>.
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.app
import android.Manifest.permission
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat
import androidx.fragment.app.Fragment
import com.itsaky.androidide.utils.ILogger
abstract class IDEActivity : AppCompatActivity() {
fun loadFragment(fragment: Fragment?, id: Int) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(id, fragment!!)
transaction.commit()
}
abstract class IDEActivity : BaseIDEActivity() {
val app: IDEApplication
get() = application as IDEApplication
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
preSetContentLayout()
setContentView(bindLayout())
if (!isStoragePermissionGranted) {
requestStorage()
return
}
if (isStoragePermissionGranted) {
onStorageAlreadyGranted()
} else {
onStorageDenied()
}
}
val isStoragePermissionGranted: Boolean
get() =
(ContextCompat.checkSelfPermission(this, permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, permission.WRITE_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED)
protected fun requestStorage() {
if (isStoragePermissionGranted) {
onStorageGranted()
return
}
ActivityCompat.requestPermissions(
this,
arrayOf(permission.WRITE_EXTERNAL_STORAGE, permission.READ_EXTERNAL_STORAGE),
REQCODE_STORAGE
)
}
protected open fun onStorageGranted() {}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQCODE_STORAGE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)
onStorageGranted()
else onStorageDenied()
}
}
protected open fun onStorageAlreadyGranted() {}
protected open fun onStorageDenied() {}
protected open fun preSetContentLayout() {}
protected abstract fun bindLayout(): View
companion object {
const val REQCODE_STORAGE = 1009
protected var LOG = ILogger.newInstance("StudioActivity")
}
}
+2 -2
View File
@@ -4,7 +4,7 @@ This release brings various improvements and bug fixes to AndroidIDE.
## Important notes
> _No notes_
> _The UI designer has been TEMPORARILY removed as we are working on integrating it with the new projects API for better and improved layout inflation/preview._
## Additions
- The IDE now creates `.nomedia` file in the `PROJECTS` directory if the file does not already exist. Thanks to @jayx003 (#489).
@@ -14,7 +14,7 @@ This release brings various improvements and bug fixes to AndroidIDE.
- Readded `Clear Gradle cache` preference. Thanks to @deepkrg17 (#587).
## Removals
> _No removals_
- The UI designer.
## Fixes
- Some classes not being shown in completion (#500).
@@ -0,0 +1,111 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
/**
* 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 <https:></https:>//www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.app
import android.Manifest.permission
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.itsaky.androidide.utils.ILogger
abstract class BaseIDEActivity : AppCompatActivity() {
fun loadFragment(fragment: Fragment?, id: Int) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(id, fragment!!)
transaction.commit()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
preSetContentLayout()
setContentView(bindLayout())
if (!isStoragePermissionGranted) {
requestStorage()
return
}
if (isStoragePermissionGranted) {
onStorageAlreadyGranted()
} else {
onStorageDenied()
}
}
val isStoragePermissionGranted: Boolean
get() =
(ContextCompat.checkSelfPermission(this, permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, permission.WRITE_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED)
protected fun requestStorage() {
if (isStoragePermissionGranted) {
onStorageGranted()
return
}
ActivityCompat.requestPermissions(
this,
arrayOf(permission.WRITE_EXTERNAL_STORAGE, permission.READ_EXTERNAL_STORAGE),
REQCODE_STORAGE
)
}
protected open fun onStorageGranted() {}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQCODE_STORAGE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)
onStorageGranted()
else onStorageDenied()
}
}
protected open fun onStorageAlreadyGranted() {}
protected open fun onStorageDenied() {}
protected open fun preSetContentLayout() {}
protected abstract fun bindLayout(): View
companion object {
const val REQCODE_STORAGE = 1009
protected var LOG = ILogger.newInstance("StudioActivity")
}
}
@@ -1,3 +1,20 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
/**
* This file is part of AndroidIDE.
*
+1
View File
@@ -47,3 +47,4 @@ include ':resources'
include ':xml-inflater'
include ':annotation-processors'
include ':annotations'
include ':uidesigner'
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
/build
+50
View File
@@ -0,0 +1,50 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
namespace "com.itsaky.androidide.uidesigner"
compileSdkVersion rootProject.ext.compileSdk
buildToolsVersion rootProject.ext.buildTools
defaultConfig {
minSdkVersion rootProject.ext.minSdk
targetSdkVersion rootProject.ext.targetSdk
}
buildFeatures.viewBinding true
compileOptions {
sourceCompatibility rootProject.ext.javaSourceVersion
targetCompatibility rootProject.ext.javaTargetVersion
}
kotlinOptions {
jvmTarget = "11"
}
buildTypes {
release {
minifyEnabled true
}
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
}
dependencies {
implementation androidx.appcompat
implementation google.material
implementation project(path: ':common')
implementation project(path: ':logger')
implementation project(path: ':xml-inflater')
testImplementation tests.junit
testImplementation tests.google_truth
testImplementation tests.robolectric
}
View File
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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 <https://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>
@@ -15,22 +15,19 @@
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide
package com.itsaky.androidide.uidesigner
import android.os.Bundle
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams
import com.blankj.utilcode.util.SizeUtils
import com.itsaky.androidide.app.IDEActivity
import com.itsaky.androidide.databinding.ActivityUiDesignerBinding
import com.itsaky.androidide.app.BaseIDEActivity
import com.itsaky.androidide.uidesigner.databinding.ActivityUiDesignerBinding
/**
* The UI Designer activity allows the user to design XML layouts with a drag-n-drop interface.
*
* @author Akash Yadav
*/
class UIDesignerActivity : IDEActivity() {
class UIDesignerActivity : BaseIDEActivity() {
private var binding: ActivityUiDesignerBinding? = null
@@ -15,13 +15,14 @@
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.fragments
package com.itsaky.androidide.uidesigner.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.itsaky.androidide.databinding.FragmentUiWidgetsBinding
import com.itsaky.androidide.fragments.BaseFragment
import com.itsaky.androidide.uidesigner.databinding.FragmentUiWidgetsBinding
/**
* A fragment that shows the list of widgets available to use in the UI designer.
@@ -29,20 +30,24 @@ import com.itsaky.androidide.databinding.FragmentUiWidgetsBinding
* @author Akash Yadav
*/
class WidgetsListFragment : BaseFragment() {
private var binding: FragmentUiWidgetsBinding? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
this.binding = FragmentUiWidgetsBinding.inflate(inflater, container, false)
return this.binding!!.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
}
}
@@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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 <https://www.gnu.org/licenses/>.
-->
<com.itsaky.androidide.views.ContentTranslatingDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
@@ -41,7 +58,7 @@
<androidx.fragment.app.FragmentContainerView
android:id="@+id/widgets_fragment_container"
android:name="com.itsaky.androidide.fragments.WidgetsListFragment"
android:name="com.itsaky.androidide.uidesigner.fragments.WidgetsListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/fragment_ui_widgets" />
@@ -0,0 +1,34 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.uidesigner
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}