zusammenkopiert aus Teraplex und CodeGuard
This commit is contained in:
parent
3d74d80b7a
commit
c634995e41
@ -7,11 +7,11 @@
|
||||
<deviceKey>
|
||||
<Key>
|
||||
<type value="VIRTUAL_DEVICE_PATH" />
|
||||
<value value="C:\Users\Cody\.android\avd\for_Website.avd" />
|
||||
<value value="C:\Users\Cody\.android\avd\Pixel_C_API_33.avd" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</targetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2024-02-23T16:37:40.934381500Z" />
|
||||
<timeTargetWasSelectedWithDropDown value="2024-02-24T17:39:55.956737900Z" />
|
||||
</component>
|
||||
</project>
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
|
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||
|
@ -46,6 +46,7 @@ dependencies {
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
|
||||
implementation 'com.caverock:androidsvg-aar:1.4'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
implementation 'com.jcraft:jsch:0.1.55'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
|
@ -0,0 +1,103 @@
|
||||
package com.example.onetap_ssh;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.onetap_ssh.ui.tabs.TabsFragment;
|
||||
|
||||
public class AddButtonDialogSingle extends DialogFragment {
|
||||
private EditText editText_command, editText_name, editText_button_name;
|
||||
private AddButtonDialogListenerSingle listener;
|
||||
private TabsFragment frag;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param savedInstanceState
|
||||
* @return
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = requireActivity().getLayoutInflater();
|
||||
View view = inflater.inflate(R.layout.addbuttondialog_single, null);
|
||||
|
||||
editText_command = view.findViewById(R.id.dialogSingle_editText_command);
|
||||
editText_name = view.findViewById(R.id.dialogheadline_editText_name);
|
||||
editText_button_name = view.findViewById(R.id.dialogSingle_editText_buttonName);
|
||||
|
||||
|
||||
builder.setView(view)
|
||||
.setTitle("SINGLE BUTTON")
|
||||
.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.add, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
String command = editText_command.getText().toString();
|
||||
String name = editText_name.getText().toString();
|
||||
String button = editText_button_name.getText().toString();
|
||||
if(command.isEmpty()||button.isEmpty()||name.isEmpty()){
|
||||
|
||||
AlertDialog mDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(getString(R.string.invalid))
|
||||
.setMessage(getString(R.string.inputfields_cant_be_empty))
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(android.R.string.yes, null )
|
||||
.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
return;
|
||||
}
|
||||
listener.applyTextsSingle(name,command,button);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
AlertDialog mDialog = builder.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
return mDialog;
|
||||
}
|
||||
|
||||
public void setFragment(TabsFragment frag)
|
||||
{
|
||||
this.frag = frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NotNull Context context) {
|
||||
super.onAttach(context);
|
||||
|
||||
try {
|
||||
listener = (AddButtonDialogListenerSingle) frag;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(frag.toString() +
|
||||
"must implement ExampleDialogListener");
|
||||
}
|
||||
}
|
||||
|
||||
public interface AddButtonDialogListenerSingle {
|
||||
void applyTextsSingle(String name, String command, String button);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package com.example.onetap_ssh;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.onetap_ssh.ui.tabs.TabsFragment;
|
||||
|
||||
|
||||
public class AddButtonsDialogDouble extends DialogFragment {
|
||||
private AddButtonsDialogListenerDouble listener;
|
||||
|
||||
private EditText editText_name, editText_command1, editText_button1, editText_command2, editText_button2;
|
||||
private TabsFragment frag;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
|
||||
LayoutInflater inflater = requireActivity().getLayoutInflater();
|
||||
View view = inflater.inflate(R.layout.addbuttonsdialog_double, null);
|
||||
|
||||
builder.setView(view)
|
||||
.setTitle("ON/OFF BUTTON")
|
||||
.setNegativeButton(getString(R.string.cancel), null)
|
||||
.setPositiveButton(R.string.add, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
String command1 = editText_command1.getText().toString();
|
||||
String command2 = editText_command2.getText().toString();
|
||||
String name = editText_name.getText().toString();
|
||||
String button1 = editText_button1.getText().toString();
|
||||
String button2 = editText_button2.getText().toString();
|
||||
if(command1.isEmpty()||command2.isEmpty()||name.isEmpty()||button1.isEmpty()||button2.isEmpty()){
|
||||
|
||||
AlertDialog mDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(getString(R.string.invalid))
|
||||
.setMessage(getString(R.string.inputfields_cant_be_empty))
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(android.R.string.yes, null )
|
||||
.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
return;
|
||||
}
|
||||
listener.applyTextsDouble(name,command1,command2,button1,button2);
|
||||
}
|
||||
});
|
||||
|
||||
editText_name = view.findViewById(R.id.dialogDouble_editText_name);
|
||||
editText_command1 = view.findViewById(R.id.dialogDouble_editText_command1);
|
||||
editText_command2 = view.findViewById(R.id.dialogDouble_editText_command2);
|
||||
editText_button1 = view.findViewById(R.id.dialogDouble_editText_button1);
|
||||
editText_button2 = view.findViewById(R.id.dialogDouble_editText_button2);
|
||||
|
||||
AlertDialog mDialog = builder.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
return mDialog;
|
||||
}
|
||||
|
||||
public void setFragment(TabsFragment frag) {
|
||||
this.frag = frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NotNull Context context) {
|
||||
super.onAttach(context);
|
||||
|
||||
try {
|
||||
listener = (AddButtonsDialogListenerDouble) frag;
|
||||
} catch (ClassCastException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public interface AddButtonsDialogListenerDouble {
|
||||
void applyTextsDouble(String name, String command1, String command2, String button1, String button2);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,92 @@
|
||||
package com.example.onetap_ssh;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.onetap_ssh.ui.tabs.TabsFragment;
|
||||
|
||||
public class AddHeadlineDialog extends DialogFragment {
|
||||
private AddHeadlineDialogListener listener;
|
||||
|
||||
private EditText editText_name;
|
||||
private TabsFragment frag;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param savedInstanceState
|
||||
* @return
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = requireActivity().getLayoutInflater();
|
||||
View view = inflater.inflate(R.layout.addheadlinedialog, null);
|
||||
|
||||
editText_name = view.findViewById(R.id.dialogheadline_editText_name);
|
||||
|
||||
builder.setView(view)
|
||||
.setTitle(R.string.heading)
|
||||
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
|
||||
|
||||
})
|
||||
.setPositiveButton(R.string.add, (dialogInterface, i) -> {
|
||||
String headline = editText_name.getText().toString();
|
||||
if(headline.isEmpty()){
|
||||
|
||||
AlertDialog mDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(getString(R.string.invalid))
|
||||
.setMessage(getString(R.string.inputfields_cant_be_empty))
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(android.R.string.yes, null )
|
||||
.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
return;
|
||||
}
|
||||
listener.applyTextsHeadline(headline);
|
||||
});
|
||||
|
||||
|
||||
AlertDialog mDialog = builder.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
return mDialog;
|
||||
}
|
||||
|
||||
public void setFragment(TabsFragment frag)
|
||||
{
|
||||
this.frag = frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NotNull Context context) {
|
||||
super.onAttach(context);
|
||||
|
||||
try {
|
||||
listener = (AddHeadlineDialogListener) frag;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(frag.toString() +
|
||||
"must implement ExampleDialogListener");
|
||||
}
|
||||
}
|
||||
|
||||
public interface AddHeadlineDialogListener {
|
||||
void applyTextsHeadline(String headline);
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,13 @@
|
||||
package com.example.onetap_ssh;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -13,6 +17,8 @@ import com.example.onetap_ssh.util.SettingsUtil;
|
||||
|
||||
public class IntroActivity extends BaseActivity {
|
||||
|
||||
public static boolean show_logoanimation = false;
|
||||
|
||||
private ActivityIntroBinding binding;
|
||||
|
||||
private MediaPlayer mMediaPlayer;
|
||||
@ -46,6 +52,26 @@ public class IntroActivity extends BaseActivity {
|
||||
});
|
||||
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
SharedPreferences p = getSharedPreferences("appsettings", Activity.MODE_PRIVATE);
|
||||
show_logoanimation = p.getBoolean("Logoanimation", true);
|
||||
if (show_logoanimation) {
|
||||
setContentView(R.layout.activity_intro);
|
||||
final Handler handler = new Handler(Looper.getMainLooper());
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//Do something after 4000ms
|
||||
Intent m = new Intent(getApplicationContext(), MainActivity.class);
|
||||
m.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
startActivity(m);
|
||||
}
|
||||
}, 4000);
|
||||
} else {
|
||||
Intent m = new Intent(getApplicationContext(), MainActivity.class);
|
||||
m.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
startActivity(m);
|
||||
}
|
||||
}
|
||||
|
||||
public void openMainActivity() {
|
||||
|
@ -1,12 +1,24 @@
|
||||
package com.example.onetap_ssh;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Bundle;
|
||||
import android.os.Vibrator;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.Menu;
|
||||
import android.view.LayoutInflater;
|
||||
|
||||
import com.example.onetap_ssh.fragment.AboutFragment;
|
||||
import com.example.onetap_ssh.fragment.SettingsFragment;
|
||||
import com.example.onetap_ssh.ui.tabs.TabsFragment;
|
||||
import com.example.onetap_ssh.util.DialogUtil;
|
||||
import com.example.onetap_ssh.util.NavigationUtil;
|
||||
import com.example.onetap_ssh.util.SettingsUtil;
|
||||
@ -15,16 +27,27 @@ import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.core.view.GravityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.navigation.ui.AppBarConfiguration;
|
||||
import androidx.navigation.ui.NavigationUI;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
|
||||
import com.example.onetap_ssh.databinding.ActivityMainBinding;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
@ -33,9 +56,13 @@ public class MainActivity extends AppCompatActivity {
|
||||
private ActivityMainBinding binding;
|
||||
|
||||
private boolean fullyLaunched;
|
||||
|
||||
public static boolean button_vibration = false;
|
||||
private boolean lockOnStop = true;
|
||||
|
||||
public static boolean editmode = false;
|
||||
int lastID = 6969;
|
||||
Map<String, MenuItem> tabitems = new HashMap<>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -51,7 +78,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
.setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
DrawerLayout drawer = binding.appBackground;
|
||||
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
||||
NavigationView navigationView = binding.navView;
|
||||
// Passing each menu ID as a set of Ids because each
|
||||
// menu should be considered as top level destinations.
|
||||
@ -59,13 +86,127 @@ public class MainActivity extends AppCompatActivity {
|
||||
R.id.nav_home, R.id.nav_settings, R.id.nav_about)
|
||||
.setOpenableLayout(drawer)
|
||||
.build();
|
||||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
|
||||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
|
||||
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
|
||||
NavigationUI.setupWithNavController(navigationView, navController);
|
||||
|
||||
SharedPreferences p = getSharedPreferences("appsettings", Activity.MODE_PRIVATE);
|
||||
button_vibration = p.getBoolean("Vibration", false );
|
||||
IntroActivity.show_logoanimation = p.getBoolean("Logoanimation", true );
|
||||
launchApp();
|
||||
|
||||
navigationView.getMenu().getItem(4).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (button_vibration) {
|
||||
Vibrator vr = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
SharedPreferences p = getSharedPreferences("appsettings", MODE_PRIVATE);
|
||||
String tabsString = p.getString("tabs", null);
|
||||
List<String> tabs = new ArrayList<String>();
|
||||
if (tabsString != null) {
|
||||
try {
|
||||
JSONArray tabsArray = new JSONArray(tabsString);
|
||||
for (int i = 0; i < tabsArray.length(); i++) {
|
||||
tabs.add(tabsArray.getString(i));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
List<String> selectedTabs = new ArrayList<>();
|
||||
String[] tabsarray = tabs.toArray(new String[0]);
|
||||
AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);
|
||||
mBuilder.setTitle(R.string.menu_remove);
|
||||
|
||||
mBuilder.setMultiChoiceItems(tabsarray, null, new DialogInterface.OnMultiChoiceClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i, boolean isChecked) {
|
||||
String selectedItem = tabsarray[i];
|
||||
if (isChecked) {
|
||||
selectedTabs.add(selectedItem);
|
||||
} else {
|
||||
selectedTabs.remove(selectedItem);
|
||||
}
|
||||
}
|
||||
});
|
||||
mBuilder.setPositiveButton(getString(R.string.remove), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (button_vibration) {
|
||||
Vibrator vr = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
tabs.removeAll(selectedTabs);
|
||||
SharedPreferences.Editor editor = p.edit();
|
||||
editor.putString("tabs", new JSONArray(tabs).toString());
|
||||
for (String tab : selectedTabs) {
|
||||
editor.remove("listItems." + tab);
|
||||
editor.apply();
|
||||
navigationView.getMenu().removeItem(tabitems.get(tab).getItemId());
|
||||
tabitems.remove(tab);
|
||||
dialogInterface.dismiss();
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
mBuilder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (button_vibration) {
|
||||
Vibrator vr = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
}
|
||||
});
|
||||
AlertDialog mDialog = mBuilder.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
String tabsString = p.getString("tabs", null);
|
||||
List<String> tabs = new ArrayList<>();
|
||||
if (tabsString != null) {
|
||||
try {
|
||||
JSONArray tabsArray = new JSONArray(tabsString);
|
||||
for (int i = 0; i < tabsArray.length(); i++) {
|
||||
tabs.add(tabsArray.getString(i));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
for (String tab : tabs) {
|
||||
MenuItem item = navigationView.getMenu().add(R.id.dynamicgroup, lastID++, 3, tab);
|
||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (button_vibration) {
|
||||
Vibrator vr = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
DrawerLayout mDrawerLayout;
|
||||
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
mDrawerLayout.closeDrawer(GravityCompat.START);
|
||||
Objects.requireNonNull(getSupportActionBar()).setTitle(tab);
|
||||
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
|
||||
NavHostFragment nhf = (NavHostFragment) currentFragment;
|
||||
assert nhf != null;
|
||||
nhf.getChildFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new TabsFragment(tab)).commit();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
tabitems.put(tab, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
@ -75,7 +216,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public boolean onSupportNavigateUp() {
|
||||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
|
||||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
|
||||
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|
||||
|| super.onSupportNavigateUp();
|
||||
}
|
||||
@ -119,4 +260,37 @@ public class MainActivity extends AppCompatActivity {
|
||||
Fragment fragment = NavigationUtil.getCurrentFragment(this);
|
||||
|
||||
}
|
||||
public static Bitmap scaleCenterCrop(Bitmap source, int newHeight,
|
||||
int newWidth) {
|
||||
int sourceWidth = source.getWidth();
|
||||
int sourceHeight = source.getHeight();
|
||||
|
||||
float xScale = (float) newWidth / sourceWidth;
|
||||
float yScale = (float) newHeight / sourceHeight;
|
||||
float scale = Math.max(xScale, yScale);
|
||||
|
||||
// Now get the size of the source bitmap when scaled
|
||||
float scaledWidth = scale * sourceWidth;
|
||||
float scaledHeight = scale * sourceHeight;
|
||||
|
||||
float left = (newWidth - scaledWidth) / 2;
|
||||
float top = (newHeight - scaledHeight) / 2;
|
||||
|
||||
RectF targetRect = new RectF(left, top, left + scaledWidth, top
|
||||
+ scaledHeight);//from ww w .j a va 2s. co m
|
||||
|
||||
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight,
|
||||
source.getConfig());
|
||||
Canvas canvas = new Canvas(dest);
|
||||
canvas.drawBitmap(source, null, targetRect, null);
|
||||
|
||||
return dest;
|
||||
}
|
||||
public static int getScreenWidth() {
|
||||
return Resources.getSystem().getDisplayMetrics().widthPixels;
|
||||
}
|
||||
|
||||
public static int getScreenHeight() {
|
||||
return Resources.getSystem().getDisplayMetrics().heightPixels;
|
||||
}
|
||||
}
|
58
app/src/main/java/com/example/onetap_ssh/SSH_connection.java
Normal file
58
app/src/main/java/com/example/onetap_ssh/SSH_connection.java
Normal file
@ -0,0 +1,58 @@
|
||||
package com.example.onetap_ssh;
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.ChannelExec;
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.Session;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class SSH_connection {
|
||||
|
||||
public static void executeRemoteCommand(String ip, String user, String password, String command) throws Exception {
|
||||
new Thread(() -> {
|
||||
String command1 = command;
|
||||
try {
|
||||
|
||||
java.util.Properties config = new java.util.Properties();
|
||||
config.put("StrictHostKeyChecking", "no");
|
||||
JSch jsch = new JSch();
|
||||
Session session = jsch.getSession(user, ip, 22);
|
||||
session.setPassword(password);
|
||||
session.setConfig(config);
|
||||
session.connect();
|
||||
System.out.println("Connected");
|
||||
|
||||
Channel channel = session.openChannel("exec");
|
||||
((ChannelExec) channel).setCommand(command1);
|
||||
channel.setInputStream(null);
|
||||
((ChannelExec) channel).setErrStream(System.err);
|
||||
|
||||
InputStream in = channel.getInputStream();
|
||||
channel.connect();
|
||||
byte[] tmp = new byte[1024];
|
||||
while (true) {
|
||||
while (in.available() > 0) {
|
||||
int i = in.read(tmp, 0, 1024);
|
||||
if (i < 0) break;
|
||||
System.out.print(new String(tmp, 0, i));
|
||||
}
|
||||
if (channel.isClosed()) {
|
||||
System.out.println("exit-status: " + channel.getExitStatus());
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
channel.disconnect();
|
||||
session.disconnect();
|
||||
System.out.println("DONE");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +1,372 @@
|
||||
package com.example.onetap_ssh.ui.home;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Vibrator;
|
||||
import android.text.method.HideReturnsTransformationMethod;
|
||||
import android.text.method.PasswordTransformationMethod;
|
||||
import android.util.Base64;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.example.onetap_ssh.databinding.FragmentHomeBinding;
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.Session;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.onetap_ssh.MainActivity;
|
||||
import com.example.onetap_ssh.R;
|
||||
import com.example.onetap_ssh.SSH_connection;
|
||||
import com.example.onetap_ssh.ui.terminal.Terminal;
|
||||
|
||||
public class HomeFragment extends Fragment {
|
||||
|
||||
private FragmentHomeBinding binding;
|
||||
public static String user, password, ip;
|
||||
|
||||
public static EditText ipInput;
|
||||
public static EditText userInput;
|
||||
public static EditText passwordInput;
|
||||
boolean isPasswordVisible = false;
|
||||
Button reboot_Button;
|
||||
Button shutdown_Button;
|
||||
Button loginButton;
|
||||
Button logoutButton;
|
||||
ImageView togglepassword;
|
||||
ImageView backgroundoverlay_bottom;
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
HomeViewModel homeViewModel =
|
||||
new ViewModelProvider(this).get(HomeViewModel.class);
|
||||
SharedPreferences prefs = requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE);
|
||||
user = prefs.getString("user", null);
|
||||
password = prefs.getString("password", null);
|
||||
ip = prefs.getString("ip", null);
|
||||
|
||||
binding = FragmentHomeBinding.inflate(inflater, container, false);
|
||||
View root = binding.getRoot();
|
||||
View root = inflater.inflate(R.layout.fragment_home, container, false);
|
||||
SharedPreferences p = requireContext().getSharedPreferences("appsettings", Activity.MODE_PRIVATE);
|
||||
String Background = p.getString("Background", null);
|
||||
if (Background != null) {
|
||||
ImageView I = root.findViewById(R.id.Background);
|
||||
byte[] BA = Base64.decode(Background, Base64.DEFAULT);
|
||||
I.setImageDrawable(new BitmapDrawable(getResources(), MainActivity.scaleCenterCrop(BitmapFactory.decodeByteArray(BA, 0, BA.length), MainActivity.getScreenHeight(), MainActivity.getScreenWidth())));
|
||||
I.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
}
|
||||
final TextView textView = root.findViewById(R.id.text_home);
|
||||
final TextView login_data = root.findViewById(R.id.login_data);
|
||||
if (user == null || ip == null) {
|
||||
login_data.setText(R.string.please_login);
|
||||
} else {
|
||||
login_data.setText(getString(R.string.sie_sind_als_angemeldet).replace("{IP}", ip).replace("{USERNAME}", user));
|
||||
}
|
||||
userInput = (EditText) root.findViewById(R.id.loginuserInput);
|
||||
passwordInput = (EditText) root.findViewById(R.id.loginpasswordInput);
|
||||
ipInput = (EditText) root.findViewById(R.id.ipInput);
|
||||
loginButton = (Button) root.findViewById(R.id.loginButton);
|
||||
reboot_Button = (Button) root.findViewById(R.id.reboot);
|
||||
shutdown_Button = (Button) root.findViewById(R.id.shutdown);
|
||||
togglepassword = (ImageView) root.findViewById(R.id.togglepassword);
|
||||
SharedPreferences t = requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE);
|
||||
if (user == null || ip == null) {
|
||||
loginButton.setVisibility(View.VISIBLE);
|
||||
togglepassword.setVisibility(View.VISIBLE);
|
||||
reboot_Button.setVisibility(View.GONE);
|
||||
shutdown_Button.setVisibility(View.GONE);
|
||||
} else {
|
||||
loginButton.setVisibility(View.INVISIBLE);
|
||||
togglepassword.setVisibility(View.INVISIBLE);
|
||||
ipInput.setVisibility(View.GONE);
|
||||
userInput.setVisibility(View.GONE);
|
||||
passwordInput.setVisibility(View.GONE);
|
||||
reboot_Button.setVisibility(View.VISIBLE);
|
||||
shutdown_Button.setVisibility(View.VISIBLE);
|
||||
}
|
||||
loginButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
if (userInput.getText().toString().trim().length() == 0 || ipInput.getText().toString().trim().length() == 0 || passwordInput.getText().toString().trim().length() == 0) {
|
||||
|
||||
AlertDialog mDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(getString(R.string.invalid))
|
||||
.setMessage(getString(R.string.inputfields_cant_be_empty))
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
}
|
||||
}).create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
} else {
|
||||
user = userInput.getText().toString();
|
||||
password = passwordInput.getText().toString();
|
||||
ip = ipInput.getText().toString();
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
JSch jsch = new JSch();
|
||||
Session session;
|
||||
session = jsch.getSession(user, ip, 22);
|
||||
session.setPassword(password);
|
||||
session.setUserInfo(new Terminal.MyUserInfo() {
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return super.getPassword();
|
||||
}
|
||||
});
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
System.out.println("CONNECT");
|
||||
session.connect(30000);
|
||||
Channel channel = session.openChannel("shell");
|
||||
channel.connect(3 * 1000);
|
||||
session.disconnect();
|
||||
System.out.println("DISCONNECT");
|
||||
requireActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(getContext(), R.string.connecting, Toast.LENGTH_SHORT).show();
|
||||
SharedPreferences p = requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE);
|
||||
p.edit().putString("user", user).putString("password", password).putString("ip", ip).apply();
|
||||
if (user == null || ip == null) {
|
||||
login_data.setText("");
|
||||
reboot_Button.setVisibility(View.GONE);
|
||||
shutdown_Button.setVisibility(View.GONE);
|
||||
backgroundoverlay_bottom.setVisibility(View.INVISIBLE);
|
||||
|
||||
} else {
|
||||
login_data.setText(getString(R.string.sie_sind_als_angemeldet).replace("{IP}", ip).replace("{USERNAME}", user));
|
||||
logoutButton.setVisibility(View.VISIBLE);
|
||||
loginButton.setVisibility(View.INVISIBLE);
|
||||
togglepassword.setVisibility(View.INVISIBLE);
|
||||
ipInput.setVisibility(View.GONE);
|
||||
userInput.setVisibility(View.GONE);
|
||||
passwordInput.setVisibility(View.GONE);
|
||||
reboot_Button.setVisibility(View.VISIBLE);
|
||||
shutdown_Button.setVisibility(View.VISIBLE);
|
||||
backgroundoverlay_bottom.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
requireActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
e.printStackTrace();
|
||||
AlertDialog mDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(getString(R.string.unable_to_connect))
|
||||
.setMessage(getString(R.string.try_again))
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
}
|
||||
}).create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
logoutButton = (Button) root.findViewById(R.id.logoutButton);
|
||||
if (user == null || ip == null) {
|
||||
logoutButton.setVisibility(View.INVISIBLE);
|
||||
ipInput.setVisibility(View.VISIBLE);
|
||||
userInput.setVisibility(View.VISIBLE);
|
||||
passwordInput.setVisibility(View.VISIBLE);
|
||||
reboot_Button.setVisibility(View.GONE);
|
||||
shutdown_Button.setVisibility(View.GONE);
|
||||
backgroundoverlay_bottom.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
logoutButton.setVisibility(View.VISIBLE);
|
||||
reboot_Button.setVisibility(View.VISIBLE);
|
||||
shutdown_Button.setVisibility(View.VISIBLE);
|
||||
backgroundoverlay_bottom.setVisibility(View.VISIBLE);
|
||||
}
|
||||
logoutButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE).edit().remove("ip").remove("user").remove("password").apply();
|
||||
startActivity(requireActivity().getIntent());
|
||||
requireActivity().finish();
|
||||
}
|
||||
});
|
||||
reboot_Button = (Button) root.findViewById(R.id.reboot);
|
||||
reboot_Button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
|
||||
AlertDialog mDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(getString(R.string.restart_server))
|
||||
.setMessage(getString(R.string.are_you_sure))
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
try {
|
||||
|
||||
Toast.makeText(getContext(), R.string.rebooting, Toast.LENGTH_SHORT).show();
|
||||
SSH_connection.executeRemoteCommand(ip, user, password, "reboot");
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// Continue with delete operation
|
||||
}
|
||||
})
|
||||
|
||||
// A null listener allows the button to dismiss the dialog and take no further action.
|
||||
.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
}
|
||||
}).create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
shutdown_Button = (Button) root.findViewById(R.id.shutdown);
|
||||
shutdown_Button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
|
||||
AlertDialog mDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(getString(R.string.shutdown_server))
|
||||
.setMessage(getString(R.string.are_you_sure))
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
try {
|
||||
|
||||
Toast.makeText(getContext(), R.string.shutting_down, Toast.LENGTH_SHORT).show();
|
||||
SSH_connection.executeRemoteCommand(ip, user, password, "shutdown now");
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// Continue with delete operation
|
||||
}
|
||||
})
|
||||
|
||||
// A null listener allows the button to dismiss the dialog and take no further action.
|
||||
.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
}
|
||||
}).create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (togglepassword.getVisibility() == View.VISIBLE) {
|
||||
togglepassword.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
if (isPasswordVisible) {
|
||||
passwordInput.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
|
||||
isPasswordVisible = false;
|
||||
} else {
|
||||
passwordInput.setTransformationMethod(PasswordTransformationMethod.getInstance());
|
||||
isPasswordVisible = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final TextView textView = binding.textHome;
|
||||
homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
|
||||
return root;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Vibrator;
|
||||
import android.view.View;
|
||||
|
||||
import com.example.onetap_ssh.MainActivity;
|
||||
import com.example.onetap_ssh.SSH_connection;
|
||||
|
||||
public class CommandExecutor implements View.OnClickListener {
|
||||
|
||||
private final String command;
|
||||
public CommandExecutor(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
SharedPreferences prefs = v.getContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE);
|
||||
String user = prefs.getString("user", null);
|
||||
String password = prefs.getString("password", null);
|
||||
String ip = prefs.getString("ip", null);
|
||||
if (user == null||ip == null||password == null){
|
||||
return;
|
||||
}
|
||||
try {
|
||||
SSH_connection.executeRemoteCommand(ip, user, password, command);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
public interface IViewHolder {
|
||||
abstract public String getCommand();
|
||||
|
||||
abstract public View[] getViews();
|
||||
}
|
@ -0,0 +1,396 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.onetap_ssh.AddButtonsDialogDouble;
|
||||
import com.example.onetap_ssh.MainActivity;
|
||||
import com.example.onetap_ssh.R;
|
||||
|
||||
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ListItemViewHolder> {
|
||||
|
||||
private AddButtonsDialogDouble.AddButtonsDialogListenerDouble listener;
|
||||
private EditText editText_name, editText_command, editText_command1, editText_button1, editText_command2, editText_button2, editText_button_name;
|
||||
private TabsFragment frag;
|
||||
|
||||
public static final int
|
||||
SINGLEBUTTON = 0,
|
||||
DOUBLEBUTTON = 1,
|
||||
HEADLINE = 2,
|
||||
SPACE = 3;
|
||||
|
||||
private final LayoutInflater inflater;
|
||||
private final String tabname;
|
||||
private final ArrayList<ListItem> objects;
|
||||
private final Context context;
|
||||
|
||||
public ListAdapter(Context context, ArrayList<ListItem> objects, String tabname) {
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
this.tabname = tabname;
|
||||
this.objects = objects;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@NotNull
|
||||
@Override
|
||||
public ListItemViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
|
||||
return new ListItemViewHolder(createView(viewType, parent));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull @NotNull ListItemViewHolder holder, int position) {
|
||||
bindView(holder.getItemView(), objects.get(position));
|
||||
}
|
||||
|
||||
public int getItemViewType(int position) {
|
||||
return objects.get(position).getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return objects.size();
|
||||
}
|
||||
|
||||
public void add(ListItem item) {
|
||||
objects.add(item);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void remove(ListItem item) {
|
||||
int position = objects.indexOf(item);
|
||||
objects.remove(item);
|
||||
notifyItemRemoved(position);
|
||||
}
|
||||
|
||||
public void remove(int position) {
|
||||
objects.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
}
|
||||
|
||||
public void swap(int idx1, int idx2) {
|
||||
Collections.swap(objects, idx1, idx2);
|
||||
notifyItemMoved(idx1, idx2);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
objects.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public ArrayList<ListItem> getObjects() {
|
||||
return objects;
|
||||
}
|
||||
|
||||
public View createView(int listViewItemType, ViewGroup parent) {
|
||||
switch(listViewItemType) {
|
||||
case SINGLEBUTTON:
|
||||
{
|
||||
return inflater.inflate(R.layout.singlebutton, parent, false);
|
||||
}
|
||||
case DOUBLEBUTTON:
|
||||
{
|
||||
return inflater.inflate(R.layout.doublebutton, parent, false);
|
||||
}
|
||||
case SPACE:
|
||||
{
|
||||
return inflater.inflate(R.layout.space, parent, false);
|
||||
}
|
||||
case HEADLINE:
|
||||
{
|
||||
return inflater.inflate(R.layout.headline, parent, false);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void bindView(View view, ListItem item) {
|
||||
String[] strings = item.getStrings();
|
||||
ImageView Remove = view.findViewById(R.id.image_remove);
|
||||
ImageView Edit = view.findViewById(R.id.image_edit);
|
||||
|
||||
|
||||
if (MainActivity.editmode) {
|
||||
Remove.setVisibility(View.VISIBLE);
|
||||
Edit.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
Remove.setVisibility(View.GONE);
|
||||
Edit.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
Remove.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
remove(item);
|
||||
try {
|
||||
TabsFragment.save(tabname, context, ListAdapter.this);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
Edit.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switch (item.getType()) {
|
||||
case SINGLEBUTTON: {
|
||||
AlertDialog.Builder mBuilder = new AlertDialog.Builder(v.getContext());
|
||||
|
||||
View view = inflater.inflate(R.layout.addbuttondialog_single, null);
|
||||
|
||||
editText_command = view.findViewById(R.id.dialogSingle_editText_command);
|
||||
editText_command.setText(strings[1]);
|
||||
editText_name = view.findViewById(R.id.dialogheadline_editText_name);
|
||||
editText_name.setText(strings[0]);
|
||||
editText_button_name = view.findViewById(R.id.dialogSingle_editText_buttonName);
|
||||
editText_button_name.setText(strings[2]);
|
||||
|
||||
|
||||
mBuilder.setView(view)
|
||||
.setTitle("SINGLE BUTTON")
|
||||
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.add, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
String command = editText_command.getText().toString();
|
||||
String name = editText_name.getText().toString();
|
||||
String button = editText_button_name.getText().toString();
|
||||
if(command.isEmpty()||button.isEmpty()||name.isEmpty()){
|
||||
|
||||
AlertDialog mDialog = new AlertDialog.Builder(v.getContext())
|
||||
.setTitle(R.string.invalid)
|
||||
.setMessage(R.string.inputfields_cant_be_empty)
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(android.R.string.yes, null )
|
||||
.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
|
||||
return;
|
||||
}
|
||||
ListItemSingle item_tmp = (ListItemSingle) item;
|
||||
item_tmp.setButtonName(button);
|
||||
item_tmp.setCommand(command);
|
||||
item_tmp.setName(name);
|
||||
notifyDataSetChanged();
|
||||
try {
|
||||
TabsFragment.save(tabname, context, ListAdapter.this);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
AlertDialog mDialog = mBuilder.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
break;
|
||||
}
|
||||
case DOUBLEBUTTON: {
|
||||
|
||||
AlertDialog.Builder mBuilder = new AlertDialog.Builder(v.getContext());
|
||||
|
||||
|
||||
View view = inflater.inflate(R.layout.addbuttonsdialog_double, null);
|
||||
|
||||
mBuilder.setView(view)
|
||||
.setTitle("ON/OFF BUTTON")
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.add, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
String command1 = editText_command1.getText().toString();
|
||||
String command2 = editText_command2.getText().toString();
|
||||
String name = editText_name.getText().toString();
|
||||
String button1 = editText_button1.getText().toString();
|
||||
String button2 = editText_button2.getText().toString();
|
||||
if (command1.isEmpty() || command2.isEmpty() || name.isEmpty() || button1.isEmpty() || button2.isEmpty()) {
|
||||
|
||||
AlertDialog mDialog = new AlertDialog.Builder(v.getContext())
|
||||
.setTitle(R.string.invalid)
|
||||
.setMessage(R.string.inputfields_cant_be_empty)
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(android.R.string.yes, null)
|
||||
.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
|
||||
return;
|
||||
}
|
||||
ListItemDouble item_tmp = (ListItemDouble) item;
|
||||
item_tmp.setButton1(button1);
|
||||
item_tmp.setButton2(button2);
|
||||
item_tmp.setCommand1(command1);
|
||||
item_tmp.setCommand2(command2);
|
||||
item_tmp.setName(name);
|
||||
notifyDataSetChanged();
|
||||
try {
|
||||
TabsFragment.save(tabname, context, ListAdapter.this);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
editText_name = view.findViewById(R.id.dialogDouble_editText_name);
|
||||
editText_name.setText(strings[0]);
|
||||
editText_command1 = view.findViewById(R.id.dialogDouble_editText_command1);
|
||||
editText_command1.setText(strings[1]);
|
||||
editText_command2 = view.findViewById(R.id.dialogDouble_editText_command2);
|
||||
editText_command2.setText(strings[2]);
|
||||
editText_button1 = view.findViewById(R.id.dialogDouble_editText_button1);
|
||||
editText_button1.setText(strings[3]);
|
||||
editText_button2 = view.findViewById(R.id.dialogDouble_editText_button2);
|
||||
editText_button2.setText(strings[4]);
|
||||
|
||||
AlertDialog mDialog = mBuilder.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
break;
|
||||
}
|
||||
case HEADLINE: {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
|
||||
|
||||
View view = inflater.inflate(R.layout.addheadlinedialog, null);
|
||||
|
||||
editText_name = view.findViewById(R.id.dialogheadline_editText_name);
|
||||
editText_name.setText(strings[0]);
|
||||
|
||||
|
||||
builder.setView(view)
|
||||
.setTitle(R.string.heading)
|
||||
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
|
||||
|
||||
})
|
||||
.setPositiveButton(R.string.add, (dialogInterface, i) -> {
|
||||
String headline = editText_name.getText().toString();
|
||||
if(headline.isEmpty()){
|
||||
|
||||
AlertDialog mDialog = new AlertDialog.Builder(v.getContext())
|
||||
.setTitle(R.string.invalid)
|
||||
.setMessage(R.string.inputfields_cant_be_empty)
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(android.R.string.yes, null )
|
||||
.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
return;
|
||||
}
|
||||
ListItemHeadline item_tmp = (ListItemHeadline) item;
|
||||
item_tmp.setName(headline);
|
||||
notifyDataSetChanged();
|
||||
try {
|
||||
TabsFragment.save(tabname, context, ListAdapter.this);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
AlertDialog mDialog = builder.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}});
|
||||
switch(item.getType()) {
|
||||
case SINGLEBUTTON:
|
||||
{
|
||||
Button bRun = view.findViewById(R.id.singleButton_button);
|
||||
Button text = view.findViewById(R.id.singleButton_text);
|
||||
|
||||
bRun.setText(strings[2]);
|
||||
bRun.setOnClickListener(new CommandExecutor(strings[1]));
|
||||
text.setText(strings[0]);
|
||||
break;
|
||||
}
|
||||
case DOUBLEBUTTON:
|
||||
{
|
||||
Button bLeft = (Button) view.findViewById(R.id.doubleButton_bLeft);
|
||||
Button bRight = (Button) view.findViewById(R.id.doubleButton_bRight);
|
||||
Button text = (Button) view.findViewById(R.id.doubleButton_text);
|
||||
|
||||
bLeft.setText(strings[3]);
|
||||
bRight.setText(strings[4]);
|
||||
bLeft.setOnClickListener(new CommandExecutor(strings[1]));
|
||||
bRight.setOnClickListener(new CommandExecutor(strings[2]));
|
||||
text.setText(strings[0]);
|
||||
break;
|
||||
}
|
||||
case SPACE:
|
||||
{
|
||||
// NOP
|
||||
break;
|
||||
}
|
||||
case HEADLINE:
|
||||
{
|
||||
Button text = (Button) view.findViewById(R.id.headline_text);
|
||||
text.setText(strings[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ListItemViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private View itemView;
|
||||
|
||||
public ListItemViewHolder(@NonNull @NotNull View itemView) {
|
||||
super(itemView);
|
||||
this.itemView = itemView;
|
||||
}
|
||||
|
||||
public void setItemView(View itemView) {
|
||||
this.itemView = itemView;
|
||||
}
|
||||
|
||||
public View getItemView() {
|
||||
return itemView;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public abstract class ListItem {
|
||||
private int type;
|
||||
|
||||
public ListItem(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public JSONObject toJson() throws JSONException {
|
||||
JSONObject toJson = new JSONObject();
|
||||
toJson.put("type", type);
|
||||
JSONArray a = new JSONArray();
|
||||
for(String s : getStrings()) {
|
||||
a.put(s);
|
||||
}
|
||||
toJson.put("strings", a);
|
||||
return toJson;
|
||||
}
|
||||
|
||||
|
||||
abstract public String[] getStrings();
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static ListItem fromJson(JSONObject object) throws JSONException {
|
||||
JSONArray Strings = object.getJSONArray("strings");
|
||||
switch (object.getInt("type")){
|
||||
case ListAdapter.SINGLEBUTTON:{
|
||||
return new ListItemSingle(Strings.getString(0), Strings.getString(1), Strings.getString(2));
|
||||
}
|
||||
case ListAdapter.DOUBLEBUTTON:{
|
||||
return new ListItemDouble(Strings.getString(0), Strings.getString(1), Strings.getString(2), Strings.getString(3), Strings.getString(4));
|
||||
}
|
||||
case ListAdapter.HEADLINE:{
|
||||
return new ListItemHeadline(Strings.getString(0));
|
||||
}
|
||||
case ListAdapter.SPACE:{
|
||||
return new ListItemSpace();
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("UNGÜLTIGER OBJEKTTYP");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
public class ListItemDouble extends ListItem{
|
||||
|
||||
private String name, command1, command2,button1, button2;
|
||||
public ListItemDouble( String name, String command1, String command2, String button1, String button2) {
|
||||
super( ListAdapter.DOUBLEBUTTON);
|
||||
this.name = name;
|
||||
this.command1 = command1;
|
||||
this.command2 = command2;
|
||||
this.button1 = button1;
|
||||
this.button2 = button2;
|
||||
}
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
public void setCommand1(String command1)
|
||||
{
|
||||
this.command1 = command1;
|
||||
}
|
||||
public void setCommand2(String command2)
|
||||
{
|
||||
this.command2 = command2;
|
||||
}
|
||||
public void setButton1(String button1)
|
||||
{
|
||||
this.button1 = button1;
|
||||
}
|
||||
public void setButton2(String button2)
|
||||
{
|
||||
this.button2 = button2;
|
||||
}
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
public String getCommand1()
|
||||
{
|
||||
return command1;
|
||||
}
|
||||
public String getCommand2()
|
||||
{
|
||||
return command2;
|
||||
}
|
||||
public String getButton1()
|
||||
{
|
||||
return button1;
|
||||
}
|
||||
public String getButton2()
|
||||
{
|
||||
return button2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getStrings() {
|
||||
String[] s = {name, command1, command2, button1, button2};
|
||||
return s;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
public class ListItemHeadline extends ListItem{
|
||||
|
||||
private String name;
|
||||
public ListItemHeadline(String name) {
|
||||
super( ListAdapter.HEADLINE);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getStrings() {
|
||||
String[] s = {name};
|
||||
return s;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
public class ListItemSingle extends ListItem{
|
||||
String buttonName;
|
||||
String command;
|
||||
String name;
|
||||
|
||||
public ListItemSingle(String name,String command,String buttonName ) {
|
||||
super(ListAdapter.SINGLEBUTTON);
|
||||
this.name = name;
|
||||
this.buttonName = buttonName;
|
||||
this.command = command;
|
||||
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
public void setButtonName(String buttonName)
|
||||
{
|
||||
this.buttonName = buttonName;
|
||||
}
|
||||
public void setCommand(String command)
|
||||
{
|
||||
this.command = command;
|
||||
}
|
||||
@Override
|
||||
public String[] getStrings() {
|
||||
String[] s = {name, command, buttonName};
|
||||
return s;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
public class ListItemSpace extends ListItem {
|
||||
|
||||
public ListItemSpace() {
|
||||
super(ListAdapter.SPACE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String[] getStrings() {
|
||||
String[] s = {};
|
||||
return s;
|
||||
}
|
||||
}
|
@ -0,0 +1,272 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Base64;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.onetap_ssh.AddButtonDialogSingle;
|
||||
import com.example.onetap_ssh.AddButtonsDialogDouble;
|
||||
import com.example.onetap_ssh.AddHeadlineDialog;
|
||||
import com.example.onetap_ssh.MainActivity;
|
||||
import com.example.onetap_ssh.R;
|
||||
|
||||
public class TabsFragment extends Fragment implements AddButtonDialogSingle.AddButtonDialogListenerSingle, AddButtonsDialogDouble.AddButtonsDialogListenerDouble, AddHeadlineDialog.AddHeadlineDialogListener {
|
||||
|
||||
|
||||
String[] commands = {"Hello1", "Hello2", "Hello3", "Hello4", "Hello5"};
|
||||
int[] type = {0, 1, 0, 0, 1};
|
||||
|
||||
RecyclerView listView;
|
||||
ListAdapter listAdapter;
|
||||
FloatingActionButton addfab;
|
||||
|
||||
ArrayList<ListItem> items;
|
||||
|
||||
|
||||
String tabname;
|
||||
|
||||
|
||||
public TabsFragment(String tabname) {
|
||||
this.tabname = tabname;
|
||||
|
||||
}
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
View root = inflater.inflate(R.layout.fragment_tabs, container, false);
|
||||
SharedPreferences p = requireContext().getSharedPreferences("appsettings", Activity.MODE_PRIVATE);
|
||||
String Background = p.getString("Background", null);
|
||||
if (Background != null) {
|
||||
ImageView I = root.findViewById(R.id.Background);
|
||||
byte[] BA = Base64.decode(Background, Base64.DEFAULT);
|
||||
I.setImageDrawable(new BitmapDrawable(getResources(), MainActivity.scaleCenterCrop(BitmapFactory.decodeByteArray(BA, 0, BA.length), MainActivity.getScreenHeight(), MainActivity.getScreenWidth())));
|
||||
I.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
}
|
||||
|
||||
|
||||
listView = root.findViewById(R.id.listView);
|
||||
|
||||
items = new ArrayList<ListItem>();
|
||||
|
||||
|
||||
listAdapter = new ListAdapter(getContext(), items, tabname);
|
||||
listView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
listView.setAdapter(listAdapter);
|
||||
|
||||
ItemTouchHelper h = new ItemTouchHelper(new ItemTouchHelper.Callback() {
|
||||
@Override
|
||||
public int getMovementFlags(@NonNull @NotNull RecyclerView recyclerView, @NonNull @NotNull RecyclerView.ViewHolder viewHolder) {
|
||||
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
|
||||
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
|
||||
return makeMovementFlags(dragFlags, swipeFlags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMove(@NonNull @NotNull RecyclerView recyclerView, @NonNull @NotNull RecyclerView.ViewHolder viewHolder, @NonNull @NotNull RecyclerView.ViewHolder target) {
|
||||
//listAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
|
||||
listAdapter.swap(viewHolder.getAdapterPosition(), target.getAdapterPosition());
|
||||
try {
|
||||
save();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwiped(@NonNull @NotNull RecyclerView.ViewHolder viewHolder, int direction) {
|
||||
listAdapter.remove(viewHolder.getAdapterPosition());
|
||||
try {
|
||||
save();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLongPressDragEnabled() {
|
||||
return MainActivity.editmode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemViewSwipeEnabled() {
|
||||
return MainActivity.editmode;
|
||||
|
||||
}
|
||||
});
|
||||
h.attachToRecyclerView(listView);
|
||||
|
||||
addfab = root.findViewById(R.id.fab);
|
||||
if (MainActivity.editmode) {
|
||||
addfab.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
addfab.setVisibility(View.GONE);
|
||||
}
|
||||
addfab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showChooseElement();
|
||||
}
|
||||
});
|
||||
try {
|
||||
load();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void showChooseElement() {
|
||||
final String[] listItems = {getString(R.string.single_button), getString(R.string.double_button), getString(R.string.heading), getString(R.string.space)};
|
||||
AlertDialog.Builder mBuilder = new AlertDialog.Builder(getActivity());
|
||||
mBuilder.setTitle(getString(R.string.choose_element));
|
||||
mBuilder.setSingleChoiceItems(listItems, -1, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (i == 0) {
|
||||
openDialog1();
|
||||
} else if (i == 1) {
|
||||
openDialog2();
|
||||
} else if (i == 2) {
|
||||
openDialog3();
|
||||
} else if (i == 3) {
|
||||
listAdapter.add(new ListItemSpace());
|
||||
try {
|
||||
save();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dialogInterface.dismiss();
|
||||
}
|
||||
});
|
||||
AlertDialog mDialog = mBuilder.create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
}
|
||||
|
||||
public void openDialog1() {
|
||||
AddButtonDialogSingle addButtonDialogSingle = new AddButtonDialogSingle();
|
||||
addButtonDialogSingle.setFragment(this);
|
||||
addButtonDialogSingle.show(requireActivity().getSupportFragmentManager(), getString(R.string.single_button));
|
||||
|
||||
}
|
||||
|
||||
public void openDialog2() {
|
||||
AddButtonsDialogDouble addButtonsDialogDouble = new AddButtonsDialogDouble();
|
||||
addButtonsDialogDouble.setFragment(this);
|
||||
addButtonsDialogDouble.show(requireActivity().getSupportFragmentManager(), getString(R.string.double_button));
|
||||
}
|
||||
|
||||
public void openDialog3() {
|
||||
AddHeadlineDialog addHeadlineDialog = new AddHeadlineDialog();
|
||||
addHeadlineDialog.setFragment(this);
|
||||
addHeadlineDialog.show(requireActivity().getSupportFragmentManager(), getString(R.string.heading));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTextsSingle(String name, String command, String button) {
|
||||
//items.add(new ListItemSingle(0,name,command,button));
|
||||
listAdapter.add(new ListItemSingle(name, command, button));
|
||||
try {
|
||||
save();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
public static int getScreenWidth() {
|
||||
return Resources.getSystem().getDisplayMetrics().widthPixels;
|
||||
}
|
||||
|
||||
public static int getScreenHeight() {
|
||||
return Resources.getSystem().getDisplayMetrics().heightPixels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTextsDouble(String name, String command1, String command2, String button1, String button2) {
|
||||
listAdapter.add(new ListItemDouble(name, command1, command2, button1, button2));
|
||||
try {
|
||||
save();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTextsHeadline(String headline) {
|
||||
listAdapter.add(new ListItemHeadline(headline));
|
||||
try {
|
||||
save();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void load() throws JSONException {
|
||||
if (MainActivity.editmode) {
|
||||
addfab.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
addfab.setVisibility(View.GONE);
|
||||
}
|
||||
listAdapter.clear();
|
||||
SharedPreferences p = requireContext().getSharedPreferences("appsettings", Activity.MODE_PRIVATE);
|
||||
String listItems = p.getString("listItems." + tabname, "[]");
|
||||
JSONArray listItems2 = new JSONArray(listItems);
|
||||
for (int i = 0; i < listItems2.length(); i++) {
|
||||
JSONObject item = listItems2.getJSONObject(i);
|
||||
listAdapter.add(ListItem.fromJson(item));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void save(String tabname, Context context, ListAdapter listAdapter) throws JSONException {
|
||||
JSONArray listItems2 = new JSONArray();
|
||||
for (ListItem Item : listAdapter.getObjects()) {
|
||||
listItems2.put(Item.toJson());
|
||||
}
|
||||
SharedPreferences.Editor editor = context.getSharedPreferences("appsettings", MODE_PRIVATE).edit();
|
||||
editor.putString("listItems." + tabname, listItems2.toString());
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public void save() throws JSONException {
|
||||
save(tabname, requireContext(), listAdapter);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class ViewHolderDoubleButton implements IViewHolder{
|
||||
String commandL;
|
||||
Button bLeft, bRight;
|
||||
|
||||
@Override
|
||||
public String getCommand() {
|
||||
return commandL;
|
||||
}
|
||||
public Button getbLeft() {
|
||||
return bLeft;
|
||||
}
|
||||
public Button getbRight(){return bRight;}
|
||||
@Override
|
||||
public View[] getViews()
|
||||
{
|
||||
return new View[]{getbLeft(),getbRight()};
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.example.onetap_ssh.ui.tabs;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class ViewHolderSingleButton implements IViewHolder {
|
||||
|
||||
String command;
|
||||
Button bRun;
|
||||
|
||||
@Override
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
public Button getbRun() {
|
||||
return bRun;
|
||||
}
|
||||
@Override
|
||||
public View[] getViews()
|
||||
{
|
||||
return new View[]{getbRun(),};
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package com.example.onetap_ssh.ui.terminal;
|
||||
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/**
|
||||
* This program enables you to connect to sshd server and get the shell prompt.
|
||||
* $ CLASSPATH=.:../build javac Shell.java
|
||||
* $ CLASSPATH=.:../build java Shell
|
||||
* You will be asked username, hostname and passwd.
|
||||
* If everything works fine, you will get the shell prompt. Output may
|
||||
* be ugly because of lacks of terminal-emulation, but you can issue commands.
|
||||
*/
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.Session;
|
||||
import com.jcraft.jsch.UIKeyboardInteractive;
|
||||
import com.jcraft.jsch.UserInfo;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
|
||||
import com.example.onetap_ssh.ui.home.HomeFragment;
|
||||
|
||||
public class Terminal {
|
||||
private Session session;
|
||||
private JSch jsch;
|
||||
private ByteArrayOutputStream Output;
|
||||
private PipedOutputStream Input;
|
||||
|
||||
|
||||
public Terminal() {
|
||||
|
||||
try {
|
||||
JSch jsch = new JSch();
|
||||
session = jsch.getSession(HomeFragment.user, HomeFragment.ip, 22);
|
||||
session.setPassword(HomeFragment.password);
|
||||
|
||||
session.setUserInfo(new MyUserInfo() {
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return super.getPassword();
|
||||
}
|
||||
});
|
||||
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
session.connect(30000);
|
||||
|
||||
Channel channel = session.openChannel("shell");
|
||||
|
||||
|
||||
Input = new PipedOutputStream();
|
||||
|
||||
channel.setInputStream(new PipedInputStream(Input));
|
||||
|
||||
Output = new ByteArrayOutputStream();
|
||||
|
||||
channel.setOutputStream(Output);
|
||||
|
||||
|
||||
channel.connect(3 * 1000);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getTerminalOutput() {
|
||||
return new String(Output.toByteArray()).replaceAll("\u001B\\[[;\\d]*m", "");
|
||||
}
|
||||
|
||||
public void sendTerminalCommand(String terminalcommand) {
|
||||
try {
|
||||
Input.write((terminalcommand + "\n").getBytes());
|
||||
Input.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void closeTerminal() {
|
||||
session.disconnect();
|
||||
}
|
||||
|
||||
|
||||
public static abstract class MyUserInfo
|
||||
implements UserInfo, UIKeyboardInteractive {
|
||||
public String getPassword() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean promptYesNo(String str) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getPassphrase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean promptPassphrase(String message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean promptPassword(String message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void showMessage(String message) {
|
||||
}
|
||||
|
||||
public String[] promptKeyboardInteractive(String destination,
|
||||
String name,
|
||||
String instruction,
|
||||
String[] prompt,
|
||||
boolean[] echo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
package com.example.onetap_ssh.ui.terminal;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Vibrator;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.onetap_ssh.MainActivity;
|
||||
import com.example.onetap_ssh.R;
|
||||
|
||||
public class TerminalFragment extends Fragment {
|
||||
|
||||
public static boolean atBottom = false;
|
||||
|
||||
public static String command;
|
||||
|
||||
Button send_button;
|
||||
EditText terminal_edit_text;
|
||||
TextView terminal_textView;
|
||||
Terminal terminal;
|
||||
ScrollView scrollView;
|
||||
public static String user, password, ip;
|
||||
|
||||
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
View root = inflater.inflate(R.layout.fragment_terminal, container, false);
|
||||
SharedPreferences prefs = requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE);
|
||||
user = prefs.getString("user", null);
|
||||
password = prefs.getString("password", null);
|
||||
ip = prefs.getString("ip", null);
|
||||
if (user == null || ip == null || password == null) {
|
||||
AlertDialog mDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(getString(R.string.unable_to_connect))
|
||||
.setMessage(getString(R.string.please_login))
|
||||
|
||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
||||
.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
}
|
||||
}).create();
|
||||
Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
|
||||
mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
|
||||
mDialog.show();
|
||||
|
||||
} else {
|
||||
scrollView = (ScrollView) root.findViewById((R.id.scrollView));
|
||||
terminal_edit_text = (EditText) root.findViewById(R.id.terminal_edit_text);
|
||||
send_button = (Button) root.findViewById(R.id.send_button);
|
||||
send_button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (MainActivity.button_vibration) {
|
||||
Vibrator vr = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
assert vr != null;
|
||||
vr.vibrate(100);
|
||||
}
|
||||
if (terminal != null) {
|
||||
terminal.sendTerminalCommand(terminal_edit_text.getText().toString());
|
||||
if (atBottom) {
|
||||
final Handler handler = new Handler(Looper.getMainLooper());
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollView.fullScroll(View.FOCUS_DOWN);
|
||||
}
|
||||
|
||||
}, 500);
|
||||
}}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
terminal_textView = (TextView) root.findViewById(R.id.terminal_textView);
|
||||
new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
terminal = new Terminal();
|
||||
} catch (Exception e) {
|
||||
requireActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(getContext(), R.string.unable_to_connect, Toast.LENGTH_SHORT).show();
|
||||
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
requireActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(getContext(), R.string.connected, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
while (terminal != null) {
|
||||
|
||||
if (getActivity() == null) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
requireActivity().runOnUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
atBottom = scrollView.getChildAt(0).getBottom() <= (scrollView.getHeight() + scrollView.getScrollY());
|
||||
terminal_textView.setText(terminal.getTerminalOutput());
|
||||
System.out.println(atBottom);
|
||||
|
||||
terminal_textView.invalidate();
|
||||
scrollView.invalidate();
|
||||
//scrollView.fullScroll(View.FOCUS_DOWN);
|
||||
|
||||
}
|
||||
});
|
||||
Thread.sleep(250);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (terminal != null) {
|
||||
terminal.closeTerminal();
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -40,7 +40,7 @@ public class NavigationUtil {
|
||||
FragmentManager manager = activity.getSupportFragmentManager();
|
||||
manager.beginTransaction()
|
||||
.setReorderingAllowed(true)
|
||||
.add(R.id.nav_host_fragment_content_main, overlay)
|
||||
.add(R.id.nav_host_fragment, overlay)
|
||||
.runOnCommit(() -> updateActivity(activity, overlay))
|
||||
.commit();
|
||||
}
|
||||
@ -70,7 +70,7 @@ public class NavigationUtil {
|
||||
private static void navigate(FragmentManager manager, Fragment fragment, Runnable onCommit) {
|
||||
manager.beginTransaction()
|
||||
.setReorderingAllowed(true)
|
||||
.replace(R.id.nav_host_fragment_content_main, fragment)
|
||||
.replace(R.id.nav_host_fragment, fragment)
|
||||
.runOnCommit(onCommit)
|
||||
.commit();
|
||||
}
|
||||
@ -80,7 +80,7 @@ public class NavigationUtil {
|
||||
}
|
||||
|
||||
public static Fragment getCurrentFragment(FragmentManager manager) {
|
||||
return manager.findFragmentById(R.id.nav_host_fragment_content_main);
|
||||
return manager.findFragmentById(R.id.nav_host_fragment);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class ThemeUtil {
|
||||
if(!SettingsUtil.isThemedBackgroundEnabled(activity)) return;
|
||||
|
||||
int background = getBackground(activity);
|
||||
View v = activity.findViewById(R.id.app_background);
|
||||
View v = activity.findViewById(R.id.drawer_layout);
|
||||
if(v != null) {
|
||||
v.setBackgroundResource(background);
|
||||
}
|
||||
|
29
app/src/main/res/anim/dialog_in.xml
Normal file
29
app/src/main/res/anim/dialog_in.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"
|
||||
android:shareInterpolator="true" >
|
||||
<alpha
|
||||
android:fromAlpha="0.0"
|
||||
android:toAlpha="1.0"
|
||||
android:duration="300"/>
|
||||
<scale
|
||||
android:fromXScale="0.8"
|
||||
android:toXScale="1.0"
|
||||
android:fromYScale="1.0"
|
||||
android:toYScale="1.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"/>
|
||||
<translate
|
||||
android:fromXDelta="0%"
|
||||
android:toXDelta="0%"
|
||||
android:fromYDelta="-10%"
|
||||
android:toYDelta="0%"
|
||||
android:duration="300"/>
|
||||
<rotate
|
||||
android:fromDegrees="10"
|
||||
android:toDegrees="0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"/>
|
||||
</set>
|
29
app/src/main/res/anim/dialog_out.xml
Normal file
29
app/src/main/res/anim/dialog_out.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/anticipate_interpolator"
|
||||
android:shareInterpolator="true" >
|
||||
<alpha
|
||||
android:fromAlpha="1.0"
|
||||
android:toAlpha="0.0"
|
||||
android:duration="300"/>
|
||||
<scale
|
||||
android:fromXScale="1.0"
|
||||
android:toXScale="0.8"
|
||||
android:fromYScale="1.0"
|
||||
android:toYScale="1.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"/>
|
||||
<translate
|
||||
android:fromXDelta="0%"
|
||||
android:toXDelta="0%"
|
||||
android:fromYDelta="0%"
|
||||
android:toYDelta="-10%"
|
||||
android:duration="300"/>
|
||||
<rotate
|
||||
android:fromDegrees="0"
|
||||
android:toDegrees="-10"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"/>
|
||||
</set>
|
16
app/src/main/res/drawable/background_full.xml
Normal file
16
app/src/main/res/drawable/background_full.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<stroke
|
||||
android:width="0dp"
|
||||
android:color="#FFFFFF" />
|
||||
<gradient
|
||||
android:angle="180"
|
||||
android:endColor="?attr/colorPrimary"
|
||||
android:startColor="?attr/colorSecondary" />
|
||||
<corners
|
||||
android:bottomLeftRadius="0dp"
|
||||
android:bottomRightRadius="0dp"
|
||||
android:topLeftRadius="0dp"
|
||||
android:topRightRadius="0dp" />
|
||||
</shape>
|
13
app/src/main/res/drawable/backgroundoverlay.xml
Normal file
13
app/src/main/res/drawable/backgroundoverlay.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<stroke android:width="0dp"
|
||||
android:color="#FFFFFF"/>
|
||||
<solid
|
||||
android:color="?attr/colorBackgroundFloating"
|
||||
android:alpha="0.0"/>
|
||||
<corners
|
||||
android:bottomLeftRadius="20dp"
|
||||
android:bottomRightRadius="20dp"
|
||||
android:topLeftRadius="20dp"
|
||||
android:topRightRadius="20dp" />
|
||||
</shape>
|
39
app/src/main/res/drawable/button_left.xml
Normal file
39
app/src/main/res/drawable/button_left.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<stroke
|
||||
android:width="0dp"
|
||||
android:color="#FFFFFF" />
|
||||
<gradient
|
||||
android:angle="0"
|
||||
android:endColor="?attr/colorPrimary"
|
||||
android:startColor="?attr/colorSecondary" />
|
||||
<corners
|
||||
android:bottomLeftRadius="20dp"
|
||||
android:bottomRightRadius="0dp"
|
||||
android:topLeftRadius="20dp"
|
||||
android:topRightRadius="0dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:bottom="2dp"
|
||||
android:left="0dp"
|
||||
android:right="0dp"
|
||||
android:top="0dp">
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<stroke
|
||||
android:width="0dp"
|
||||
android:color="#FFFFFF" />
|
||||
<gradient
|
||||
android:angle="180"
|
||||
android:endColor="?attr/colorOnBackground"
|
||||
android:startColor="?attr/colorOnBackground" />
|
||||
<corners
|
||||
android:bottomLeftRadius="20dp"
|
||||
android:bottomRightRadius="0dp"
|
||||
android:topLeftRadius="20dp"
|
||||
android:topRightRadius="0dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
39
app/src/main/res/drawable/button_middle.xml
Normal file
39
app/src/main/res/drawable/button_middle.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<stroke
|
||||
android:width="0dp"
|
||||
android:color="#FFFFFF" />
|
||||
<gradient
|
||||
android:angle="180"
|
||||
android:endColor="?attr/colorPrimary"
|
||||
android:startColor="?attr/colorPrimary" />
|
||||
<corners
|
||||
android:bottomLeftRadius="0dp"
|
||||
android:bottomRightRadius="0dp"
|
||||
android:topLeftRadius="0dp"
|
||||
android:topRightRadius="0dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:bottom="2dp"
|
||||
android:left="0dp"
|
||||
android:right="0dp"
|
||||
android:top="0dp">
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<stroke
|
||||
android:width="0dp"
|
||||
android:color="#FFFFFF" />
|
||||
<gradient
|
||||
android:angle="180"
|
||||
android:endColor="?attr/colorOnBackground"
|
||||
android:startColor="?attr/colorOnBackground" />
|
||||
<corners
|
||||
android:bottomLeftRadius="0dp"
|
||||
android:bottomRightRadius="0dp"
|
||||
android:topLeftRadius="0dp"
|
||||
android:topRightRadius="0dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
39
app/src/main/res/drawable/button_right.xml
Normal file
39
app/src/main/res/drawable/button_right.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<stroke
|
||||
android:width="0dp"
|
||||
android:color="#FFFFFF" />
|
||||
<gradient
|
||||
android:angle="180"
|
||||
android:endColor="?attr/colorPrimary"
|
||||
android:startColor="?attr/colorSecondary" />
|
||||
<corners
|
||||
android:bottomLeftRadius="0dp"
|
||||
android:bottomRightRadius="20dp"
|
||||
android:topLeftRadius="0dp"
|
||||
android:topRightRadius="20dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:bottom="2dp"
|
||||
android:left="0dp"
|
||||
android:right="0dp"
|
||||
android:top="0dp">
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<stroke
|
||||
android:width="0dp"
|
||||
android:color="#FFFFFF" />
|
||||
<gradient
|
||||
android:angle="180"
|
||||
android:endColor="?attr/colorOnBackground"
|
||||
android:startColor="?attr/colorOnBackground" />
|
||||
<corners
|
||||
android:bottomLeftRadius="0dp"
|
||||
android:bottomRightRadius="20dp"
|
||||
android:topLeftRadius="0dp"
|
||||
android:topRightRadius="20dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
9
app/src/main/res/drawable/clear_black_24dp.xml
Normal file
9
app/src/main/res/drawable/clear_black_24dp.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12 19,6.41z"
|
||||
android:fillColor="#000000"/>
|
||||
</vector>
|
@ -4,7 +4,8 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#000000">
|
||||
android:background="#000000"
|
||||
android:id="@+id/drawer_layout">
|
||||
|
||||
<VideoView
|
||||
android:id="@+id/videoView"
|
||||
|
@ -5,7 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:id="@+id/app_background"
|
||||
android:id="@+id/drawer_layout"
|
||||
tools:openDrawer="start">
|
||||
|
||||
<include
|
||||
|
31
app/src/main/res/layout/addbuttondialog_single.xml
Normal file
31
app/src/main/res/layout/addbuttondialog_single.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogheadline_editText_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/name"
|
||||
android:inputType="textPersonName" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogSingle_editText_buttonName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/button"
|
||||
android:inputType="textPersonName" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogSingle_editText_command"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/command"
|
||||
android:inputType="textPersonName" />
|
||||
</LinearLayout>
|
47
app/src/main/res/layout/addbuttonsdialog_double.xml
Normal file
47
app/src/main/res/layout/addbuttonsdialog_double.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation = "vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogDouble_editText_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/name"
|
||||
android:inputType="textPersonName" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogDouble_editText_command1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/command1"
|
||||
android:inputType="textPersonName" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogDouble_editText_button1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/button1"
|
||||
android:inputType="textPersonName" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogDouble_editText_command2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/command2"
|
||||
android:inputType="textPersonName" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogDouble_editText_button2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/button2"
|
||||
android:inputType="textPersonName" />
|
||||
</LinearLayout>
|
16
app/src/main/res/layout/addheadlinedialog.xml
Normal file
16
app/src/main/res/layout/addheadlinedialog.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogheadline_editText_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/heading"
|
||||
android:inputType="textPersonName" />
|
||||
|
||||
</LinearLayout>
|
16
app/src/main/res/layout/addtabdialog.xml
Normal file
16
app/src/main/res/layout/addtabdialog.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogtab_editText_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/tabname"
|
||||
android:inputType="textPersonName" />
|
||||
|
||||
</LinearLayout>
|
@ -8,7 +8,7 @@
|
||||
tools:showIn="@layout/app_bar_main">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_host_fragment_content_main"
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
66
app/src/main/res/layout/doublebutton.xml
Normal file
66
app/src/main/res/layout/doublebutton.xml
Normal file
@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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"
|
||||
android:id="@+id/line1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/doubleButton_bLeft"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/button_left"
|
||||
android:text="Button1"
|
||||
app:backgroundTint="@null" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/doubleButton_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/button_middle"
|
||||
android:text="Button1"
|
||||
app:backgroundTint="@null" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/doubleButton_bRight"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/button_right"
|
||||
android:text="Button2"
|
||||
app:backgroundTint="@null" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_edit"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="0"
|
||||
app:srcCompat="@drawable/mode_edit_black_24dp"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="VectorDrawableCompat">
|
||||
|
||||
</ImageView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_remove"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
app:srcCompat="@drawable/clear_black_24dp"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="VectorDrawableCompat">
|
||||
|
||||
</ImageView>
|
||||
|
||||
</LinearLayout>
|
16
app/src/main/res/layout/exportdialog.xml
Normal file
16
app/src/main/res/layout/exportdialog.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialogexport_editText_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/filename"
|
||||
android:inputType="textPersonName" />
|
||||
|
||||
</LinearLayout>
|
31
app/src/main/res/layout/fragment_tabs.xml
Normal file
31
app/src/main/res/layout/fragment_tabs.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/fragment_tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/Background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#80FFFFFF"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/background_red_blue" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="65dp"
|
||||
android:visibility="visible"
|
||||
android:divider="@null"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
android:dividerHeight="0dp"
|
||||
/>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
|
81
app/src/main/res/layout/fragment_terminal.xml
Normal file
81
app/src/main/res/layout/fragment_terminal.xml
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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"
|
||||
android:id="@+id/fragment_terminal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="true"
|
||||
tools:context=".ui.terminal.TerminalFragment">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:scrollbars="horizontal|vertical"
|
||||
app:layout_constraintBottom_toTopOf="@+id/divider2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/terminal_textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="serif-monospace"
|
||||
android:text="TextView"
|
||||
android:textColor="#FFFFFF" />
|
||||
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
</ScrollView>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/background_full"
|
||||
app:layout_constraintBottom_toTopOf="@+id/terminal_edit_text"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/terminal_edit_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:ems="10"
|
||||
android:fontFamily="serif-monospace"
|
||||
android:hint="@string/command"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="text"
|
||||
android:textColor="#FFFFFF"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/send_button"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/send_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/button_right"
|
||||
android:text="@string/send"
|
||||
app:backgroundTint="@null"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
48
app/src/main/res/layout/headline.xml
Normal file
48
app/src/main/res/layout/headline.xml
Normal file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/headline_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/backgroundoverlay"
|
||||
android:insetLeft="25dp"
|
||||
android:insetRight="25dp"
|
||||
android:text="TEXT"
|
||||
app:backgroundTint="@null" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_edit"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="0"
|
||||
android:visibility="visible"
|
||||
app:srcCompat="@drawable/mode_edit_black_24dp"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="VectorDrawableCompat">
|
||||
|
||||
</ImageView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_remove"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:visibility="visible"
|
||||
app:srcCompat="@drawable/clear_black_24dp"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="VectorDrawableCompat">
|
||||
|
||||
</ImageView>
|
||||
</LinearLayout>
|
59
app/src/main/res/layout/singlebutton.xml
Normal file
59
app/src/main/res/layout/singlebutton.xml
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/singleButton_text"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_weight="2"
|
||||
android:background="@drawable/button_middle"
|
||||
android:text="TEXT"
|
||||
app:backgroundTint="@null" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/singleButton_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/button_right"
|
||||
android:text="Button2"
|
||||
app:backgroundTint="@null" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_edit"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="0"
|
||||
android:visibility="visible"
|
||||
app:srcCompat="@drawable/mode_edit_black_24dp"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="VectorDrawableCompat">
|
||||
|
||||
</ImageView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_remove"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="0"
|
||||
android:visibility="visible"
|
||||
app:srcCompat="@drawable/clear_black_24dp"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="VectorDrawableCompat">
|
||||
|
||||
</ImageView>
|
||||
|
||||
</LinearLayout>
|
40
app/src/main/res/layout/space.xml
Normal file
40
app/src/main/res/layout/space.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_edit"
|
||||
android:layout_width="00dp"
|
||||
android:layout_height="00dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="0"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/mode_edit_black_24dp"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="VectorDrawableCompat">
|
||||
|
||||
</ImageView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_remove"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:visibility="visible"
|
||||
app:srcCompat="@drawable/clear_black_24dp"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="VectorDrawableCompat">
|
||||
|
||||
</ImageView>
|
||||
</LinearLayout>
|
@ -19,6 +19,7 @@
|
||||
android:title="@string/menu_terminal" />
|
||||
|
||||
|
||||
|
||||
</group>
|
||||
<group
|
||||
android:id="@+id/Down"
|
||||
|
@ -5,6 +5,17 @@
|
||||
android:id="@+id/mobile_navigation"
|
||||
app:startDestination="@+id/nav_home">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_tabs"
|
||||
android:name="com.example.onetap_ssh.ui.tabs.TabsFragment"
|
||||
android:label="@string/menu_tabs"
|
||||
tools:layout="@layout/fragment_tabs" />
|
||||
<fragment
|
||||
android:id="@+id/nav_terminal"
|
||||
android:name="com.example.onetap_ssh.ui.terminal.TerminalFragment"
|
||||
android:label="@string/menu_terminal"
|
||||
tools:layout="@layout/fragment_terminal" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_home"
|
||||
android:name="com.example.onetap_ssh.ui.home.HomeFragment"
|
||||
|
Binary file not shown.
@ -11,4 +11,8 @@
|
||||
<item name="colorTheme1">@color/color_blue</item>
|
||||
<item name="colorTheme2">@color/color_light_green</item>
|
||||
</style>
|
||||
<style name="DialogAnimation">
|
||||
<item name="android:windowEnterAnimation">@anim/dialog_in</item>
|
||||
<item name="android:windowExitAnimation">@anim/dialog_out</item>
|
||||
</style>
|
||||
</resources>
|
@ -82,4 +82,8 @@
|
||||
<item name="colorTheme1">@color/color_blue</item>
|
||||
<item name="colorTheme2">@color/color_light_green</item>
|
||||
</style>
|
||||
<style name="DialogAnimation">
|
||||
<item name="android:windowEnterAnimation">@anim/dialog_in</item>
|
||||
<item name="android:windowExitAnimation">@anim/dialog_out</item>
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user