32 Commits

Author SHA1 Message Date
ac5cb93fd9 Updated dependencies. Migrated to androidx (mostly). Stripping JSONRPC
next.
2018-12-01 14:43:18 +01:00
97b1f37164 updated to latest deps, needs some rework for incoming protobuf implementation 2017-04-14 20:07:30 +02:00
96a0bf9ed4 fixed some merge derps 2017-01-31 16:30:22 +01:00
23035084e8 updated deps and code to a more recent state 2017-01-31 16:15:24 +01:00
5872be4fe7 proper Timber integration
updated some deps
2016-05-17 00:38:30 +02:00
a776411a2e moved the lib to jitpack, awesome 2016-05-15 17:13:19 +02:00
86282e6872 fixed wrong icon used when adding a new profile 2016-05-15 15:19:35 +02:00
6c8e7bbfa0 added null check for stripes #8 2016-05-01 22:28:37 +02:00
1d1d27257c Added missing aar file 2016-05-01 22:04:55 +02:00
9d043c21a3 updated holo-color-picker
removed some debug out
2016-05-01 22:03:22 +02:00
ab2c219dca added badges for profile
fixed icon not showing when just added a profile
suppressed some annoying warnings
2016-05-01 00:58:24 +02:00
79c42216fc hockeyapp integration 2016-04-30 21:35:16 +02:00
a582a5b1bc renamed file to be not enormously long anymore 2016-04-30 21:02:23 +02:00
e1f6ca4f33 fixed int treated as string 2016-04-30 20:56:10 +02:00
c6887e5905 updated some jenkins related stuff 2016-04-30 20:48:36 +02:00
64b2f80848 added wrapper 2016-04-30 20:27:54 +02:00
58980c494e updated libs
added library management
changed some edittext to the right class
2016-04-30 20:17:07 +02:00
239429cb5e Added icons for the new drawer
Added profiles (not fully completed yet, but it works)
Removed some unused icons
2016-03-18 15:39:38 +01:00
9ff32af9f1 Upgraded gradle parts to latest
Switched to another fork of the holo-color-picker
Switched to MaterialDrawer due NavigationView is still very buggy and much more limited
General cleanup
Version bump to 1.0.3
2016-03-17 20:38:16 +01:00
Giovanni Harting
9a3b955d32 updated deps
removed workaround for issue with the navigationHeader
added handling of empty responses
2015-11-14 14:37:08 +01:00
Giovanni Harting
9739116db6 added missing resource files from last commit 2015-10-31 22:32:40 +01:00
Giovanni Harting
2211186d9f more bug fixing
moved rate limiting to another class
navigation header is close to being functional
2015-10-31 22:30:48 +01:00
Giovanni Harting
ce198af0ef updated zipalign to zipAlignEnabled 2015-10-26 23:53:13 +01:00
Giovanni Harting
2991094f2d added zipalign to release and debug 2015-10-26 23:50:57 +01:00
Giovanni Harting
aaea03a5c2 updated dependencies 2015-10-15 22:35:28 +02:00
Giovanni Harting
7bac6a394a moved some stuff around
avoid flicker of stripe when selected in app
2015-10-15 22:33:49 +02:00
Giovanni Harting
ee78ba9b53 removed test button 2015-10-15 13:51:32 +02:00
Giovanni Harting
60f805f15c switched to json-rpc (ref LedD d5f403d5573d13e6b8f3113a1c62a096ea721f19)
fixed duplicate connections were made when adding a daemon
2015-10-11 21:52:39 +02:00
Giovanni Harting
6c321aaa90 reactivating the stripe now sets the colorwheel's current color
increased thickness of saturation and value bars
2015-09-17 17:31:54 +02:00
Giovanni Harting
34776fc225 extracted some more strings, yay
exchanged svbar with separate value and saturation bar
added switch in toolbar to disable (set black) the stripe and ignore all following inputs until reactivated again
2015-09-17 16:16:50 +02:00
Giovanni Harting
9fa55d2994 fixed some bugs
added rate control to the changecolor event (much smoother now)
extraced some more string from the code, more is to come
2015-09-16 15:21:50 +02:00
Giovanni Harting
42ff424622 general post-release cleanup
removed lots of unused strings/resources/drawables
extracted all translatable strings
added new logo
2015-09-16 13:40:04 +02:00
110 changed files with 1461 additions and 1376 deletions

View File

@@ -20,47 +20,52 @@ buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
classpath 'com.github.ben-manes:gradle-versions-plugin:0.11.3'
maven { url "https://jitpack.io" }
}
}
apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.hugo'
apply plugin: 'com.github.ben-manes.versions'
repositories {
maven { url "https://jitpack.io" }
}
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
compileSdkVersion 28
buildToolsVersion '28.0.3'
lintOptions {
abortOnError false
}
defaultConfig {
applicationId "com.idlegandalf.ledd"
minSdkVersion 17
targetSdkVersion 23
versionCode 2
versionName "1.0.1"
minSdkVersion 24
targetSdkVersion 28
versionCode System.getenv("BUILD_NUMBER") as Integer ?: 100
versionName "2.0.0-SNAPSHOT"
archivesBaseName = "LedD-" + versionName + "-" + versionCode
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:support-v4:23.0.1'
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.koushikdutta.async:androidasync:2.1.6'
compile 'com.android.support:design:23.0.1'
compile 'com.larswerkman:HoloColorPicker:1.5'
compile 'com.google.guava:guava:19.0-rc1'
provided 'org.projectlombok:lombok:1.16.6'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.koushikdutta.async:androidasync:2.2.1'
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation 'com.jakewharton.timber:timber:4.7.1'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.jakewharton:butterknife:8.8.1'
implementation 'com.github.madrapps:pikolo:1.1.6'
implementation 'com.google.guava:guava:27.0-android'
implementation('com.mikepenz:materialdrawer:6.1.1@aar') {
transitive = true
}
annotationProcessor 'org.projectlombok:lombok:1.18.4'
compileOnly 'org.projectlombok:lombok:1.18.4'
}

View File

@@ -17,19 +17,20 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<manifest
package="com.idlegandalf.ledd"
xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.idlegandalf.ledd">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-feature android:glEsVersion="0x00030000" android:required="true" />
<application
android:name=".ColorApplication"
android:allowBackup="true"
android:fullBackupContent="false"
android:icon="@drawable/ic_launcher"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity

View File

@@ -22,59 +22,77 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import com.idlegandalf.ledd.callbacks.RecieveColorCallback;
import com.google.android.material.snackbar.Snackbar;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.idlegandalf.ledd.callbacks.ReceiveColorCallback;
import com.idlegandalf.ledd.callbacks.StripesCallback;
import com.idlegandalf.ledd.components.HSV;
import com.idlegandalf.ledd.components.LedDDaemon;
import com.idlegandalf.ledd.components.LedStripe;
import com.idlegandalf.ledd.components.Profile;
import com.idlegandalf.ledd.fragments.AddProfileDialog;
import com.idlegandalf.ledd.fragments.AddStripeDialog;
import com.idlegandalf.ledd.helper.LedDHelper;
import com.larswerkman.holocolorpicker.ColorPicker;
import com.larswerkman.holocolorpicker.SVBar;
import com.idlegandalf.ledd.utils.RateLimiter;
import com.madrapps.pikolo.HSLColorPicker;
import com.madrapps.pikolo.listeners.SimpleColorSelectionListener;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.holder.BadgeStyle;
import com.mikepenz.materialdrawer.interfaces.OnCheckedChangeListener;
import com.mikepenz.materialdrawer.model.DividerDrawerItem;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
import com.mikepenz.materialdrawer.model.SecondarySwitchDrawerItem;
import com.mikepenz.materialdrawer.model.SwitchDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import org.json.JSONException;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import butterknife.BindView;
import butterknife.ButterKnife;
import timber.log.Timber;
public class ColorActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
public class ColorActivity extends AppCompatActivity implements Drawer.OnDrawerItemClickListener, Drawer.OnDrawerItemLongClickListener, OnCheckedChangeListener {
@Bind(R.id.drawer_layout)
DrawerLayout mDrawerLayout;
@Bind(R.id.toolbar)
@BindView(R.id.main_layout)
LinearLayout scrollView;
@BindView(R.id.toolbar)
Toolbar toolbar;
@Bind(R.id.drawer)
NavigationView navigationView;
@Bind(R.id.picker)
ColorPicker colorPicker;
@Bind(R.id.svbar)
SVBar svBar;
private ActionBarDrawerToggle mDrawerToggle;
@BindView(R.id.picker)
HSLColorPicker colorPicker;
Drawer mDrawer;
private List<IDrawerItem> mDaemons;
private refreshDaemonsListener daemonsListener;
private List<LedStripe> ledStripes;
private List<Profile> profiles;
private LedStripe mCurrentStripe;
private LedDHelper mCurrentHelper;
private boolean fromOnCreate = true;
private boolean autoColorSet = false;
private RateLimiter limiter;
private boolean isRefreshRunning = false;
private Type profileList = new TypeToken<List<Profile>>() {
}.getType();
private PrimaryDrawerItem menuProfiles;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -82,56 +100,78 @@ public class ColorActivity extends AppCompatActivity implements NavigationView.O
setContentView(R.layout.activity_color);
ButterKnife.bind(this);
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
}
// check for connectivity
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isConnected()) {
// TODO: Display error (snackbar)
if (networkInfo == null || !networkInfo.isConnected() || networkInfo.getType() != ConnectivityManager.TYPE_WIFI) {
Snackbar.make(scrollView, R.string.snackbar_no_wlan, Snackbar.LENGTH_INDEFINITE).setAction("RETRY", v -> {
refreshStripes();
}).show();
}
colorPicker.addSVBar(svBar);
colorPicker.setShowOldCenterColor(false);
mDaemons = new ArrayList<>();
limiter = new RateLimiter(30.0, 1000);
colorPicker.setOnColorChangedListener(new ColorPicker.OnColorChangedListener() {
colorPicker.setColorSelectionListener(new SimpleColorSelectionListener() {
@Override
public void onColorChanged(int i) {
if (mCurrentStripe != null && mCurrentHelper != null) {
float[] hsv = new float[3];
Color.colorToHSV(i, hsv);
mCurrentStripe.setColor(new HSV(hsv[0], hsv[1], hsv[2]));
mCurrentHelper.setColor(mCurrentStripe);
public void onColorSelected(int color) {
if (mCurrentStripe != null && limiter.check() && !autoColorSet) {
mCurrentStripe.setColor(color);
}
}
});
navigationView.setNavigationItemSelectedListener(this);
setSupportActionBar(toolbar);
toolbar.setTitle(R.string.app_name);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.app_name, R.string.app_name) {
mDrawer = new DrawerBuilder()
.withActivity(this)
.withToolbar(toolbar)
.withOnDrawerItemClickListener(this)
.withOnDrawerItemLongClickListener(this)
.addStickyDrawerItems(
new PrimaryDrawerItem().withName(R.string.text_add_stripe).withTag("add_stripe").withSelectable(false).withIcon(R.drawable.ic_add_circle_black_48dp),
new PrimaryDrawerItem().withName(R.string.text_settings).withTag("settings").withSelectable(false).withIcon(R.drawable.ic_tune_black_48dp)
)
.addDrawerItems(
new DividerDrawerItem(),
menuProfiles = new PrimaryDrawerItem()
.withName("Profiles")
.withIcon(R.drawable.ic_save_black_48dp)
.withSelectable(false)
.withIsExpanded(true)
.withBadgeStyle(new BadgeStyle().withColor(Color.CYAN).withTextColor(Color.WHITE))
)
.build();
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
// TODO: do things that have to be done here
}
menuProfiles.withSubItems(new SecondaryDrawerItem().withName("Add Profile").withTag("add_profile").withSelectable(false).withIcon(R.drawable.ic_add_circle_outline_black_48dp));
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
// TODO: do things that have to be done here
}
};
// set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
// enable Homebutton navigation to drawer
// enable HomeButton navigation to drawer
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
mDrawer.getActionBarDrawerToggle().setDrawerIndicatorEnabled(true);
}
List<IDrawerItem> subProfiles = menuProfiles.getSubItems();
if (PreferenceManager.getDefaultSharedPreferences(this).contains("profiles")) {
profiles = new Gson().fromJson(PreferenceManager.getDefaultSharedPreferences(this).getString("profiles", ""), profileList);
for (Profile profile : profiles) {
subProfiles.add(0, new SecondaryDrawerItem().withName(profile.getName()).withTag(profile.getValues()).withSelectable(false).withIcon(R.drawable.ic_note_black_48dp));
}
} else {
profiles = new ArrayList<>();
}
menuProfiles.withSubItems(subProfiles);
mDrawer.updateItem(menuProfiles);
daemonsListener = new refreshDaemonsListener();
registerReceiver(daemonsListener, new IntentFilter(ColorApplication.INTENT_ACTION_REFRESH));
}
@Override
@@ -142,39 +182,56 @@ public class ColorActivity extends AppCompatActivity implements NavigationView.O
return true;
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
@Override
protected void onRestart() {
super.onRestart();
ColorApplication.getInstance().onResume();
registerReceiver(daemonsListener, new IntentFilter(ColorApplication.INTENT_ACTION_REFRESH));
refreshStripes();
}
@Override
public void onCheckedChanged(IDrawerItem drawerItem, CompoundButton buttonView, boolean isChecked) {
LedStripe stripe = null;
for (LedStripe ledStripe : ledStripes) {
if (((int) drawerItem.getTag()) == ledStripe.getId()) {
stripe = ledStripe;
break;
}
}
if (stripe != null) {
if (isChecked) {
if (stripe == mCurrentStripe) {
if (colorPicker.getSolidColor() != Color.BLACK)
stripe.setColor(colorPicker.getSolidColor());
else {
colorPicker.setColor(Color.WHITE);
}
} else {
stripe.setColor(Color.WHITE);
}
} else {
if (stripe == mCurrentStripe)
colorPicker.setColor(Color.BLACK);
else
stripe.setColor(Color.BLACK);
}
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) {
mDrawerLayout.closeDrawer(Gravity.LEFT);
if (mDrawer.isDrawerOpen()) {
mDrawer.closeDrawer();
} else {
mDrawerLayout.openDrawer(Gravity.LEFT);
mDrawer.openDrawer();
}
return true;
@@ -187,6 +244,12 @@ public class ColorActivity extends AppCompatActivity implements NavigationView.O
super.onPause();
ColorApplication.getInstance().teardown();
unregisterReceiver(daemonsListener);
if (mCurrentStripe != null)
PreferenceManager.getDefaultSharedPreferences(this).edit().putInt("lastStripe", mCurrentStripe.getId()).apply();
if (profiles != null)
PreferenceManager.getDefaultSharedPreferences(this).edit().putString("profiles", new Gson().toJson(profiles, profileList)).apply();
}
@Override
@@ -198,156 +261,267 @@ public class ColorActivity extends AppCompatActivity implements NavigationView.O
@Override
protected void onResume() {
super.onResume();
ColorApplication.getInstance().onResume();
registerReceiver(daemonsListener, new IntentFilter(ColorApplication.INTENT_ACTION_REFRESH));
try {
if (!fromOnCreate) {
ColorApplication.getInstance().onResume();
registerReceiver(daemonsListener, new IntentFilter(ColorApplication.INTENT_ACTION_REFRESH));
refreshStripes();
} catch (IOException e) {
e.printStackTrace();
} else {
fromOnCreate = false;
}
}
@SuppressWarnings("unchecked")
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
int id = menuItem.getItemId();
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
if (drawerItem.getTag() instanceof String) {
String tag = (String) drawerItem.getTag();
switch (id) {
case R.id.nv_add_stripe:
new AddStripeDialog().show(getFragmentManager(), "");
return true;
case R.id.nv_settings:
return true;
}
for (LedStripe stripe : ledStripes) {
if (stripe.getName().equals(menuItem.getTitle())) {
mCurrentStripe = stripe;
try {
mCurrentHelper = ColorApplication.getInstance().getHelperForDaemon(stripe.getLedDDaemon());
} catch (IOException e) {
e.printStackTrace();
}
mDrawerLayout.closeDrawer(Gravity.LEFT);
toolbar.setTitle(stripe.getName());
try {
mCurrentHelper.getColor(mCurrentStripe, new RecieveColorCallback() {
@Override
public void onColorRecieved(LedStripe stripe) {
final HSV cColor = stripe.getColor();
runOnUiThread(new Runnable() {
@Override
public void run() {
colorPicker.setColor(Color.HSVToColor(new float[]{(float) cColor.getHue(), (float) cColor.getSaturation(),
(float) cColor.getValue()}));
}
});
}
@Override
public void onRecievFailed(String msg) {
}
@Override
public void onConnectionFailed(String message) {
}
});
} catch (JSONException | IOException e) {
e.printStackTrace();
}
return true;
switch (tag) {
case "add_stripe":
new AddStripeDialog().show(getFragmentManager(), "");
return true;
case "settings":
return true;
case "add_profile":
new AddProfileDialog().show(getFragmentManager(), "");
return true;
}
}
if (drawerItem.getTag() instanceof SparseArray) {
SparseArray<HSV> sparseArray = (SparseArray<HSV>) drawerItem.getTag();
if (ledStripes != null) {
for (LedStripe ledStripe : ledStripes) {
String json_workaround = new Gson().toJson(sparseArray.get(ledStripe.getId()));
HSV nHSV = new Gson().fromJson(json_workaround, new TypeToken<HSV>() {
}.getType());
if (nHSV != null) {
ledStripe.setColor(nHSV);
}
}
}
}
if (drawerItem.isSelectable()) {
if (drawerItem.getTag() instanceof Integer) {
int tag = (int) drawerItem.getTag();
for (LedStripe stripe : ledStripes) {
if (tag == stripe.getId()) {
selectStripe(stripe);
return true;
}
}
}
}
return false;
}
@Override
public boolean onItemLongClick(View view, int position, IDrawerItem drawerItem) {
Timber.d("Longclick of %s", drawerItem.getClass().getName());
return false;
}
public void refreshStripes() throws IOException {
reCreateNavigationView(); // need to recreate the navigationview since we can't remove a once added submenu
public List<LedStripe> getStripes() {
return ledStripes;
}
final Menu nvMenu = navigationView.getMenu();
final int stripeGroup = 42;
public void addProfile(Profile profile) {
if (profiles != null) {
profiles.add(profile);
List<IDrawerItem> subProfiles = menuProfiles.getSubItems();
subProfiles.add(0, new SecondaryDrawerItem().withName(profile.getName()).withSelectable(false).withTag(profile.getValues()).withIcon(R.drawable.ic_note_black_48dp));
menuProfiles.withSubItems(subProfiles).withIsExpanded(true).withBadge(String.valueOf(profiles.size()));
mDrawer.updateItem(menuProfiles);
}
}
@SuppressWarnings("deprecated")
public void refreshStripes() {
if (isRefreshRunning)
return;
isRefreshRunning = true;
int i = 1;
for (final LedDDaemon dDaemon : ColorApplication.getInstance().getDaemons()) {
LedDHelper helper = ColorApplication.getInstance().getHelperForDaemon(dDaemon);
if (helper != null) {
try {
final int finalI = i;
helper.getStripes(new StripesCallback() {
@Override
public void onSuccess(final List<LedStripe> stripes) {
runOnUiThread(new Runnable() {
final int finalI = i;
helper.getStripes(new StripesCallback() {
@Override
public void onSuccess(List<LedStripe> stripes) {
ledStripes = stripes;
runOnUiThread(() -> {
PrimaryDrawerItem nDaemonMenu = null;
long selectedItemId = -1;
for (IDrawerItem drawerItem : mDaemons) {
if (((PrimaryDrawerItem) drawerItem).getName().getText().equals(dDaemon.toString())) {
nDaemonMenu = (PrimaryDrawerItem) drawerItem;
break;
}
}
if (nDaemonMenu == null) {
nDaemonMenu = new PrimaryDrawerItem().withName(dDaemon.toString()).withTag(finalI).withSelectable(false).withIsExpanded(true).withIcon(R.drawable.ic_computer_black_48dp);
mDrawer.addItemAtPosition(nDaemonMenu, 0);
mDaemons.add(nDaemonMenu);
}
int lastStripeId = -1;
if (PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).contains("lastStripe")) {
lastStripeId = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getInt("lastStripe", -1);
}
List<IDrawerItem> mStripes = new ArrayList<>();
for (LedStripe stripe : ledStripes) {
final SwitchDrawerItem sItem = new SwitchDrawerItem()
.withName(stripe.getName())
.withTag(stripe.getId())
.withIcon(R.drawable.ic_wb_iridescent_black_48dp)
.withOnCheckedChangeListener(ColorActivity.this);
mStripes.add(sItem);
if (lastStripeId != -1 && stripe.getId() == lastStripeId) {
selectStripe(stripe);
selectedItemId = sItem.getIdentifier();
}
}
nDaemonMenu.withSubItems(mStripes);
nDaemonMenu.withBadge(String.valueOf(mStripes.size()));
//noinspection deprecation
nDaemonMenu.withBadgeStyle(new BadgeStyle().withColor(getResources().getColor(R.color.material_drawer_accent)).withTextColor(Color.WHITE));
mDrawer.updateItem(nDaemonMenu);
if (selectedItemId != -1)
mDrawer.setSelection(selectedItemId);
//noinspection ConstantConditions
Snackbar.make(findViewById(android.R.id.content), R.string.snackbar_stripes_reloaded, Snackbar.LENGTH_LONG).show();
});
for (LedStripe stripe : ledStripes) {
stripe.getColor(new ReceiveColorCallback() {
@Override
public void run() {
SubMenu nDaemonMenu = nvMenu.addSubMenu(Menu.NONE, Menu.NONE, finalI, dDaemon.toString());
nDaemonMenu.setGroupCheckable(stripeGroup, true, true);
public void onConnectionFailed(String message) {
ledStripes = stripes;
Snackbar.make(findViewById(android.R.id.content), "LED stripes reloaded", Snackbar.LENGTH_LONG).show();
}
for (LedStripe stripe : ledStripes) {
MenuItem sItem = nDaemonMenu.add(stripeGroup, View.generateViewId(), stripe.getId(), stripe.getName());
sItem.setIcon(R.drawable.ic_wb_iridescent_black_48dp);
@Override
public void onColorReceived(LedStripe stripe) {
if (stripe.isOn()) {
IDrawerItem sItem = findItemForStripe(stripe);
if (sItem != null) {
final SecondarySwitchDrawerItem cItem = (SecondarySwitchDrawerItem) sItem;
cItem.withSwitchEnabled(true);
runOnUiThread(() -> mDrawer.updateItem(cItem));
}
}
}
@Override
public void onReceiveFailed(int code, String msg) {
}
});
}
}
@Override
public void onGetFailed(String message) {
Snackbar.make(findViewById(android.R.id.content), "Coudn't get stripes from daemon: " + message, Snackbar.LENGTH_LONG)
.show();
@Override
public void onGetFailed(int code, String message) {
//noinspection ConstantConditions
Snackbar.make(findViewById(android.R.id.content), getString(R.string.snackbar_no_connection_stripes) + message, Snackbar
.LENGTH_LONG).show();
}
}
@Override
public void onConnectionFailed(String message) {
//noinspection ConstantConditions
Snackbar.make(findViewById(android.R.id.content), getString(R.string.snackbar_connection_failed) + message, Snackbar
.LENGTH_LONG).show();
}
});
@Override
public void onConnectionFailed(String message) {
Snackbar.make(findViewById(android.R.id.content), "Coudn't connect to daemon: " + message, Snackbar.LENGTH_LONG).show();
}
});
} catch (JSONException | IOException e) {
e.printStackTrace();
}
}
i++;
}
isRefreshRunning = false;
}
private void reCreateNavigationView() {
runOnUiThread(new Runnable() {
private void selectStripe(LedStripe stripe) {
mCurrentStripe = stripe;
toolbar.setTitle(stripe.getName());
autoColorSet = true;
mDrawer.closeDrawer();
mCurrentStripe.getColor(new ReceiveColorCallback() {
@Override
public void run() {
mDrawerLayout.removeView(navigationView);
navigationView = new NavigationView(ColorActivity.this);
DrawerLayout.LayoutParams params = new DrawerLayout.LayoutParams(DrawerLayout.LayoutParams.WRAP_CONTENT, DrawerLayout.LayoutParams
.MATCH_PARENT);
params.gravity = Gravity.START;
navigationView.setLayoutParams(params);
navigationView.inflateMenu(R.menu.navigation_drawer);
navigationView.inflateHeaderView(R.layout.navigation_header);
mDrawerLayout.addView(navigationView, params);
navigationView.setNavigationItemSelectedListener(ColorActivity.this);
mDrawerToggle.syncState();
public void onColorReceived(final LedStripe stripe) {
final HSV cColor = stripe.getColor();
final int color = Color.HSVToColor(new float[]{(float) cColor.getHue(), (float) cColor.getSaturation(), (float) cColor.getValue()});
runOnUiThread(() -> {
colorPicker.setColor(color);
autoColorSet = false;
if (stripe.isOn()) {
IDrawerItem fItem = findItemForStripe(stripe);
if (fItem != null)
((SecondarySwitchDrawerItem) fItem).withSwitchEnabled(true);
}
});
}
@Override
public void onReceiveFailed(int code, String msg) {
autoColorSet = false;
}
@Override
public void onConnectionFailed(String message) {
autoColorSet = false;
}
});
}
@Nullable
private IDrawerItem findItemForStripe(LedStripe stripe) {
for (IDrawerItem dItem : mDaemons) {
if (((PrimaryDrawerItem) dItem).getSubItems() != null) {
for (IDrawerItem sItem : ((PrimaryDrawerItem) dItem).getSubItems()) {
if (((int) sItem.getTag()) == stripe.getId()) {
return sItem;
}
}
}
}
return null;
}
protected class refreshDaemonsListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ColorApplication.INTENT_ACTION_REFRESH)) {
try {
refreshStripes();
} catch (IOException e) {
e.printStackTrace();
}
refreshStripes();
}
}
}

View File

@@ -21,7 +21,6 @@ package com.idlegandalf.ledd;
import android.app.Application;
import android.content.Intent;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@@ -29,14 +28,13 @@ import com.idlegandalf.ledd.callbacks.DiscoverCallback;
import com.idlegandalf.ledd.components.LedDDaemon;
import com.idlegandalf.ledd.helper.LedDHelper;
import org.json.JSONException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import timber.log.Timber;
public class ColorApplication extends Application {
public static final String TAG = "LedD";
public static final String INTENT_ACTION_REFRESH = "com.idlegandalf.ledd.action.refreshStripes";
@@ -50,51 +48,40 @@ public class ColorApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
singleton = this;
singleton = this;
ledDHelpers = new HashMap<>();
this.onResume();
}
public LedDHelper getHelperForDaemon(final LedDDaemon ledDDaemon) throws IOException {
public LedDHelper getHelperForDaemon(final LedDDaemon ledDDaemon) {
if (ledDHelpers.containsKey(ledDDaemon) && ledDHelpers.get(ledDDaemon) != null) {
return ledDHelpers.get(ledDDaemon);
} else {
final LedDHelper dHelper = new LedDHelper(ledDDaemon, getApplicationContext());
try {
dHelper.discover(new DiscoverCallback() {
@Override
public void onConnectionFailed(String message) {
}
@Override
public void onDiscoverSuccessfully(String version) {
ledDHelpers.put(ledDDaemon, dHelper);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
dHelper.discover(new DiscoverCallback() {
@Override
public void onConnectionFailed(String message) {
}
@Override
public void onDiscoverSuccessfully(String version) {
ledDHelpers.put(ledDDaemon, dHelper);
}
});
return dHelper;
}
}
public List<LedDDaemon> getDaemons() {
ArrayList<LedDDaemon> ledDDaemons = new ArrayList<>();
ledDDaemons.addAll(ledDHelpers.keySet());
return ledDDaemons;
return new ArrayList<>(ledDHelpers.keySet());
}
public void teardown() {
for (LedDHelper dHelper : ledDHelpers.values()) {
dHelper.teardown();
}
ledDHelpers.values().forEach(LedDHelper::teardown);
PreferenceManager.getDefaultSharedPreferences(this).edit().putString("daemons", new Gson().toJson(ledDHelpers.keySet())).commit();
PreferenceManager.getDefaultSharedPreferences(this).edit().putString("daemons", new Gson().toJson(ledDHelpers.keySet())).apply();
}
public void onResume() {
@@ -103,37 +90,31 @@ public class ColorApplication extends Application {
TypeToken<Set<LedDDaemon>>() {
}.getType());
Timber.i("Loaded " + ledDDaemons.size() + " Daemons from preferences");
for (final LedDDaemon ledDDaemon : ledDDaemons) {
try {
final LedDHelper helper = new LedDHelper(ledDDaemon, getApplicationContext());
final LedDHelper helper = new LedDHelper(ledDDaemon, getApplicationContext());
helper.discover(new DiscoverCallback() {
@Override
public void onDiscoverSuccessfully(String version) {
//ledDDaemon.setActive(true);
ledDHelpers.put(ledDDaemon, helper);
helper.discover(new DiscoverCallback() {
@Override
public void onDiscoverSuccessfully(String version) {
//ledDDaemon.setActive(true);
ledDHelpers.put(ledDDaemon, helper);
Intent i = new Intent(INTENT_ACTION_REFRESH);
sendBroadcast(i);
}
Intent i = new Intent(INTENT_ACTION_REFRESH);
sendBroadcast(i);
}
@Override
public void onConnectionFailed(String message) {
//ledDDaemon.setActive(false);
ledDHelpers.put(ledDDaemon, helper);
@Override
public void onConnectionFailed(String message) {
//ledDDaemon.setActive(false);
ledDHelpers.put(ledDDaemon, helper);
Intent i = new Intent(INTENT_ACTION_REFRESH);
sendBroadcast(i);
}
});
} catch (IOException | JSONException e) {
e.printStackTrace();
}
Intent i = new Intent(INTENT_ACTION_REFRESH);
sendBroadcast(i);
}
});
}
}
Log.i(ColorApplication.TAG, "Loaded " + ledDHelpers.size() + " Daemons from preferences");
}
}

View File

@@ -1,38 +0,0 @@
/*
* LEDD Project
* Copyright (C) 2015 LEDD Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.idlegandalf.ledd;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import com.idlegandalf.ledd.fragments.SettingsFragment;
public class SettingsActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
// Display the fragment as the main content.
getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
}
}

View File

@@ -28,6 +28,6 @@ public interface AddControllerCallback extends BaseCallback {
*/
void onControllerAdded(Controller controller);
void onAddFailed(String msg, String detail);
void onAddFailed(int code, String msg);
}

View File

@@ -23,4 +23,6 @@ import com.idlegandalf.ledd.components.LedStripe;
public interface AddStripeCallback extends BaseCallback {
void onAddSuccessfully(LedStripe stripe);
void onAddFailed(int code, String msg);
}

View File

@@ -20,8 +20,8 @@ package com.idlegandalf.ledd.callbacks;
import com.idlegandalf.ledd.components.LedStripe;
public interface RecieveColorCallback extends BaseCallback {
void onColorRecieved(LedStripe stripe);
public interface ReceiveColorCallback extends BaseCallback {
void onColorReceived(LedStripe stripe);
void onRecievFailed(String msg);
void onReceiveFailed(int code, String msg);
}

View File

@@ -26,5 +26,5 @@ import java.util.List;
public interface StripesCallback extends BaseCallback {
void onSuccess(List<LedStripe> stripes);
void onGetFailed(String message);
void onGetFailed(int code, String message);
}

View File

@@ -19,11 +19,11 @@
package com.idlegandalf.ledd.components;
import org.json.JSONObject;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
public abstract class AnswerTask {
public abstract void onConnectionFailed(String message);
public abstract void onResponse(JSONObject response);
public abstract void onResponse(JSONRPC2Response response);
}

View File

@@ -33,8 +33,4 @@ public class HSV {
this.saturation = s;
this.value = v;
}
public HSV() {
}
}

View File

@@ -50,10 +50,7 @@ public class LedDDaemon {
@Override
public boolean equals(Object o) {
if (o instanceof LedDDaemon) {
if (address.equals(((LedDDaemon) o).address) && port == ((LedDDaemon) o).port) return true;
}
return false;
return o instanceof LedDDaemon && address.equals(((LedDDaemon) o).address) && port == ((LedDDaemon) o).port;
}
@Override

View File

@@ -18,16 +18,16 @@
package com.idlegandalf.ledd.components;
import org.json.JSONObject;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
import lombok.Getter;
@Getter
public class LedDRequest {
JSONObject request;
JSONRPC2Request request;
AnswerTask task;
public LedDRequest(JSONObject request, AnswerTask task) {
public LedDRequest(JSONRPC2Request request, AnswerTask task) {
this.request = request;
this.task = task;
}

View File

@@ -18,6 +18,13 @@
package com.idlegandalf.ledd.components;
import android.graphics.Color;
import android.support.annotation.Nullable;
import com.idlegandalf.ledd.ColorApplication;
import com.idlegandalf.ledd.callbacks.ReceiveColorCallback;
import com.idlegandalf.ledd.helper.LedDHelper;
import lombok.Getter;
import lombok.Setter;
@@ -34,6 +41,7 @@ public class LedStripe {
boolean RGB;
Controller controller;
LedDDaemon ledDDaemon;
LedDHelper helper;
public LedStripe() {
this(-1, -1, -1, -1, "");
@@ -55,4 +63,55 @@ public class LedStripe {
this.name = name;
this.RGB = RGB;
}
@Override
public String toString() {
return String.format("%s->%s->%s (%d|%d|%d)", ledDDaemon, controller.getAddress(), name, channelRed, channelGreen, channelBlue);
}
public void setColor(int color) {
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
setColor(new HSV(hsv[0], hsv[1], hsv[2]));
}
public void setColor(HSV color) {
checkHelper();
this.color = color;
helper.setColor(this);
}
private void checkHelper() {
if (helper == null) {
helper = ColorApplication.getInstance().getHelperForDaemon(ledDDaemon);
}
}
public void getColor(@Nullable final ReceiveColorCallback callback) {
checkHelper();
helper.getColor(this, new ReceiveColorCallback() {
@Override
public void onColorReceived(LedStripe stripe) {
color = stripe.getColor();
if (callback != null)
callback.onColorReceived(LedStripe.this);
}
@Override
public void onReceiveFailed(int code, String msg) {
if (callback != null) callback.onReceiveFailed(code, msg);
}
@Override
public void onConnectionFailed(String message) {
if (callback != null) callback.onConnectionFailed(message);
}
});
}
public boolean isOn() {
return color != null && color.getValue() != 0.0;
}
}

View File

@@ -0,0 +1,22 @@
package com.idlegandalf.ledd.components;
import android.util.SparseArray;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Profile {
private SparseArray<HSV> values;
private String name;
public Profile(SparseArray<HSV> hsvHashMap) {
setValues(hsvHashMap);
}
public Profile(String name) {
setValues(new SparseArray<HSV>());
setName(name);
}
}

View File

@@ -18,33 +18,26 @@
package com.idlegandalf.ledd.components;
import org.json.JSONException;
import org.json.JSONObject;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
import java.util.UUID;
import org.json.JSONException;
import lombok.Getter;
@Getter
public class Sendable {
LedDDaemon recipient;
JSONObject message;
String ref;
JSONRPC2Request request;
AnswerTask onAnswer;
public Sendable(JSONObject msg, AnswerTask task, LedDDaemon ledDDaemon) throws JSONException {
this(msg, UUID.randomUUID().toString(), task, ledDDaemon);
}
public Sendable(JSONObject msg, String ref, AnswerTask task, LedDDaemon recipient) throws JSONException {
this.message = msg;
this.ref = ref;
this.message.put("ref", ref);
public Sendable(JSONRPC2Request request, AnswerTask task, LedDDaemon recipient) throws JSONException {
this.request = request;
this.onAnswer = task;
this.recipient = recipient;
}
public void onResponse(JSONObject object) {
public void onResponse(JSONRPC2Response object) {
if (onAnswer != null) {
onAnswer.onResponse(object);
}
@@ -55,6 +48,8 @@ public class Sendable {
}
public void onConnectionFailed(String message) {
onAnswer.onConnectionFailed(message);
if (onAnswer != null) {
onAnswer.onConnectionFailed(message);
}
}
}

View File

@@ -21,9 +21,6 @@ package com.idlegandalf.ledd.components;
import com.idlegandalf.ledd.helper.LedDHelper;
import org.json.JSONException;
import java.io.IOException;
import java.util.ArrayList;
public class StripeGroup {
@@ -60,7 +57,7 @@ public class StripeGroup {
return null;
}
public void setRGB(int r, int g, int b, LedDHelper api) throws JSONException, IOException {
public void setRGB(int r, int g, int b, LedDHelper api) {
for (int i = 0; i < mStripes.size(); i++) {
//mStripes.get(i).setRGB(r, g, b, api);
}

View File

@@ -22,8 +22,6 @@ import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
@@ -31,6 +29,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout;
import com.google.gson.Gson;
import com.idlegandalf.ledd.ColorApplication;
import com.idlegandalf.ledd.R;
@@ -39,31 +39,35 @@ import com.idlegandalf.ledd.components.Controller;
import com.idlegandalf.ledd.components.LedDDaemon;
import com.idlegandalf.ledd.helper.LedDHelper;
import org.json.JSONException;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.ParsePosition;
import butterknife.Bind;
import butterknife.BindView;
import butterknife.ButterKnife;
public class AddControllerDialog extends DialogFragment implements DialogInterface.OnShowListener {
@Bind(R.id.input_i2c_layout)
@BindView(R.id.input_i2c_layout)
TextInputLayout i2cLayout;
@Bind(R.id.input_i2c)
@BindView(R.id.input_i2c)
EditText i2cText;
@Bind(R.id.input_address_layout)
@BindView(R.id.input_address_layout)
TextInputLayout addressLayout;
@Bind(R.id.input_address)
@BindView(R.id.input_address)
EditText addressText;
@Bind(R.id.input_channel_layout)
@BindView(R.id.input_channel_layout)
TextInputLayout channelLayout;
@Bind(R.id.input_channel)
@BindView(R.id.input_channel)
EditText channelText;
LedDDaemon dDaemon;
private static boolean isNumeric(String str) {
NumberFormat formatter = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
formatter.parse(str, pos);
return str.length() == pos.getIndex();
}
public Dialog onCreateDialog(Bundle savedInstanceState) {
View v = View.inflate(getActivity(), R.layout.fragment_addcontroller, null);
ButterKnife.bind(this, v);
@@ -136,101 +140,60 @@ public class AddControllerDialog extends DialogFragment implements DialogInterfa
}
});
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AddStripeDialog.instance.onResume();
alertDialog.dismiss();
}
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(v -> {
// TODO: AddStripeDialog.instance.onResume();
alertDialog.dismiss();
});
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (i2cText.getText().toString().isEmpty() || !isNumeric(i2cText.getText().toString())) {
i2cLayout.setError("No valid i2c device number");
return;
}
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
if (i2cText.getText().toString().isEmpty() || !isNumeric(i2cText.getText().toString())) {
i2cLayout.setError("No valid i2c device number");
return;
}
if (!addressText.getText().toString().contains("0x") || !addressText.getText().toString().split("x")[1].matches("-?[0-9a-fA-F]+")) {
addressLayout.setError("No valid hexdecimal address");
return;
}
if (!addressText.getText().toString().contains("0x") || !addressText.getText().toString().split("x")[1].matches("-?[0-9a-fA-F]+")) {
addressLayout.setError("No valid hexdecimal address");
return;
}
if (channelText.getText().toString().isEmpty() || !isNumeric(channelText.getText().toString()) && Integer.parseInt(channelText
.getText().toString()) <= 0) {
channelLayout.setError("No valid channel amount");
return;
}
if (channelText.getText().toString().isEmpty() || !isNumeric(channelText.getText().toString()) && Integer.parseInt(channelText
.getText().toString()) <= 0) {
channelLayout.setError("No valid channel amount");
return;
}
Controller c = new Controller();
c.setAddress(addressText.getText().toString());
c.setI2c_device(Integer.parseInt(i2cText.getText().toString()));
c.setChannels(Integer.parseInt(channelText.getText().toString()));
Controller c = new Controller();
c.setAddress(addressText.getText().toString());
c.setI2c_device(Integer.parseInt(i2cText.getText().toString()));
c.setChannels(Integer.parseInt(channelText.getText().toString()));
LedDHelper helper = null;
try {
helper = ColorApplication.getInstance().getHelperForDaemon(dDaemon);
} catch (IOException e) {
e.printStackTrace();
}
LedDHelper helper = ColorApplication.getInstance().getHelperForDaemon(dDaemon);
if (helper != null) {
try {
helper.addController(c, new AddControllerCallback() {
@Override
public void onControllerAdded(final Controller controller) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content))
.getChildAt(0), "Added Controller (" + controller.getId() + ")", Snackbar.LENGTH_LONG).show();
}
});
if (helper != null) {
helper.addController(c, new AddControllerCallback() {
@Override
public void onControllerAdded(final Controller controller) {
getActivity().runOnUiThread(() -> Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0), String.format(getActivity().getString(R.string.snachbar_added_controller), controller.getId()), Snackbar.LENGTH_LONG).show());
dDaemon.getControllers().add(controller);
dismiss();
}
@Override
public void onAddFailed(final String msg, String detail) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content))
.getChildAt(0), "Error: " + msg, Snackbar.LENGTH_LONG).show();
}
});
AddStripeDialog.instance.onResume();
dismiss();
}
@Override
public void onConnectionFailed(final String message) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content))
.getChildAt(0), "Coudn't connect to" +
" daemon at " + dDaemon + ": " + message, Snackbar.LENGTH_LONG).show();
}
});
AddStripeDialog.instance.onResume();
dismiss();
}
});
} catch (JSONException | IOException e) {
e.printStackTrace();
dDaemon.getControllers().add(controller);
dismiss();
}
}
@Override
public void onAddFailed(final int code, final String msg) {
getActivity().runOnUiThread(() -> Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0), getActivity().getString(R.string.snackbar_error) + msg, Snackbar.LENGTH_LONG).show());
// TODO: AddStripeDialog.instance.onResume();
dismiss();
}
@Override
public void onConnectionFailed(final String message) {
getActivity().runOnUiThread(() -> Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0), String.format(getActivity().getString(R.string.snackbar_daemon_connection_failed), dDaemon, message), Snackbar.LENGTH_LONG).show());
// TODO: AddStripeDialog.instance.onResume();
dismiss();
}
});
}
});
}
private static boolean isNumeric(String str) {
NumberFormat formatter = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
formatter.parse(str, pos);
return str.length() == pos.getIndex();
}
}

View File

@@ -25,8 +25,6 @@ import android.content.DialogInterface;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
@@ -38,6 +36,8 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout;
import com.google.common.net.InetAddresses;
import com.idlegandalf.ledd.ColorActivity;
import com.idlegandalf.ledd.ColorApplication;
@@ -45,25 +45,22 @@ import com.idlegandalf.ledd.R;
import com.idlegandalf.ledd.callbacks.DiscoverCallback;
import com.idlegandalf.ledd.components.LedDDaemon;
import org.json.JSONException;
import java.io.IOException;
import java.net.Inet4Address;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import butterknife.BindView;
import butterknife.ButterKnife;
public class AddDaemonDialog extends DialogFragment implements DialogInterface.OnShowListener, NsdManager.DiscoveryListener {
private final String SERVICE_TYPE = "_ledd._tcp.";
@Bind(R.id.input_ip)
@BindView(R.id.input_ip)
EditText ip;
@Bind(R.id.input_ip_layout)
@BindView(R.id.input_ip_layout)
TextInputLayout ip_lay;
@Bind(R.id.host_container)
@BindView(R.id.host_container)
LinearLayout hostContainer;
List<LedDDaemon> ledDDaemons = new ArrayList<>();
NsdManager mNsdManager;
@@ -111,46 +108,40 @@ public class AddDaemonDialog extends DialogFragment implements DialogInterface.O
}
});
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mNsdManager.stopServiceDiscovery(AddDaemonDialog.this);
AddStripeDialog.instance.onResume();
alertDialog.dismiss();
}
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(v -> {
mNsdManager.stopServiceDiscovery(AddDaemonDialog.this);
// TODO: AddStripeDialog.instance.onResume();
alertDialog.dismiss();
});
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String strIp = ip.getText().toString();
int port;
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
String strIp = ip.getText().toString();
int port;
if (strIp.contains(":")) {
strIp = strIp.split(":")[0];
try {
port = Integer.parseInt(ip.getText().toString().split(":")[1]);
} catch (NumberFormatException e) {
ip_lay.setError("Please check your port");
return;
}
if (port < 1024 || port > 65535) {
ip_lay.setError("Port is out of range");
return;
}
} else {
port = 1425;
if (strIp.contains(":")) {
strIp = strIp.split(":")[0];
try {
port = Integer.parseInt(ip.getText().toString().split(":")[1]);
} catch (NumberFormatException e) {
ip_lay.setError("Please check your port");
return;
}
if (InetAddresses.isInetAddress(strIp)) {
LedDDaemon daemon = new LedDDaemon(strIp, port);
if (!ledDDaemons.contains(daemon)) addDaemon(new LedDDaemon(strIp, port));
else ip_lay.setError("Daemon already exist");
} else {
ip_lay.setError("No valid ip address");
if (port < 1024 || port > 65535) {
ip_lay.setError("Port is out of range");
return;
}
} else {
port = 1425;
}
if (InetAddresses.isInetAddress(strIp)) {
LedDDaemon daemon = new LedDDaemon(strIp, port);
if (!ledDDaemons.contains(daemon)) addDaemon(new LedDDaemon(strIp, port));
else ip_lay.setError("Daemon already exist");
} else {
ip_lay.setError("No valid ip address");
}
});
}
@@ -198,49 +189,43 @@ public class AddDaemonDialog extends DialogFragment implements DialogInterface.O
final LedDDaemon nLedDDaemon = new LedDDaemon(serviceInfo.getHost().getHostAddress(), serviceInfo.getPort());
if (!ledDDaemons.contains(nLedDDaemon)) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
View v = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout
.host_row, hostContainer, false);
getActivity().runOnUiThread(() -> {
View v = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout
.host_row, hostContainer, false);
TextView host = (TextView) v.findViewById(R.id.text_host);
TextView host = (TextView) v.findViewById(R.id.text_host);
host.setText(nLedDDaemon.toString());
host.setText(nLedDDaemon.toString());
if (ColorApplication.getInstance().getDaemons().contains(nLedDDaemon)) {
v.setEnabled(false);
host.setEnabled(false);
}
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.isEnabled()) {
LedDDaemon d;
if (v instanceof TextView) {
d = (LedDDaemon) ((LinearLayout) v.getParent()).getTag();
} else {
d = (LedDDaemon) v.getTag();
}
if (d != null) {
addDaemon(d);
}
}
}
};
v.setOnClickListener(listener);
host.setOnClickListener(listener);
v.setTag(nLedDDaemon);
ledDDaemons.add(nLedDDaemon);
hostContainer.addView(v);
if (ColorApplication.getInstance().getDaemons().contains(nLedDDaemon)) {
v.setEnabled(false);
host.setEnabled(false);
}
View.OnClickListener listener = v1 -> {
if (v1.isEnabled()) {
LedDDaemon d;
if (v1 instanceof TextView) {
d = (LedDDaemon) ((LinearLayout) v1.getParent()).getTag();
} else {
d = (LedDDaemon) v1.getTag();
}
if (d != null) {
addDaemon(d);
}
}
};
v.setOnClickListener(listener);
host.setOnClickListener(listener);
v.setTag(nLedDDaemon);
ledDDaemons.add(nLedDDaemon);
hostContainer.addView(v);
});
}
}
@@ -286,44 +271,23 @@ public class AddDaemonDialog extends DialogFragment implements DialogInterface.O
}
private void addDaemon(final LedDDaemon ledDDaemon) {
try {
ColorApplication.getInstance().getHelperForDaemon(ledDDaemon).discover(new DiscoverCallback() {
@Override
public void onConnectionFailed(final String message) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0),
"Coudn't connect to" +
" daemon at " + ledDDaemon + ": " + message, Snackbar.LENGTH_LONG).show();
}
});
AddStripeDialog stripeAdd = (AddStripeDialog) getFragmentManager().findFragmentByTag("stripeAdd");
AddStripeDialog.instance.onResume();
dismiss();
}
ColorApplication.getInstance().getHelperForDaemon(ledDDaemon).discover(new DiscoverCallback() {
@Override
public void onConnectionFailed(final String message) {
getActivity().runOnUiThread(() -> Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0), String.format(getActivity().getString(R.string.snackbar_daemon_connection_failed), ledDDaemon, message), Snackbar.LENGTH_LONG).show());
// TODO: AddStripeDialog.instance.onResume();
dismiss();
}
@Override
public void onDiscoverSuccessfully(final String version) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0),
"Added LedD Daemon version: " + version, Snackbar.LENGTH_LONG).show();
}
});
@Override
public void onDiscoverSuccessfully(final String version) {
getActivity().runOnUiThread(() -> Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0),
getActivity().getString(R.string.snackbar_added_daemon_version, version), Snackbar.LENGTH_LONG).show());
try {
((ColorActivity) getActivity()).refreshStripes();
} catch (IOException e) {
e.printStackTrace();
}
AddStripeDialog.instance.onResume();
dismiss();
}
});
} catch (JSONException | IOException e) {
e.printStackTrace();
}
((ColorActivity) getActivity()).refreshStripes();
// TODO: AddStripeDialog.instance.onResume();
dismiss();
}
});
}
}

View File

@@ -0,0 +1,142 @@
package com.idlegandalf.ledd.fragments;
/*
* LEDD Project
* Copyright (C) 2015 LEDD Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.android.material.textfield.TextInputLayout;
import com.idlegandalf.ledd.ColorActivity;
import com.idlegandalf.ledd.R;
import com.idlegandalf.ledd.components.LedStripe;
import com.idlegandalf.ledd.components.Profile;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class AddProfileDialog extends DialogFragment implements DialogInterface.OnShowListener {
@BindView(R.id.input_profile_name_layout)
TextInputLayout nameLayout;
@BindView(R.id.input_profile_name)
EditText nameText;
@BindView(R.id.container_linlay)
LinearLayout checkboxContainer;
List<LedStripe> mStripes;
List<CheckBox> mCheckboxes;
public Dialog onCreateDialog(Bundle savedInstanceState) {
View v = View.inflate(getActivity(), R.layout.fragment_addprofile, null);
ButterKnife.bind(this, v);
mStripes = ((ColorActivity) getActivity()).getStripes();
mCheckboxes = new ArrayList<>();
if (mStripes != null) {
for (LedStripe ledStripe : mStripes) {
CheckBox nC = (CheckBox) View.inflate(getActivity(), R.layout.fragment_addprofile_item, null);
nC.setText(ledStripe.getName());
mCheckboxes.add(nC);
checkboxContainer.addView(nC);
}
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(v).setPositiveButton("Save", null).setNegativeButton("Cancel", null);
AlertDialog dialog = builder.create();
dialog.setOnShowListener(this);
return dialog;
}
@Override
public void onShow(final DialogInterface dialog) {
final AlertDialog alertDialog = (AlertDialog) dialog;
nameText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
nameLayout.setError(null);
}
});
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(v -> alertDialog.dismiss());
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
if (nameText.getText().toString().isEmpty()) {
nameLayout.setError("Please enter a name");
return;
}
int checked = 0;
for (CheckBox c : mCheckboxes) {
if (c.isChecked()) {
checked++;
mStripes.get(checkboxContainer.indexOfChild(c)).getColor();
}
}
if (checked < 2) {
Toast.makeText(getActivity(), "Please select at least two stripes for your profile", Toast.LENGTH_LONG).show();
return;
}
Profile profile = new Profile(nameText.getText().toString());
mCheckboxes.stream().filter(CompoundButton::isChecked).forEach(c -> {
LedStripe stripe = mStripes.get(checkboxContainer.indexOfChild(c));
profile.getValues().append(stripe.getId(), stripe.getColor());
});
((ColorActivity) getActivity()).addProfile(profile);
Toast.makeText(getActivity(), "Added profile " + nameText.getText().toString(), Toast.LENGTH_SHORT).show();
dismiss();
});
}
}

View File

@@ -23,8 +23,6 @@ import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
@@ -39,6 +37,8 @@ import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout;
import com.google.gson.Gson;
import com.idlegandalf.ledd.ColorActivity;
import com.idlegandalf.ledd.ColorApplication;
@@ -50,49 +50,45 @@ import com.idlegandalf.ledd.components.LedDDaemon;
import com.idlegandalf.ledd.components.LedStripe;
import com.idlegandalf.ledd.helper.LedDHelper;
import org.json.JSONException;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.List;
import butterknife.Bind;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class AddStripeDialog extends DialogFragment implements DialogInterface.OnShowListener {
public static AddStripeDialog instance;
@Bind(R.id.spinner_daemon)
@BindView(R.id.spinner_daemon)
Spinner daemonSpinner;
@Bind(R.id.spinner_controller)
@BindView(R.id.spinner_controller)
Spinner controllerSpinner;
@Bind(R.id.choose_controller_lay)
@BindView(R.id.choose_controller_lay)
RelativeLayout controllerLayout;
@Bind(R.id.input_stripe_name_lay)
@BindView(R.id.input_stripe_name_lay)
TextInputLayout stripeNameLay;
@Bind(R.id.input_stripe_name)
@BindView(R.id.input_stripe_name)
EditText stripeNameText;
@Bind(R.id.input_channel_r_lay)
@BindView(R.id.input_channel_r_lay)
TextInputLayout channelRLay;
@Bind(R.id.input_channel_r)
@BindView(R.id.input_channel_r)
EditText channelR;
@Bind(R.id.input_channel_g_lay)
@BindView(R.id.input_channel_g_lay)
TextInputLayout channelGLay;
@Bind(R.id.input_channel_g)
@BindView(R.id.input_channel_g)
EditText channelG;
@Bind(R.id.input_channel_b_lay)
@BindView(R.id.input_channel_b_lay)
TextInputLayout channelBLay;
@Bind(R.id.input_channel_b)
@BindView(R.id.input_channel_b)
EditText channelB;
@Bind(R.id.stripe_mapping_lay)
@BindView(R.id.stripe_mapping_lay)
LinearLayout stripeMapping;
@Bind(R.id.imgbuttn_togglechannel_r)
@BindView(R.id.imgbuttn_togglechannel_r)
ImageButton channelRBttn;
@Bind(R.id.imgbuttn_togglechannel_g)
@BindView(R.id.imgbuttn_togglechannel_g)
ImageButton channelGBttn;
@Bind(R.id.imgbuttn_togglechannel_b)
@BindView(R.id.imgbuttn_togglechannel_b)
ImageButton channelBBttn;
ArrayAdapter<LedDDaemon> daemonArrayAdapter;
ArrayAdapter<Controller> controllerArrayAdapter;
@@ -109,7 +105,6 @@ public class AddStripeDialog extends DialogFragment implements DialogInterface.O
public Dialog onCreateDialog(Bundle savedInstanceState) {
View v = View.inflate(getActivity(), R.layout.fragment_addstripe, null);
ButterKnife.bind(this, v);
instance = this;
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(v).setPositiveButton("Add", null).setNegativeButton("Cancel", null);
@@ -208,20 +203,17 @@ public class AddStripeDialog extends DialogFragment implements DialogInterface.O
}
});
ImageButton.OnClickListener imgListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.imgbuttn_togglechannel_r:
testChannel(channelR, (ImageButton) v);
break;
case R.id.imgbuttn_togglechannel_g:
testChannel(channelG, (ImageButton) v);
break;
case R.id.imgbuttn_togglechannel_b:
testChannel(channelB, (ImageButton) v);
break;
}
ImageButton.OnClickListener imgListener = v -> {
switch (v.getId()) {
case R.id.imgbuttn_togglechannel_r:
testChannel(channelR, (ImageButton) v);
break;
case R.id.imgbuttn_togglechannel_g:
testChannel(channelG, (ImageButton) v);
break;
case R.id.imgbuttn_togglechannel_b:
testChannel(channelB, (ImageButton) v);
break;
}
};
@@ -229,81 +221,53 @@ public class AddStripeDialog extends DialogFragment implements DialogInterface.O
channelGBttn.setOnClickListener(imgListener);
channelBBttn.setOnClickListener(imgListener);
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alertDialog.dismiss();
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(v -> alertDialog.dismiss());
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
if (!mDaemonSelected) {
Toast.makeText(getActivity(), "Please select Daemon and Controller", Toast.LENGTH_LONG).show();
return;
}
});
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!mDaemonSelected) {
Toast.makeText(getActivity(), "Please select Daemon and Controller", Toast.LENGTH_LONG).show();
return;
}
if (stripeNameText.getText().toString().isEmpty()) {
stripeNameLay.setError("Please set the Stripe name");
return;
}
if (stripeNameText.getText().toString().isEmpty()) {
stripeNameLay.setError("Please set the Stripe name");
return;
}
if (channelR.getText().toString().isEmpty() || channelG.getText().toString().isEmpty() || channelB.getText().toString().isEmpty()) {
Toast.makeText(getActivity(), "Please add mapping for all channels", Toast.LENGTH_LONG).show();
return;
}
if (channelR.getText().toString().isEmpty() || channelG.getText().toString().isEmpty() || channelB.getText().toString().isEmpty()) {
Toast.makeText(getActivity(), "Please add mapping for all channels", Toast.LENGTH_LONG).show();
return;
}
LedStripe stripe = new LedStripe(Integer.parseInt(channelR.getText().toString()), Integer.parseInt(channelG.getText().toString()),
Integer.parseInt(channelB.getText().toString()), stripeNameText.getText().toString());
stripe.setLedDDaemon((LedDDaemon) daemonSpinner.getSelectedItem());
stripe.setController((Controller) controllerSpinner.getSelectedItem());
LedStripe stripe = new LedStripe(Integer.parseInt(channelR.getText().toString()), Integer.parseInt(channelG.getText().toString()),
Integer.parseInt(channelB.getText().toString()), stripeNameText.getText().toString());
stripe.setLedDDaemon((LedDDaemon) daemonSpinner.getSelectedItem());
stripe.setController((Controller) controllerSpinner.getSelectedItem());
LedDHelper helper = ColorApplication.getInstance().getHelperForDaemon((LedDDaemon) daemonSpinner.getSelectedItem());
LedDHelper helper = null;
try {
helper = ColorApplication.getInstance().getHelperForDaemon((LedDDaemon) daemonSpinner.getSelectedItem());
} catch (IOException e) {
e.printStackTrace();
}
if (helper != null) {
helper.addStripe(stripe, new AddStripeCallback() {
@Override
public void onAddSuccessfully(final LedStripe stripe) {
ColorActivity activity = ((ColorActivity) getActivity());
activity.refreshStripes();
if (helper != null) {
try {
helper.addStripe(stripe, new AddStripeCallback() {
@Override
public void onAddSuccessfully(final LedStripe stripe) {
ColorActivity activity = ((ColorActivity) getActivity());
try {
activity.refreshStripes();
} catch (IOException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content))
.getChildAt(0), "Added stripe (" + stripe.getId() + ")", Snackbar.LENGTH_LONG).show();
}
});
dismiss();
}
@Override
public void onConnectionFailed(final String message) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content))
.getChildAt(0), "Failed to add stripe: " + message, Snackbar.LENGTH_LONG).show();
}
});
dismiss();
}
});
} catch (JSONException | IOException e) {
e.printStackTrace();
getActivity().runOnUiThread(() -> Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0), String.format(getActivity().getString(R.string.snackbar_added_stripe_id), stripe.getId()), Snackbar.LENGTH_LONG).show());
dismiss();
}
}
@Override
public void onAddFailed(int code, String msg) {
}
@Override
public void onConnectionFailed(final String message) {
getActivity().runOnUiThread(() -> Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0), getActivity().getString(R.string.snackbar_failed_add_stripe) + message, Snackbar.LENGTH_LONG).show());
dismiss();
}
});
}
});
@@ -371,14 +335,17 @@ public class AddStripeDialog extends DialogFragment implements DialogInterface.O
public void onResume() {
super.onResume();
ColorApplication.getInstance().onResume();
if (daemonArrayAdapter != null) {
daemonArrayAdapter.clear();
daemonArrayAdapter.addAll(ColorApplication.getInstance().getDaemons());
}
if (controllerArrayAdapter != null && mDaemonSelected) {
refreshController((LedDDaemon) daemonSpinner.getSelectedItem());
}
getActivity().runOnUiThread(() -> {
if (daemonArrayAdapter != null) {
daemonArrayAdapter.clear();
daemonArrayAdapter.addAll(ColorApplication.getInstance().getDaemons());
}
if (controllerArrayAdapter != null && mDaemonSelected) {
refreshController((LedDDaemon) daemonSpinner.getSelectedItem());
}
});
}
private void testChannel(EditText text, ImageButton button) {
@@ -398,19 +365,11 @@ public class AddStripeDialog extends DialogFragment implements DialogInterface.O
}
text.setTag(toggle);
LedDHelper helper = null;
try {
helper = ColorApplication.getInstance().getHelperForDaemon((LedDDaemon) daemonSpinner.getSelectedItem());
} catch (IOException e) {
e.printStackTrace();
}
LedDHelper helper = ColorApplication.getInstance().getHelperForDaemon((LedDDaemon) daemonSpinner.getSelectedItem());
if (helper != null) {
try {
helper.testChannel((Controller) controllerSpinner.getSelectedItem(), Integer.parseInt(text.getText().toString()), val);
} catch (JSONException e) {
e.printStackTrace();
}
helper.testChannel((Controller) controllerSpinner.getSelectedItem(), Integer.parseInt(text.getText().toString()), val);
}
}
}
@@ -418,40 +377,28 @@ public class AddStripeDialog extends DialogFragment implements DialogInterface.O
private void refreshController(final LedDDaemon ledDDaemon) {
controllerArrayAdapter.clear();
LedDHelper helper = null;
try {
helper = ColorApplication.getInstance().getHelperForDaemon(ledDDaemon);
} catch (IOException e) {
e.printStackTrace();
}
LedDHelper helper = ColorApplication.getInstance().getHelperForDaemon(ledDDaemon);
if (helper != null) {
try {
helper.getStripes(new StripesCallback() {
@Override
public void onSuccess(List<LedStripe> stripes) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
controllerArrayAdapter.addAll(ledDDaemon.getControllers());
toggleAll(stripeMapping, true);
}
});
}
helper.getStripes(new StripesCallback() {
@Override
public void onSuccess(List<LedStripe> stripes) {
getActivity().runOnUiThread(() -> {
controllerArrayAdapter.addAll(ledDDaemon.getControllers());
toggleAll(stripeMapping, true);
});
}
@Override
public void onGetFailed(String message) {
@Override
public void onGetFailed(int code, String message) {
}
}
@Override
public void onConnectionFailed(String message) {
@Override
public void onConnectionFailed(String message) {
}
});
} catch (JSONException | IOException e) {
e.printStackTrace();
}
}
});
}
}
}

View File

@@ -23,13 +23,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
import com.idlegandalf.ledd.ColorApplication;
import com.idlegandalf.ledd.callbacks.AddControllerCallback;
import com.idlegandalf.ledd.callbacks.AddStripeCallback;
import com.idlegandalf.ledd.callbacks.DiscoverCallback;
import com.idlegandalf.ledd.callbacks.RecieveColorCallback;
import com.idlegandalf.ledd.callbacks.ReceiveColorCallback;
import com.idlegandalf.ledd.callbacks.StripesCallback;
import com.idlegandalf.ledd.components.AnswerTask;
import com.idlegandalf.ledd.components.Controller;
@@ -38,22 +36,29 @@ import com.idlegandalf.ledd.components.LedDDaemon;
import com.idlegandalf.ledd.components.LedDRequest;
import com.idlegandalf.ledd.components.LedStripe;
import com.idlegandalf.ledd.services.ColorService;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Error;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
import timber.log.Timber;
public class LedDHelper {
final String ACTION_SETCOLOR = "set_color";
final String ACTION_GETCOLOR = "get_color";
final String ACTION_ADDCONTROLLER = "add_controller";
final String ACTION_GETALLSTRIPES = "get_stripes";
final String ACTION_ADDSTRIPES = "add_stripe";
final String ACTION_ADDSTRIPE = "add_stripe";
final String ACTION_TESTCHANNEL = "test_channel";
final String ACTION_DISCOVER = "discover";
private Context context;
@@ -65,7 +70,7 @@ public class LedDHelper {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
Log.d(ColorApplication.TAG, "ColorService bound!");
Timber.d("ColorService bound!");
requestWorker = new Worker<>(dRequests, (ColorService.ColorBinder) service, ledDDaemon);
mBound = true;
new Thread(requestWorker).start();
@@ -78,7 +83,7 @@ public class LedDHelper {
}
};
public LedDHelper(LedDDaemon ledDDaemon, Context appl) throws IOException {
public LedDHelper(LedDDaemon ledDDaemon, Context appl) {
this.context = appl;
this.dRequests = new LinkedBlockingQueue<>();
this.ledDDaemon = ledDDaemon;
@@ -91,34 +96,35 @@ public class LedDHelper {
* Add controller to ledd daemon
*
* @param c controller object
* @throws JSONException no valid json
* @throws IOException socket error
*/
public void addController(final Controller c, final AddControllerCallback callback) throws JSONException, IOException {
JSONObject jnson = new JSONObject();
public void addController(final Controller c, final AddControllerCallback callback) {
Map<String, Object> params = new HashMap<>();
jnson.put("action", ACTION_ADDCONTROLLER);
jnson.put("channels", c.getChannels());
jnson.put("i2c_dev", c.getI2c_device());
jnson.put("address", c.getAddress());
params.put("channels", c.getChannels());
params.put("i2c_dev", c.getI2c_device());
params.put("address", c.getAddress());
addRequestToQueue(jnson, new AnswerTask() {
JSONRPC2Request request = new JSONRPC2Request(ACTION_ADDCONTROLLER, params, UUID.randomUUID().toString());
addRequestToQueue(request, new AnswerTask() {
@Override
public void onConnectionFailed(String message) {
callback.onAddFailed(message, "");
callback.onConnectionFailed(message);
}
@Override
public void onResponse(JSONObject response) {
try {
if (response.getBoolean("success")) {
c.setId(response.getInt("cid"));
public void onResponse(JSONRPC2Response response) {
if (response.indicatesSuccess()) {
try {
JSONObject json = new JSONObject(response.getResult().toString());
c.setId(json.getInt("cid"));
callback.onControllerAdded(c);
} else {
callback.onAddFailed(response.getString("message"), response.getString("message_detail"));
} catch (JSONException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
} else {
@SuppressWarnings("ThrowableResultOfMethodCallIgnored") JSONRPC2Error error = response.getError();
callback.onAddFailed(error.getCode(), error.getMessage());
}
}
});
@@ -126,28 +132,22 @@ public class LedDHelper {
/**
* Get stripes known to daemon
*
* @throws JSONException no valid json
* @throws IOException socket error
*/
public void getStripes(final StripesCallback callback) throws JSONException, IOException {
JSONObject jnson = new JSONObject();
jnson.put("action", ACTION_GETALLSTRIPES);
addRequestToQueue(jnson, new AnswerTask() {
public void getStripes(final StripesCallback callback) {
addRequestToQueue(new JSONRPC2Request(ACTION_GETALLSTRIPES, UUID.randomUUID().toString()), new AnswerTask() {
@Override
public void onConnectionFailed(String message) {
callback.onGetFailed(message);
callback.onConnectionFailed(message);
}
@Override
public void onResponse(JSONObject response) {
public void onResponse(JSONRPC2Response response) {
try {
if (response.getBoolean("success")) {
if (response.indicatesSuccess()) {
ledDDaemon.getControllers().clear();
List<LedStripe> list = new ArrayList<>();
JSONArray jcontrollers = response.getJSONArray("controller");
JSONObject json = new JSONObject(response.getResult().toString());
JSONArray jcontrollers = json.getJSONArray("controller");
for (int i = 0; i < jcontrollers.length(); i++) {
JSONObject row = jcontrollers.getJSONObject(i);
@@ -178,8 +178,8 @@ public class LedDHelper {
callback.onSuccess(list);
} else {
if (response.has("message")) callback.onGetFailed(response.getString("message"));
else callback.onGetFailed("unknown error");
@SuppressWarnings("ThrowableResultOfMethodCallIgnored") JSONRPC2Error error = response.getError();
callback.onGetFailed(error.getCode(), error.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
@@ -194,59 +194,56 @@ public class LedDHelper {
* @param ledStripe Stripe
*/
public void setColor(LedStripe ledStripe) {
Map<String, Object> hsv = new HashMap<>();
JSONObject jnson = new JSONObject();
JSONObject hsv = new JSONObject();
hsv.put("h", ledStripe.getColor().getHue());
hsv.put("s", ledStripe.getColor().getSaturation());
hsv.put("v", ledStripe.getColor().getValue());
try {
hsv.put("h", ledStripe.getColor().getHue());
hsv.put("s", ledStripe.getColor().getSaturation());
hsv.put("v", ledStripe.getColor().getValue());
Map<String, Object> params = new HashMap<>();
params.put("sid", ledStripe.getId());
params.put("hsv", hsv);
jnson.put("action", ACTION_SETCOLOR);
jnson.put("sid", ledStripe.getId());
jnson.put("hsv", hsv);
JSONRPC2Request request = new JSONRPC2Request(ACTION_SETCOLOR, params, UUID.randomUUID().toString());
} catch (JSONException e) {
e.printStackTrace();
}
addRequestToQueue(jnson, null);
addRequestToQueue(request, null);
}
/**
* Get color using the stripeid
*
* @param ledStripe Stripe
* @throws JSONException no valid json
* @throws IOException socket error
*/
public void getColor(final LedStripe ledStripe, final RecieveColorCallback callback) throws JSONException, IOException {
JSONObject jnson = new JSONObject();
public void getColor(final LedStripe ledStripe, final ReceiveColorCallback callback) {
HashMap<String, Object> params = new HashMap<>();
params.put("sid", ledStripe.getId());
jnson.put("action", ACTION_GETCOLOR);
jnson.put("sid", ledStripe.getId());
addRequestToQueue(jnson, new AnswerTask() {
addRequestToQueue(new JSONRPC2Request(ACTION_GETCOLOR, params, UUID.randomUUID().toString()), new AnswerTask() {
@Override
public void onConnectionFailed(String message) {
callback.onRecievFailed(message);
callback.onConnectionFailed(message);
}
@Override
public void onResponse(JSONObject response) {
try {
if (response.getBoolean("success")) {
JSONArray hsv = response.getJSONArray("color");
ledStripe.setColor(new HSV(hsv.getDouble(0), hsv.getDouble(1), hsv.getDouble(2)));
callback.onColorRecieved(ledStripe);
} else {
callback.onRecievFailed(response.getString("message"));
public void onResponse(JSONRPC2Response response) {
if (response.indicatesSuccess()) {
try {
JSONObject json = new JSONObject(response.getResult().toString());
JSONArray hsv = json.getJSONArray("color");
if (hsv.length() == 3) {
ledStripe.setColor(new HSV(hsv.getDouble(0), hsv.getDouble(1), hsv.getDouble(2)));
callback.onColorReceived(ledStripe);
} else {
callback.onReceiveFailed(-1, "HSV was empty");
}
} catch (JSONException e) {
e.printStackTrace();
callback.onReceiveFailed(-1, "Unhandeled JSON Exception");
}
} catch (Exception e) {
e.printStackTrace();
} else {
@SuppressWarnings("ThrowableResultOfMethodCallIgnored") JSONRPC2Error error = response.getError();
callback.onReceiveFailed(error.getCode(), error.getMessage());
}
}
});
@@ -258,24 +255,22 @@ public class LedDHelper {
* @param c controller
* @param channel channel number
* @param value value (1= on, 0 = off)
* @throws JSONException
*/
public void testChannel(Controller c, int channel, int value) throws JSONException {
JSONObject jnson = new JSONObject();
public void testChannel(Controller c, int channel, int value) {
HashMap<String, Object> params = new HashMap<>();
jnson.put("action", ACTION_TESTCHANNEL);
jnson.put("cid", c.getId());
jnson.put("channel", channel);
jnson.put("value", value);
params.put("cid", c.getId());
params.put("channel", channel);
params.put("value", value);
addRequestToQueue(jnson, new AnswerTask() {
addRequestToQueue(new JSONRPC2Request(ACTION_TESTCHANNEL, params, UUID.randomUUID().toString()), new AnswerTask() {
@Override
public void onConnectionFailed(String message) {
}
@Override
public void onResponse(JSONObject response) {
public void onResponse(JSONRPC2Response response) {
}
});
@@ -283,26 +278,20 @@ public class LedDHelper {
/**
* Get information about an ledd daemon
*
* @throws JSONException no valid json
* @throws IOException socket error
*/
public void discover(final DiscoverCallback callback) throws JSONException, IOException {
JSONObject jnson = new JSONObject();
jnson.put("action", ACTION_DISCOVER);
addRequestToQueue(jnson, new AnswerTask() {
public void discover(final DiscoverCallback callback) {
addRequestToQueue(new JSONRPC2Request(ACTION_DISCOVER, UUID.randomUUID().toString()), new AnswerTask() {
@Override
public void onConnectionFailed(String message) {
callback.onConnectionFailed(message);
}
@Override
public void onResponse(JSONObject response) {
public void onResponse(JSONRPC2Response response) {
try {
if (response.getBoolean("success")) {
callback.onDiscoverSuccessfully(response.getString("version"));
if (response.indicatesSuccess()) {
JSONObject json = new JSONObject(response.getResult().toString());
callback.onDiscoverSuccessfully(json.getString("version"));
}
} catch (Exception e) {
e.printStackTrace();
@@ -313,39 +302,36 @@ public class LedDHelper {
/**
* Get information about an ledd daemon
*
* @throws JSONException no valid json
* @throws IOException socket error
*/
public void addStripe(final LedStripe ledStripe, final AddStripeCallback callback) throws JSONException, IOException {
JSONObject jnson = new JSONObject();
public void addStripe(final LedStripe ledStripe, final AddStripeCallback callback) {
HashMap<String, Object> params = new HashMap<>();
HashMap<String, Object> mapping = new HashMap<>();
jnson.put("action", ACTION_ADDSTRIPES);
JSONObject stripe = new JSONObject();
params.put("name", ledStripe.getName());
params.put("rgb", ledStripe.isRGB());
stripe.put("name", ledStripe.getName());
stripe.put("rgb", ledStripe.isRGB());
JSONObject mapping = new JSONObject();
mapping.put("r", ledStripe.getChannelRed());
mapping.put("g", ledStripe.getChannelGreen());
mapping.put("b", ledStripe.getChannelBlue());
stripe.put("map", mapping);
stripe.put("cid", ledStripe.getController().getId());
jnson.put("stripe", stripe);
params.put("map", mapping);
params.put("cid", ledStripe.getController().getId());
addRequestToQueue(jnson, new AnswerTask() {
addRequestToQueue(new JSONRPC2Request(ACTION_ADDSTRIPE, params, UUID.randomUUID().toString()), new AnswerTask() {
@Override
public void onConnectionFailed(String message) {
callback.onConnectionFailed(message);
}
@Override
public void onResponse(JSONObject response) {
public void onResponse(JSONRPC2Response response) {
try {
if (response.getBoolean("success")) {
ledStripe.setId(response.getInt("sid"));
if (response.indicatesSuccess()) {
JSONObject json = new JSONObject(response.getResult().toString());
ledStripe.setId(json.getInt("sid"));
callback.onAddSuccessfully(ledStripe);
} else {
@SuppressWarnings("ThrowableResultOfMethodCallIgnored") JSONRPC2Error error = response.getError();
callback.onAddFailed(error.getCode(), error.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
@@ -354,8 +340,8 @@ public class LedDHelper {
});
}
private void addRequestToQueue(JSONObject json, AnswerTask task) {
dRequests.add(new LedDRequest(json, task));
private void addRequestToQueue(JSONRPC2Request request, AnswerTask task) {
if (request != null) dRequests.add(new LedDRequest(request, task));
}
public void teardown() {
@@ -389,8 +375,6 @@ public class LedDHelper {
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
} catch (JSONException e) {
e.printStackTrace();
}
}
}

View File

@@ -31,11 +31,12 @@ import com.koushikdutta.async.AsyncSocket;
import com.koushikdutta.async.ByteBufferList;
import com.koushikdutta.async.DataEmitter;
import com.koushikdutta.async.Util;
import com.koushikdutta.async.callback.ConnectCallback;
import com.koushikdutta.async.callback.DataCallback;
import com.thetransactioncompany.jsonrpc2.JSONRPC2ParseException;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
@@ -53,7 +54,7 @@ public class ColorService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return -1;
return Service.START_STICKY;
}
@Override
@@ -65,11 +66,6 @@ public class ColorService extends Service {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
worker.stop();
@@ -85,24 +81,24 @@ public class ColorService extends Service {
DataCallback dataCallback = new DataCallback() {
@Override
public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
JSONObject resp = null;
try {
resp = new JSONObject(new String(bb.getAllByteArray()));
} catch (JSONException e) {
e.printStackTrace();
JSONRPC2Response reqIn = null;
String dataStr = new String(bb.getAllByteArray());
if (!dataStr.isEmpty()) {
try {
reqIn = JSONRPC2Response.parse(dataStr);
} catch (JSONRPC2ParseException e) {
e.printStackTrace();
}
}
if (resp != null) {
try {
if (sendableHashMap.containsKey(resp.getString("ref"))) {
sendableHashMap.get(resp.getString("ref")).onResponse(resp);
sendableHashMap.remove(resp.getString("ref"));
if (timeoutHashMap.containsKey(resp.getString("ref")) && timeoutHashMap.get(resp.getString("ref")) != null)
timeoutHashMap.get(resp.getString("ref")).cancel(false);
timeoutHashMap.remove(resp.getString("ref"));
}
} catch (JSONException e) {
e.printStackTrace();
if (reqIn != null) {
if (sendableHashMap.containsKey(reqIn.getID().toString())) {
sendableHashMap.get(reqIn.getID().toString()).onResponse(reqIn);
sendableHashMap.remove(reqIn.getID().toString());
if (timeoutHashMap.containsKey(reqIn.getID().toString()) && timeoutHashMap.get(reqIn.getID().toString()) != null)
timeoutHashMap.get(reqIn.getID().toString()).cancel(false);
timeoutHashMap.remove(reqIn.getID().toString());
}
}
}
@@ -122,39 +118,43 @@ public class ColorService extends Service {
final T item = workQueue.take();
if (item instanceof Sendable) {
if (socketHashMap.containsKey(((Sendable) item).getRecipient()) && socketHashMap.get(((Sendable) item).getRecipient())
.getServer().isRunning()) {
final Sendable sendable = (Sendable) item;
if (socketHashMap.containsKey(sendable.getRecipient())) {
if (socketHashMap.get(sendable.getRecipient()) == null) {
// if server is not running yet, readd item to queue
workQueue.add(item);
continue;
} else if (!socketHashMap.get(sendable.getRecipient()).getServer().isRunning()) {
// connection probably closed or was interrupted -> reconnect
socketHashMap.remove(sendable.getRecipient());
workQueue.add(item);
continue;
}
Util.writeAll(socketHashMap.get(((Sendable) item).getRecipient()), (((Sendable) item).getMessage().toString() + "\n")
.getBytes
("UTF-8"), null);
sendableHashMap.put(((Sendable) item).getRef(), (Sendable) item);
Util.writeAll(socketHashMap.get(sendable.getRecipient()), (sendable.getRequest().toString() + "\n").getBytes("UTF-8"),
null);
sendableHashMap.put((String) sendable.getRequest().getID(), sendable);
if (!poolExecutor.isTerminating() && !poolExecutor.isTerminated())
timeoutHashMap.put(((Sendable) item).getRef(), poolExecutor.schedule(new Runnable() {
@Override
public void run() {
((Sendable) item).onNoResponse();
timeoutHashMap.remove(((Sendable) item).getRef());
sendableHashMap.remove(((Sendable) item).getRef());
}
timeoutHashMap.put((String) sendable.getRequest().getID(), poolExecutor.schedule(() -> {
sendable.onNoResponse();
timeoutHashMap.remove(sendable.getRequest().getID());
sendableHashMap.remove(sendable.getRequest().getID());
}, 1000, TimeUnit.MILLISECONDS));
} else {
AsyncServer.getDefault().connectSocket(new InetSocketAddress(((Sendable) item).getRecipient().getAddress(), ((Sendable)
item).getRecipient().getPort()), new ConnectCallback() {
@Override
public void onConnectCompleted(Exception ex, final AsyncSocket socket) {
if (ex == null) {
socket.setDataCallback(dataCallback);
socketHashMap.put(sendable.getRecipient(), null);
AsyncServer.getDefault().connectSocket(new InetSocketAddress(sendable.getRecipient().getAddress(), sendable
.getRecipient().getPort()), (ex, socket) -> {
if (ex == null) {
socket.setDataCallback(dataCallback);
socketHashMap.put(((Sendable) item).getRecipient(), socket);
socketHashMap.put(sendable.getRecipient(), socket);
//if (!workQueue.contains(item)) -> needs equals implementaion
workQueue.add(item);
} else {
((Sendable) item).onConnectionFailed(ex.getMessage());
}
}
});
//if (!workQueue.contains(item)) -> needs equals implementation
workQueue.add(item);
} else {
sendable.onConnectionFailed(ex.getMessage());
}
});
}
}
} catch (InterruptedException ex) {
@@ -172,10 +172,16 @@ public class ColorService extends Service {
}
public class ColorBinder extends Binder {
public String queueSend(LedDDaemon rec, JSONObject msg, AnswerTask answerTask) throws JSONException {
Sendable sendable = new Sendable(msg, answerTask, rec);
queue.add(sendable);
return sendable.getRef();
public void queueSend(LedDDaemon rec, JSONRPC2Request request, AnswerTask answerTask) {
Sendable sendable = null;
try {
sendable = new Sendable(request, answerTask, rec);
} catch (JSONException e) {
e.printStackTrace();
}
if (sendable != null) {
queue.add(sendable);
}
}
}
}

View File

@@ -0,0 +1,51 @@
/*
* LEDD Project
* Copyright (C) 2015 LEDD Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.idlegandalf.ledd.utils;
public class RateLimiter {
private double rate;
private double per;
private double allowance;
private long last_check;
public RateLimiter(double rate, double per) {
this.rate = rate;
this.per = per;
this.allowance = rate;
this.last_check = System.currentTimeMillis();
}
public boolean check() {
long current = System.currentTimeMillis();
long time_passed = current - last_check;
last_check = current;
allowance += time_passed * (rate / per);
if (allowance > rate) {
allowance = rate; // throttle
}
if (allowance < 1.0) {
return false;
} else {
allowance -= 1.0;
return true;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 638 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

View File

@@ -1,23 +0,0 @@
<!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<FrameLayout
android:id="@+id/fragmentContainer"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View File

@@ -16,52 +16,26 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:orientation="vertical">
<!-- The main content view -->
<Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?android:attr/actionBarSize"
android:titleTextColor="@android:color/black" />
<LinearLayout
<com.github.madrapps.HSLColorPicker
android:id="@+id/picker"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="25dp" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?android:attr/actionBarSize"/>
<com.larswerkman.holocolorpicker.ColorPicker
android:id="@+id/picker"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="25dp"/>
<com.larswerkman.holocolorpicker.SVBar
android:id="@+id/svbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"/>
</LinearLayout>
<!-- The navigation drawer -->
<android.support.design.widget.NavigationView
android:id="@+id/drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/navigation_header"
app:menu="@menu/navigation_drawer"/>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>

View File

@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
@@ -18,15 +17,16 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:minWidth="350dp"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:minWidth="350dp"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingTop="15dp"
android:paddingRight="15dp">
<RelativeLayout
android:layout_width="wrap_content"
@@ -36,68 +36,68 @@
android:id="@+id/img_host"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="@drawable/ic_developer_board_black_48dp"/>
android:src="@drawable/ic_developer_board_black_48dp"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/img_host"
android:layout_alignTop="@id/img_host"
android:layout_marginLeft="7dp"
android:layout_toRightOf="@id/img_host"
android:layout_alignBottom="@id/img_host"
android:layout_marginStart="7dp"
android:layout_toEndOf="@id/img_host"
android:gravity="center"
android:text="Add Controller"
android:textAppearance="?android:textAppearanceMedium"
/>
android:text="@string/text_add_controller"
android:textAppearance="?android:textAppearanceMedium" />
</RelativeLayout>
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_i2c_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
app:errorEnabled="true">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_i2c"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="i2c device number"
android:hint="@string/hint_i2c_device"
android:inputType="number"
android:minWidth="350dp"/>
android:minWidth="350dp" />
</android.support.design.widget.TextInputLayout>
</com.google.android.material.textfield.TextInputLayout>
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_address_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:errorEnabled="true">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_address"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="controller address in hex format"
android:minWidth="350dp"/>
android:hint="@string/hint_controller_address"
android:minWidth="350dp" />
</android.support.design.widget.TextInputLayout>
</com.google.android.material.textfield.TextInputLayout>
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_channel_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:errorEnabled="true">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_channel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="channels"
android:hint="@string/hint_channels"
android:inputType="number"
android:minWidth="350dp"/>
android:minWidth="350dp" />
</android.support.design.widget.TextInputLayout>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>

View File

@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
@@ -18,15 +17,16 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:minWidth="250dp"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:minWidth="250dp"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp">
<RelativeLayout
android:layout_width="wrap_content"
@@ -36,27 +36,29 @@
android:id="@+id/img_host"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="@drawable/ic_computer_black_48dp"/>
android:src="@drawable/ic_computer_black_48dp"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/img_host"
android:layout_alignTop="@id/img_host"
android:layout_marginLeft="7dp"
android:layout_toRightOf="@id/img_host"
android:gravity="center"
android:text="Choose Daemon"
android:textAppearance="?android:textAppearanceMedium"
/>
android:layout_marginStart="7dp"
android:layout_toEndOf="@id/img_host"
android:layout_toStartOf="@id/progress_daemon"
android:gravity="start|center_vertical"
android:text="@string/text_choose_daemon"
android:textAppearance="?android:textAppearanceMedium" />
<ProgressBar
android:id="@+id/progress_daemon"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp"
android:indeterminate="true"/>
android:layout_marginStart="5dp"
android:indeterminate="true" />
</RelativeLayout>
@@ -70,7 +72,7 @@
android:id="@+id/host_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"/>
android:orientation="vertical" />
</ScrollView>
@@ -80,21 +82,21 @@
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:gravity="center_horizontal"
android:text="or"
android:textAppearance="?android:textAppearanceMedium"/>
android:text="@string/text_or"
android:textAppearance="?android:textAppearanceMedium" />
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_ip_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_ip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="ip address[:port]"
android:minWidth="250dp"/>
android:hint="@string/hint_daemon_ip_port"
android:minWidth="250dp" />
</android.support.design.widget.TextInputLayout>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:minWidth="350dp"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/img_host"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="@drawable/ic_save_black_48dp"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/img_host"
android:layout_alignTop="@id/img_host"
android:layout_marginStart="7dp"
android:layout_toEndOf="@id/img_host"
android:gravity="center"
android:text="@string/add_profile"
android:textAppearance="?android:textAppearanceMedium" />
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/choose_stripes_to_include" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp">
<LinearLayout
android:id="@+id/container_linlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_profile_name_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_profile_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/profile_name"
android:inputType="text"
android:minWidth="350dp" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp" />

View File

@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
@@ -18,15 +17,16 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:minWidth="250dp"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:minWidth="250dp"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp">
<RelativeLayout
android:layout_width="wrap_content"
@@ -36,19 +36,19 @@
android:id="@+id/img_host"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/ic_computer_black_48dp"/>
android:src="@drawable/ic_computer_black_48dp"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/img_host"
android:layout_alignTop="@id/img_host"
android:layout_marginLeft="7dp"
android:layout_toRightOf="@id/img_host"
android:layout_marginStart="7dp"
android:layout_toEndOf="@id/img_host"
android:gravity="center"
android:text="Choose Daemon"
android:textAppearance="?android:textAppearanceSmall"
/>
android:text="@string/text_choose_daemon"
android:textAppearance="?android:textAppearanceSmall" />
</RelativeLayout>
@@ -62,20 +62,21 @@
android:id="@+id/imgbuttn_adddaemon"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/ic_add_circle_black_48dp"/>
android:src="@drawable/ic_add_circle_black_48dp"
tools:ignore="ContentDescription" />
<Spinner
android:id="@+id/spinner_daemon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_toLeftOf="@id/imgbuttn_adddaemon"/>
android:layout_toStartOf="@id/imgbuttn_adddaemon" />
</RelativeLayout>
@@ -89,19 +90,19 @@
android:id="@+id/img_controller"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/ic_developer_board_black_48dp"/>
android:src="@drawable/ic_developer_board_black_48dp"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/img_controller"
android:layout_alignTop="@id/img_controller"
android:layout_marginLeft="7dp"
android:layout_toRightOf="@id/img_controller"
android:layout_marginStart="7dp"
android:layout_toEndOf="@id/img_controller"
android:gravity="center"
android:text="Choose Controller"
android:textAppearance="?android:textAppearanceSmall"
/>
android:text="@string/text_choose_controller"
android:textAppearance="?android:textAppearanceSmall" />
</RelativeLayout>
@@ -115,20 +116,21 @@
android:id="@+id/imgbuttn_addcontroller"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/ic_add_circle_black_48dp"/>
android:src="@drawable/ic_add_circle_black_48dp"
tools:ignore="ContentDescription" />
<Spinner
android:id="@+id/spinner_controller"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_toLeftOf="@id/imgbuttn_addcontroller"/>
android:layout_toStartOf="@id/imgbuttn_addcontroller" />
</RelativeLayout>
@@ -141,53 +143,52 @@
android:id="@+id/img_stripe"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/ic_wb_iridescent_black_48dp"/>
android:src="@drawable/ic_wb_iridescent_black_48dp"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/img_stripe"
android:layout_alignTop="@id/img_stripe"
android:layout_marginLeft="7dp"
android:layout_toRightOf="@id/img_stripe"
android:layout_marginStart="7dp"
android:layout_toEndOf="@id/img_stripe"
android:gravity="center"
android:text="Stripe Properties"
android:textAppearance="?android:textAppearanceSmall"
/>
android:text="@string/text_stripe_properties"
android:textAppearance="?android:textAppearanceSmall" />
</RelativeLayout>
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_stripe_name_lay"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
app:errorEnabled="true">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_stripe_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Stripe name"
android:hint="@string/hint_stripe_name"
android:inputType="text"
android:minEms="12"/>
</android.support.design.widget.TextInputLayout>
android:minEms="12" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="9dp"
android:layout_marginStart="9dp"
android:layout_marginTop="15dp"
android:gravity="center"
android:text="Channel Mapping"
android:textAppearance="?android:textAppearanceSmall"
/>
android:text="@string/text_channel_mapping"
android:textAppearance="?android:textAppearanceSmall" />
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp">
<LinearLayout
@@ -196,79 +197,82 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_channel_r_lay"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_channel_r"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="2"
android:hint="R"
android:inputType="number"/>
</android.support.design.widget.TextInputLayout>
android:hint="@string/hint_channel_r"
android:inputType="number" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/imgbuttn_togglechannel_r"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/ic_visibility_off_black_48dp"/>
android:src="@drawable/ic_visibility_off_black_48dp"
tools:ignore="ContentDescription" />
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_channel_g_lay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp">
android:layout_marginStart="10dp">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_channel_g"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="2"
android:hint="G"
android:inputType="number"/>
</android.support.design.widget.TextInputLayout>
android:hint="@string/hint_channel_g"
android:inputType="number" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/imgbuttn_togglechannel_g"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/ic_visibility_off_black_48dp"/>
android:src="@drawable/ic_visibility_off_black_48dp"
tools:ignore="ContentDescription" />
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_channel_b_lay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp">
android:layout_marginStart="10dp">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_channel_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="2"
android:hint="B"
android:inputType="number"/>
</android.support.design.widget.TextInputLayout>
android:hint="@string/hint_channel_b"
android:inputType="number" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/imgbuttn_togglechannel_b"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/ic_visibility_off_black_48dp"/>
android:src="@drawable/ic_visibility_off_black_48dp"
tools:ignore="ContentDescription" />
</LinearLayout>
</HorizontalScrollView>

View File

@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
@@ -18,31 +17,36 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingLeft="7dp">
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingStart="7dp"
android:focusable="true"
tools:ignore="RtlSymmetry">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/ic_developer_board_black_48dp"/>
android:src="@drawable/ic_developer_board_black_48dp"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/text_host"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:gravity="center_vertical"
android:text="textHost"
android:text=""
android:textAppearance="?android:textAppearanceMedium"
android:textColor="@color/primaryColorDark"/>
android:textColor="@color/primaryColorDark"
android:focusable="true" />
</LinearLayout>

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="192dp"
android:background="?attr/colorPrimaryDark"
android:gravity="bottom"
android:orientation="vertical"
android:padding="16dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="-- stripes infos go here --"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
</LinearLayout>

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/activity_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-8dp" />
<FrameLayout
android:id="@+id/activity_frame"
android:layout_width="match_parent"
android:layout_height="fill_parent" />
</LinearLayout>

View File

@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
@@ -17,12 +16,11 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<CheckedTextView
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@android:color/black"/>
android:textColor="@android:color/black" />

View File

@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
@@ -17,13 +16,12 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<TextView
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:singleLine="true"
android:textAlignment="inherit"
android:textColor="@android:color/black"/>
android:textColor="@android:color/black" />

View File

@@ -17,6 +17,4 @@
-->
<menu>
</menu>

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nv_add_stripe"
android:icon="@drawable/ic_add_circle_black_48dp"
android:orderInCategory="51"
android:title="Add Stripe"/>
<item
android:id="@+id/nv_settings"
android:icon="@drawable/ic_tune_black_48dp"
android:orderInCategory="52"
android:title="Settings"/>
</menu>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,29 +0,0 @@
<!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<!--
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
-->
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- API 11 theme customizations can go here. -->
</style>
</resources>

View File

@@ -1,30 +0,0 @@
<!--
~ LEDD Project
~ Copyright (C) 2015 LEDD Team
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<!--
Base application theme for API 14+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- API 14 theme customizations can go here. -->
</style>
</resources>

View File

@@ -22,7 +22,7 @@
Base application theme for API 19+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 19+ devices.
-->
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
<style name="AppBaseTheme" parent="MaterialDrawerTheme.Light.DarkToolbar.TranslucentStatus">
<!-- API 19 theme customizations can go here. -->
<item name="android:windowTranslucentStatus">true</item>
</style>

Some files were not shown because too many files have changed in this diff Show More