diff --git a/app/build.gradle b/app/build.gradle
index f38315c..b618601 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,3 +1,21 @@
+/*
+ * 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 .
+ */
+
buildscript {
repositories {
mavenCentral()
@@ -16,11 +34,11 @@ apply plugin: 'com.github.ben-manes.versions'
android {
compileSdkVersion 23
- buildToolsVersion '23.0.0'
+ buildToolsVersion '23.0.1'
defaultConfig {
applicationId "com.idlegandalf.ledd"
- minSdkVersion 16
+ minSdkVersion 17
targetSdkVersion 23
versionCode 1
versionName "1.0"
@@ -35,13 +53,14 @@ android {
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
- compile 'com.android.support:appcompat-v7:23.0.0'
- compile 'com.android.support:support-v4:23.0.0'
+ 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.0'
- compile 'com.rarepebble:colorpicker:1.3.0'
+ 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'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cecd32c..d1ad057 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -21,23 +21,26 @@
package="com.idlegandalf.ledd"
xmlns:android="http://schemas.android.com/apk/res/android">
-
-
-
+
+
+
-
+
+
-
+
@@ -49,7 +52,7 @@
+ android:value="com.idlegandalf.ledd.ColorActivity"/>
diff --git a/app/src/main/java/com/idlegandalf/ledd/ColorActivity.java b/app/src/main/java/com/idlegandalf/ledd/ColorActivity.java
index 70dadb6..6e4e85c 100644
--- a/app/src/main/java/com/idlegandalf/ledd/ColorActivity.java
+++ b/app/src/main/java/com/idlegandalf/ledd/ColorActivity.java
@@ -18,11 +18,17 @@
package com.idlegandalf.ledd;
+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;
@@ -31,27 +37,44 @@ import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.SubMenu;
import android.view.View;
-import com.idlegandalf.ledd.components.RGBStripe;
-import com.idlegandalf.ledd.components.StripeGroup;
+import com.idlegandalf.ledd.callbacks.RecieveColorCallback;
+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.fragments.AddStripeDialog;
import com.idlegandalf.ledd.helper.LedDHelper;
+import com.larswerkman.holocolorpicker.ColorPicker;
+import com.larswerkman.holocolorpicker.SVBar;
+
+import org.json.JSONException;
+
+import java.io.IOException;
+import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
-import hugo.weaving.DebugLog;
-public class ColorActivity extends AppCompatActivity {
+public class ColorActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
@Bind(R.id.drawer_layout)
DrawerLayout mDrawerLayout;
@Bind(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;
- private LedDHelper mAPI;
- private RGBStripe mActiveStripe;
- private StripeGroup mActiveGroup;
- private boolean firstRun = false;
+ private refreshDaemonsListener daemonsListener;
+ private List ledStripes;
+ private LedStripe mCurrentStripe;
+ private LedDHelper mCurrentHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -63,11 +86,27 @@ public class ColorActivity extends AppCompatActivity {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isConnected()) {
- // TODO: Display error
+ // TODO: Display error (snackbar)
}
+ colorPicker.addSVBar(svBar);
+ colorPicker.setShowOldCenterColor(false);
+
+ colorPicker.setOnColorChangedListener(new ColorPicker.OnColorChangedListener() {
+ @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);
+ }
+ }
+ });
+
+ navigationView.setNavigationItemSelectedListener(this);
setSupportActionBar(toolbar);
- toolbar.setTitle("LedD");
+ toolbar.setTitle(R.string.app_name);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.app_name, R.string.app_name) {
@@ -90,12 +129,16 @@ public class ColorActivity extends AppCompatActivity {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
+
+ daemonsListener = new refreshDaemonsListener();
+ registerReceiver(daemonsListener, new IntentFilter(ColorApplication.INTENT_ACTION_REFRESH));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.color, menu);
+
return true;
}
@@ -139,17 +182,173 @@ public class ColorActivity extends AppCompatActivity {
return super.onKeyDown(keyCode, event);
}
- @DebugLog
@Override
protected void onPause() {
super.onPause();
ColorApplication.getInstance().teardown();
+ unregisterReceiver(daemonsListener);
}
- @DebugLog
@Override
protected void onDestroy() {
super.onDestroy();
ColorApplication.getInstance().teardown();
}
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ ColorApplication.getInstance().onResume();
+ registerReceiver(daemonsListener, new IntentFilter(ColorApplication.INTENT_ACTION_REFRESH));
+ try {
+ refreshStripes();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean onNavigationItemSelected(MenuItem menuItem) {
+ int id = menuItem.getItemId();
+
+ 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;
+ }
+ }
+
+ return false;
+ }
+
+ public void refreshStripes() throws IOException {
+ reCreateNavigationView(); // need to recreate the navigationview since we can't remove a once added submenu
+
+ final Menu nvMenu = navigationView.getMenu();
+ final int stripeGroup = 42;
+
+ 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 stripes) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ SubMenu nDaemonMenu = nvMenu.addSubMenu(Menu.NONE, Menu.NONE, finalI, dDaemon.toString());
+ nDaemonMenu.setGroupCheckable(stripeGroup, true, true);
+
+ 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 onGetFailed(String message) {
+ Snackbar.make(findViewById(android.R.id.content), "Coudn't get stripes from daemon: " + 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++;
+ }
+ }
+
+ private void reCreateNavigationView() {
+ runOnUiThread(new Runnable() {
+ @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();
+ }
+ });
+ }
+
+ 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();
+ }
+ }
+ }
+ }
}
diff --git a/app/src/main/java/com/idlegandalf/ledd/ColorApplication.java b/app/src/main/java/com/idlegandalf/ledd/ColorApplication.java
index 881b8d3..49eeb58 100644
--- a/app/src/main/java/com/idlegandalf/ledd/ColorApplication.java
+++ b/app/src/main/java/com/idlegandalf/ledd/ColorApplication.java
@@ -19,22 +19,29 @@
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;
-import com.idlegandalf.ledd.components.Host;
+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 hugo.weaving.DebugLog;
-
public class ColorApplication extends Application {
+ public static final String TAG = "LedD";
+ public static final String INTENT_ACTION_REFRESH = "com.idlegandalf.ledd.action.refreshStripes";
private static ColorApplication singleton;
- private HashMap ledDHelpers;
+ private HashMap ledDHelpers;
public static ColorApplication getInstance() {
return singleton;
@@ -46,41 +53,87 @@ public class ColorApplication extends Application {
singleton = this;
ledDHelpers = new HashMap<>();
-
- if (PreferenceManager.getDefaultSharedPreferences(this).contains("hosts")) {
- Set hosts = new Gson().fromJson(PreferenceManager.getDefaultSharedPreferences(this).getString("hosts", ""), new
- TypeToken>() {
- }.getType());
-
- for (Host host : hosts) {
- try {
- ledDHelpers.put(host, new LedDHelper(host, getApplicationContext()));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- System.out.println("len of hashmap: " + ledDHelpers.size());
+ this.onResume();
}
- public LedDHelper getHelperForHost(Host host) throws IOException {
- System.out.println("host: " + host.toString());
- if (ledDHelpers.containsKey(host)) {
- return ledDHelpers.get(host);
+ public LedDHelper getHelperForDaemon(final LedDDaemon ledDDaemon) throws IOException {
+ if (ledDHelpers.containsKey(ledDDaemon) && ledDHelpers.get(ledDDaemon) != null) {
+ return ledDHelpers.get(ledDDaemon);
} else {
- LedDHelper dHelper = new LedDHelper(host, getApplicationContext());
- ledDHelpers.put(host, dHelper);
+ 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();
+ }
+
+
return dHelper;
}
}
- @DebugLog
+ public List getDaemons() {
+ ArrayList ledDDaemons = new ArrayList<>();
+ ledDDaemons.addAll(ledDHelpers.keySet());
+
+ return ledDDaemons;
+ }
+
public void teardown() {
for (LedDHelper dHelper : ledDHelpers.values()) {
dHelper.teardown();
}
- PreferenceManager.getDefaultSharedPreferences(this).edit().putString("hosts", new Gson().toJson(ledDHelpers.keySet())).commit();
+ PreferenceManager.getDefaultSharedPreferences(this).edit().putString("daemons", new Gson().toJson(ledDHelpers.keySet())).commit();
+ }
+
+ public void onResume() {
+ if (PreferenceManager.getDefaultSharedPreferences(this).contains("daemons")) {
+ Set ledDDaemons = new Gson().fromJson(PreferenceManager.getDefaultSharedPreferences(this).getString("daemons", ""), new
+ TypeToken>() {
+ }.getType());
+
+ for (final LedDDaemon ledDDaemon : ledDDaemons) {
+ try {
+ final LedDHelper helper = new LedDHelper(ledDDaemon, getApplicationContext());
+
+ 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);
+ }
+
+ @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();
+ }
+ }
+ }
+
+ Log.i(ColorApplication.TAG, "Loaded " + ledDHelpers.size() + " Daemons from preferences");
}
}
diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java
index 0de9ed4..2f44e6d 100644
--- a/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java
+++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java
@@ -18,13 +18,15 @@
package com.idlegandalf.ledd.callbacks;
-public interface AddControllerCallback {
+import com.idlegandalf.ledd.components.Controller;
+
+public interface AddControllerCallback extends BaseCallback {
/**
* Returns when a controller was added successfully
*
- * @param cid the new controller's id
+ * @param controller the new controller
*/
- void onControllerAdded(int cid);
+ void onControllerAdded(Controller controller);
void onAddFailed(String msg, String detail);
}
diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/AddStripeCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddStripeCallback.java
new file mode 100644
index 0000000..e85df6e
--- /dev/null
+++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddStripeCallback.java
@@ -0,0 +1,26 @@
+/*
+ * 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 .
+ */
+
+package com.idlegandalf.ledd.callbacks;
+
+
+import com.idlegandalf.ledd.components.LedStripe;
+
+public interface AddStripeCallback extends BaseCallback {
+ void onAddSuccessfully(LedStripe stripe);
+}
diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/BaseCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/BaseCallback.java
new file mode 100644
index 0000000..c32a40d
--- /dev/null
+++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/BaseCallback.java
@@ -0,0 +1,28 @@
+/*
+ * 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 .
+ */
+
+package com.idlegandalf.ledd.callbacks;
+
+public interface BaseCallback {
+ /**
+ * Returns when there is a connection problem
+ *
+ * @param message error description
+ */
+ void onConnectionFailed(String message);
+}
diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/DiscoverCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/DiscoverCallback.java
new file mode 100644
index 0000000..a80ff98
--- /dev/null
+++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/DiscoverCallback.java
@@ -0,0 +1,28 @@
+/*
+ * 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 .
+ */
+
+package com.idlegandalf.ledd.callbacks;
+
+public interface DiscoverCallback extends BaseCallback {
+ /**
+ * Returns when discover has succeded
+ *
+ * @param version the ledd daemon version string
+ */
+ void onDiscoverSuccessfully(String version);
+}
diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java
index ae3db5e..ef09596 100644
--- a/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java
+++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java
@@ -18,10 +18,10 @@
package com.idlegandalf.ledd.callbacks;
-import com.idlegandalf.ledd.components.HSV;
+import com.idlegandalf.ledd.components.LedStripe;
-public interface RecieveColorCallback {
- void onColorRecieved(HSV color);
+public interface RecieveColorCallback extends BaseCallback {
+ void onColorRecieved(LedStripe stripe);
void onRecievFailed(String msg);
}
diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/StripesCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/StripesCallback.java
new file mode 100644
index 0000000..f9f247a
--- /dev/null
+++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/StripesCallback.java
@@ -0,0 +1,30 @@
+/*
+ * 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 .
+ */
+
+package com.idlegandalf.ledd.callbacks;
+
+
+import com.idlegandalf.ledd.components.LedStripe;
+
+import java.util.List;
+
+public interface StripesCallback extends BaseCallback {
+ void onSuccess(List stripes);
+
+ void onGetFailed(String message);
+}
diff --git a/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java b/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java
index 51e4835..8033071 100644
--- a/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java
+++ b/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java
@@ -21,8 +21,9 @@ package com.idlegandalf.ledd.components;
import org.json.JSONObject;
-public abstract class AnswerTask implements Runnable {
+public abstract class AnswerTask {
+ public abstract void onConnectionFailed(String message);
- public JSONObject response;
+ public abstract void onResponse(JSONObject response);
}
diff --git a/app/src/main/java/com/idlegandalf/ledd/components/Controller.java b/app/src/main/java/com/idlegandalf/ledd/components/Controller.java
index ec6eeb6..ef8b5b1 100644
--- a/app/src/main/java/com/idlegandalf/ledd/components/Controller.java
+++ b/app/src/main/java/com/idlegandalf/ledd/components/Controller.java
@@ -18,8 +18,6 @@
package com.idlegandalf.ledd.components;
-import java.util.ArrayList;
-
import lombok.Getter;
import lombok.Setter;
@@ -27,8 +25,13 @@ import lombok.Setter;
@Getter
@Setter
public class Controller {
- private int channels;
- private String address;
- private int i2c_device;
- private ArrayList stripes;
+ int id;
+ int channels;
+ String address;
+ int i2c_device;
+
+ @Override
+ public String toString() {
+ return String.format("%s@/dev/i2c-%d (%d)", address, i2c_device, channels);
+ }
}
diff --git a/app/src/main/java/com/idlegandalf/ledd/components/HSV.java b/app/src/main/java/com/idlegandalf/ledd/components/HSV.java
index 42ab86b..fe828ca 100644
--- a/app/src/main/java/com/idlegandalf/ledd/components/HSV.java
+++ b/app/src/main/java/com/idlegandalf/ledd/components/HSV.java
@@ -24,9 +24,9 @@ import lombok.Setter;
@Getter
@Setter
public class HSV {
- private double hue;
- private double saturation;
- private double value;
+ double hue;
+ double saturation;
+ double value;
public HSV(double h, double s, double v) {
this.hue = h;
diff --git a/app/src/main/java/com/idlegandalf/ledd/components/Host.java b/app/src/main/java/com/idlegandalf/ledd/components/LedDDaemon.java
similarity index 73%
rename from app/src/main/java/com/idlegandalf/ledd/components/Host.java
rename to app/src/main/java/com/idlegandalf/ledd/components/LedDDaemon.java
index cf5db68..c49ee6a 100644
--- a/app/src/main/java/com/idlegandalf/ledd/components/Host.java
+++ b/app/src/main/java/com/idlegandalf/ledd/components/LedDDaemon.java
@@ -19,23 +19,28 @@
package com.idlegandalf.ledd.components;
+import java.util.ArrayList;
+import java.util.List;
+
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
-public class Host {
- private String address;
- private int port;
+public class LedDDaemon {
+ String address;
+ int port;
+ List controllers;
+ String version;
- public Host(String address, int port) {
+ public LedDDaemon(String address, int port) {
this.address = address;
this.port = port;
+ this.controllers = new ArrayList<>();
}
- public Host() {
- this.address = null;
- this.port = 0;
+ public LedDDaemon() {
+ this(null, 0);
}
@Override
@@ -45,8 +50,8 @@ public class Host {
@Override
public boolean equals(Object o) {
- if (o instanceof Host) {
- if (address.equals(((Host) o).address) && port == ((Host) o).port) return true;
+ if (o instanceof LedDDaemon) {
+ if (address.equals(((LedDDaemon) o).address) && port == ((LedDDaemon) o).port) return true;
}
return false;
}
diff --git a/app/src/main/java/com/idlegandalf/ledd/components/RGBStripe.java b/app/src/main/java/com/idlegandalf/ledd/components/LedDRequest.java
similarity index 75%
rename from app/src/main/java/com/idlegandalf/ledd/components/RGBStripe.java
rename to app/src/main/java/com/idlegandalf/ledd/components/LedDRequest.java
index 1e97205..b8273e2 100644
--- a/app/src/main/java/com/idlegandalf/ledd/components/RGBStripe.java
+++ b/app/src/main/java/com/idlegandalf/ledd/components/LedDRequest.java
@@ -18,18 +18,17 @@
package com.idlegandalf.ledd.components;
+import org.json.JSONObject;
+
import lombok.Getter;
-import lombok.Setter;
@Getter
-@Setter
-public class RGBStripe {
- private int id;
- private int channelRed;
- private int channelGreen;
- private int channelBlue;
- private String nice_name;
- private HSV color;
- private double gammaCorrection;
+public class LedDRequest {
+ JSONObject request;
+ AnswerTask task;
-}
\ No newline at end of file
+ public LedDRequest(JSONObject request, AnswerTask task) {
+ this.request = request;
+ this.task = task;
+ }
+}
diff --git a/app/src/main/java/com/idlegandalf/ledd/components/LedStripe.java b/app/src/main/java/com/idlegandalf/ledd/components/LedStripe.java
new file mode 100644
index 0000000..3ca182f
--- /dev/null
+++ b/app/src/main/java/com/idlegandalf/ledd/components/LedStripe.java
@@ -0,0 +1,58 @@
+/*
+ * 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 .
+ */
+
+package com.idlegandalf.ledd.components;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class LedStripe {
+ int id;
+ int channelRed;
+ int channelGreen;
+ int channelBlue;
+ String name;
+ HSV color;
+ double gammaCorrection;
+ boolean RGB;
+ Controller controller;
+ LedDDaemon ledDDaemon;
+
+ public LedStripe() {
+ this(-1, -1, -1, -1, "");
+ }
+
+ public LedStripe(int channelRed, int channelGreen, int channelBlue, String name) {
+ this(-1, channelRed, channelGreen, channelBlue, name, true);
+ }
+
+ public LedStripe(int id, int channelRed, int channelGreen, int channelBlue, String name) {
+ this(id, channelRed, channelGreen, channelBlue, name, true);
+ }
+
+ public LedStripe(int id, int channelRed, int channelGreen, int channelBlue, String name, boolean RGB) {
+ this.id = id;
+ this.channelRed = channelRed;
+ this.channelGreen = channelGreen;
+ this.channelBlue = channelBlue;
+ this.name = name;
+ this.RGB = RGB;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/idlegandalf/ledd/components/Sendable.java b/app/src/main/java/com/idlegandalf/ledd/components/Sendable.java
index b1286ad..af380fd 100644
--- a/app/src/main/java/com/idlegandalf/ledd/components/Sendable.java
+++ b/app/src/main/java/com/idlegandalf/ledd/components/Sendable.java
@@ -27,16 +27,16 @@ import lombok.Getter;
@Getter
public class Sendable {
- private Host recipient;
- private JSONObject message;
- private String ref;
- private AnswerTask onAnswer;
+ LedDDaemon recipient;
+ JSONObject message;
+ String ref;
+ AnswerTask onAnswer;
- public Sendable(JSONObject msg, AnswerTask task, Host host) throws JSONException {
- this(msg, UUID.randomUUID().toString(), task, host);
+ 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, Host recipient) throws JSONException {
+ public Sendable(JSONObject msg, String ref, AnswerTask task, LedDDaemon recipient) throws JSONException {
this.message = msg;
this.ref = ref;
this.message.put("ref", ref);
@@ -46,8 +46,15 @@ public class Sendable {
public void onResponse(JSONObject object) {
if (onAnswer != null) {
- onAnswer.response = object;
- onAnswer.run();
+ onAnswer.onResponse(object);
}
}
+
+ public void onNoResponse() {
+ onAnswer.onConnectionFailed("no_response");
+ }
+
+ public void onConnectionFailed(String message) {
+ onAnswer.onConnectionFailed(message);
+ }
}
diff --git a/app/src/main/java/com/idlegandalf/ledd/components/StripeGroup.java b/app/src/main/java/com/idlegandalf/ledd/components/StripeGroup.java
index 2a1da0c..9df4a90 100644
--- a/app/src/main/java/com/idlegandalf/ledd/components/StripeGroup.java
+++ b/app/src/main/java/com/idlegandalf/ledd/components/StripeGroup.java
@@ -27,9 +27,9 @@ import java.io.IOException;
import java.util.ArrayList;
public class StripeGroup {
- private String mNiceName;
- private String mDescription;
- private ArrayList mStripes;
+ String mNiceName;
+ String mDescription;
+ ArrayList mStripes;
public String getNiceName() {
return mNiceName;
@@ -47,11 +47,11 @@ public class StripeGroup {
this.mDescription = mDescription;
}
- public RGBStripe getStripeByPos(int pos) {
+ public LedStripe getStripeByPos(int pos) {
return mStripes.get(pos);
}
- public RGBStripe getStripeById(int sid) {
+ public LedStripe getStripeById(int sid) {
for (int i = 0; i < mStripes.size(); i++) {
if (mStripes.get(i).getId() == sid) {
return mStripes.get(i);
@@ -66,12 +66,12 @@ public class StripeGroup {
}
}
- public int addStripe(RGBStripe stripe) {
+ public int addStripe(LedStripe stripe) {
mStripes.add(stripe);
return mStripes.size() - 1;
}
- public void removeStripeByObject(RGBStripe stripe) {
+ public void removeStripeByObject(LedStripe stripe) {
for (int i = 0; i < mStripes.size(); i++) {
if (mStripes.get(i).getId() == stripe.getId()) {
mStripes.remove(i);
diff --git a/app/src/main/java/com/idlegandalf/ledd/fragments/AddControllerDialog.java b/app/src/main/java/com/idlegandalf/ledd/fragments/AddControllerDialog.java
new file mode 100644
index 0000000..95842fd
--- /dev/null
+++ b/app/src/main/java/com/idlegandalf/ledd/fragments/AddControllerDialog.java
@@ -0,0 +1,383 @@
+/*
+ * 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 .
+ */
+
+package com.idlegandalf.ledd.fragments;
+
+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;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+import com.google.gson.Gson;
+import com.idlegandalf.ledd.ColorApplication;
+import com.idlegandalf.ledd.R;
+import com.idlegandalf.ledd.callbacks.AddControllerCallback;
+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.ButterKnife;
+
+public class AddControllerDialog extends DialogFragment implements DialogInterface.OnShowListener {
+
+ @Bind(R.id.input_i2c_layout)
+ TextInputLayout i2cLayout;
+ @Bind(R.id.input_i2c)
+ EditText i2cText;
+ @Bind(R.id.input_address_layout)
+ TextInputLayout addressLayout;
+ @Bind(R.id.input_address)
+ EditText addressText;
+ @Bind(R.id.input_channel_layout)
+ TextInputLayout channelLayout;
+ @Bind(R.id.input_channel)
+ EditText channelText;
+ LedDDaemon dDaemon;
+
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ View v = View.inflate(getActivity(), R.layout.fragment_addcontroller, null);
+ ButterKnife.bind(this, v);
+
+ dDaemon = new Gson().fromJson(getArguments().getString("daemon"), LedDDaemon.class);
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setView(v).setPositiveButton("Add", 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;
+
+ addressText.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) {
+ addressLayout.setError(null);
+ }
+ });
+
+ channelText.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) {
+ channelLayout.setError(null);
+ }
+ });
+
+ i2cText.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) {
+ i2cLayout.setError(null);
+ }
+ });
+
+ alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ 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;
+ }
+
+ 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;
+ }
+
+ 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();
+ }
+
+ 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();
+ }
+ });
+
+ 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();
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onShow(final DialogInterface dialog) {
+
+ final AlertDialog alertDialog = (AlertDialog) dialog;
+
+ addressText.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) {
+ addressLayout.setError(null);
+ }
+ });
+
+ channelText.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) {
+ channelLayout.setError(null);
+ }
+ });
+
+ i2cText.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) {
+ i2cLayout.setError(null);
+ }
+ });
+
+ alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ 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;
+ }
+
+ 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;
+ }
+
+ 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();
+ }
+
+ 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();
+ }
+ });
+
+ 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();
+ }
+ }
+ }
+ });
+ }
+
+ private static boolean isNumeric(String str) {
+ NumberFormat formatter = NumberFormat.getInstance();
+ ParsePosition pos = new ParsePosition(0);
+ formatter.parse(str, pos);
+ return str.length() == pos.getIndex();
+ }
+}
diff --git a/app/src/main/java/com/idlegandalf/ledd/fragments/AddDaemonDialog.java b/app/src/main/java/com/idlegandalf/ledd/fragments/AddDaemonDialog.java
new file mode 100644
index 0000000..a5c2e9a
--- /dev/null
+++ b/app/src/main/java/com/idlegandalf/ledd/fragments/AddDaemonDialog.java
@@ -0,0 +1,329 @@
+/*
+ * 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 .
+ */
+
+package com.idlegandalf.ledd.fragments;
+
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+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;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.google.common.net.InetAddresses;
+import com.idlegandalf.ledd.ColorActivity;
+import com.idlegandalf.ledd.ColorApplication;
+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.ButterKnife;
+
+
+public class AddDaemonDialog extends DialogFragment implements DialogInterface.OnShowListener, NsdManager.DiscoveryListener {
+
+ private final String SERVICE_TYPE = "_ledd._tcp.";
+ @Bind(R.id.input_ip)
+ EditText ip;
+ @Bind(R.id.input_ip_layout)
+ TextInputLayout ip_lay;
+ @Bind(R.id.host_container)
+ LinearLayout hostContainer;
+ List ledDDaemons = new ArrayList<>();
+ NsdManager mNsdManager;
+ private boolean mListening = false;
+
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ View v = View.inflate(getActivity(), R.layout.fragment_adddaemon, null);
+ ButterKnife.bind(this, v);
+
+ mNsdManager = (NsdManager) getActivity().getApplicationContext().getSystemService(Context.NSD_SERVICE);
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setView(v).setPositiveButton("Add", null).setNegativeButton("Cancel", null);
+
+ AlertDialog dialog = builder.create();
+
+ dialog.setOnShowListener(this);
+
+ return dialog;
+ }
+
+ @Override
+ public void onShow(final DialogInterface dialog) {
+ // start host discovery
+ if (!mListening) {
+ mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, this);
+ mListening = true;
+ }
+
+ final AlertDialog alertDialog = (AlertDialog) dialog;
+
+ ip.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) {
+ ip_lay.setError(null);
+ }
+ });
+
+ 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_POSITIVE).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View 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 (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");
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onStartDiscoveryFailed(String serviceType, int errorCode) {
+ Log.e(ColorApplication.TAG, "Discovery failed: Error code:" + errorCode);
+ mNsdManager.stopServiceDiscovery(this);
+ }
+
+ @Override
+ public void onStopDiscoveryFailed(String serviceType, int errorCode) {
+ Log.e(ColorApplication.TAG, "Discovery failed: Error code:" + errorCode);
+ mNsdManager.stopServiceDiscovery(this);
+ mListening = false;
+ }
+
+ @Override
+ public void onDiscoveryStarted(String serviceType) {
+ Log.d(ColorApplication.TAG, "Service discovery started");
+ mListening = true;
+ }
+
+ @Override
+ public void onDiscoveryStopped(String serviceType) {
+ Log.i(ColorApplication.TAG, "Discovery stopped: " + serviceType);
+ mListening = false;
+ }
+
+ @Override
+ public void onServiceFound(NsdServiceInfo serviceInfo) {
+ Log.d(ColorApplication.TAG, "Service discovery success: " + serviceInfo);
+ if (serviceInfo.getServiceType().equals(SERVICE_TYPE)) {
+ mNsdManager.resolveService(serviceInfo, new NsdManager.ResolveListener() {
+ @Override
+ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
+ Log.e(ColorApplication.TAG, "Resolve failed: " + errorCode);
+ }
+
+ @Override
+ public void onServiceResolved(final NsdServiceInfo serviceInfo) {
+ Log.e(ColorApplication.TAG, "Resolve Succeeded. " + serviceInfo);
+
+ if (serviceInfo.getHost() instanceof Inet4Address) {
+ 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);
+
+
+ TextView host = (TextView) v.findViewById(R.id.text_host);
+
+ 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);
+ }
+ });
+ }
+ }
+ }
+ });
+ } else {
+ Log.d(ColorApplication.TAG, "Unknown Service Type: " + serviceInfo.getServiceType());
+ }
+ }
+
+ @Override
+ public void onServiceLost(NsdServiceInfo serviceInfo) {
+ Log.e(ColorApplication.TAG, "service lost" + serviceInfo);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mNsdManager != null && mListening) {
+ mNsdManager.stopServiceDiscovery(this);
+ mListening = false;
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ if (mNsdManager != null && mListening) {
+ mNsdManager.stopServiceDiscovery(this);
+ mListening = false;
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ if (mNsdManager != null && !mListening) {
+ mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, this);
+ mListening = true;
+ }
+ }
+
+ 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();
+ }
+
+ @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();
+ }
+ });
+
+ try {
+ ((ColorActivity) getActivity()).refreshStripes();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ AddStripeDialog.instance.onResume();
+ dismiss();
+ }
+ });
+ } catch (JSONException | IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/app/src/main/java/com/idlegandalf/ledd/fragments/AddStripeDialog.java b/app/src/main/java/com/idlegandalf/ledd/fragments/AddStripeDialog.java
new file mode 100644
index 0000000..9979d0f
--- /dev/null
+++ b/app/src/main/java/com/idlegandalf/ledd/fragments/AddStripeDialog.java
@@ -0,0 +1,457 @@
+/*
+ * 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 .
+ */
+
+package com.idlegandalf.ledd.fragments;
+
+
+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;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.Spinner;
+import android.widget.Toast;
+
+import com.google.gson.Gson;
+import com.idlegandalf.ledd.ColorActivity;
+import com.idlegandalf.ledd.ColorApplication;
+import com.idlegandalf.ledd.R;
+import com.idlegandalf.ledd.callbacks.AddStripeCallback;
+import com.idlegandalf.ledd.callbacks.StripesCallback;
+import com.idlegandalf.ledd.components.Controller;
+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.ButterKnife;
+import butterknife.OnClick;
+
+public class AddStripeDialog extends DialogFragment implements DialogInterface.OnShowListener {
+
+ public static AddStripeDialog instance;
+ @Bind(R.id.spinner_daemon)
+ Spinner daemonSpinner;
+ @Bind(R.id.spinner_controller)
+ Spinner controllerSpinner;
+ @Bind(R.id.choose_controller_lay)
+ RelativeLayout controllerLayout;
+ @Bind(R.id.input_stripe_name_lay)
+ TextInputLayout stripeNameLay;
+ @Bind(R.id.input_stripe_name)
+ EditText stripeNameText;
+ @Bind(R.id.input_channel_r_lay)
+ TextInputLayout channelRLay;
+ @Bind(R.id.input_channel_r)
+ EditText channelR;
+ @Bind(R.id.input_channel_g_lay)
+ TextInputLayout channelGLay;
+ @Bind(R.id.input_channel_g)
+ EditText channelG;
+ @Bind(R.id.input_channel_b_lay)
+ TextInputLayout channelBLay;
+ @Bind(R.id.input_channel_b)
+ EditText channelB;
+ @Bind(R.id.stripe_mapping_lay)
+ LinearLayout stripeMapping;
+ @Bind(R.id.imgbuttn_togglechannel_r)
+ ImageButton channelRBttn;
+ @Bind(R.id.imgbuttn_togglechannel_g)
+ ImageButton channelGBttn;
+ @Bind(R.id.imgbuttn_togglechannel_b)
+ ImageButton channelBBttn;
+ ArrayAdapter daemonArrayAdapter;
+ ArrayAdapter controllerArrayAdapter;
+ boolean mDaemonSelected = false;
+ boolean mControllerSelected = false;
+
+ 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_addstripe, null);
+ ButterKnife.bind(this, v);
+ instance = this;
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setView(v).setPositiveButton("Add", 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;
+ toggleAll(controllerLayout, false);
+ channelRBttn.setEnabled(false);
+ channelGBttn.setEnabled(false);
+ channelBBttn.setEnabled(false);
+
+ stripeNameText.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) {
+ stripeNameLay.setError(null);
+ }
+ });
+
+ channelR.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) {
+ if (s.toString().isEmpty()) {
+ channelRBttn.setEnabled(false);
+ } else {
+ channelRBttn.setEnabled(true);
+ }
+ }
+ });
+ channelG.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) {
+ if (s.toString().isEmpty()) {
+ channelGBttn.setEnabled(false);
+ } else {
+ channelGBttn.setEnabled(true);
+ }
+ }
+ });
+ channelB.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) {
+ if (s.toString().isEmpty()) {
+ channelBBttn.setEnabled(false);
+ } else {
+ channelBBttn.setEnabled(true);
+ }
+ }
+ });
+
+ 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;
+ }
+ }
+ };
+
+ channelRBttn.setOnClickListener(imgListener);
+ 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_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 (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());
+
+ LedDHelper helper = null;
+ try {
+ helper = ColorApplication.getInstance().getHelperForDaemon((LedDDaemon) daemonSpinner.getSelectedItem());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ 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();
+ }
+ }
+ }
+ });
+
+ daemonArrayAdapter = new ArrayAdapter<>(getActivity().getApplicationContext(), R.layout.spinner_item);
+ daemonArrayAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
+ daemonArrayAdapter.addAll(ColorApplication.getInstance().getDaemons());
+
+ controllerArrayAdapter = new ArrayAdapter<>(getActivity().getApplicationContext(), R.layout.spinner_item);
+ controllerArrayAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
+
+ daemonSpinner.setAdapter(daemonArrayAdapter);
+ controllerSpinner.setAdapter(controllerArrayAdapter);
+
+ daemonSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ mDaemonSelected = true;
+ toggleAll(controllerLayout, true);
+ refreshController((LedDDaemon) daemonSpinner.getSelectedItem());
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ toggleAll(controllerLayout, false);
+ controllerArrayAdapter.clear();
+ mDaemonSelected = false;
+ mControllerSelected = false;
+ }
+ });
+
+ controllerSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ mControllerSelected = true;
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ mControllerSelected = false;
+ }
+ });
+ }
+
+ @OnClick(R.id.imgbuttn_addcontroller)
+ public void addController(ImageButton button) {
+ AddControllerDialog dialog = new AddControllerDialog();
+ Bundle b = new Bundle();
+ b.putString("daemon", new Gson().toJson(daemonSpinner.getSelectedItem()));
+ dialog.setArguments(b);
+ dialog.show(getActivity().getFragmentManager(), "");
+ }
+
+ @OnClick(R.id.imgbuttn_adddaemon)
+ public void addDaemon(ImageButton button) {
+ new AddDaemonDialog().show(getActivity().getFragmentManager(), "");
+ }
+
+ private void toggleAll(ViewGroup v, boolean status) {
+ for (int i = 0; i < v.getChildCount(); i++) {
+ v.getChildAt(i).setEnabled(status);
+ }
+ }
+
+ @Override
+ 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());
+ }
+ }
+
+ private void testChannel(EditText text, ImageButton button) {
+ if (mDaemonSelected && mControllerSelected) {
+ if (!text.getText().toString().isEmpty() && isNumeric(text.getText().toString())) {
+ int val;
+ boolean toggle = false;
+ if (text.getTag() != null) toggle = (boolean) text.getTag();
+ if (!toggle) {
+ val = 1;
+ toggle = true;
+ button.setImageResource(R.drawable.ic_visibility_black_48dp);
+ } else {
+ val = 0;
+ toggle = false;
+ button.setImageResource(R.drawable.ic_visibility_off_black_48dp);
+ }
+ text.setTag(toggle);
+
+ LedDHelper helper = null;
+ try {
+ helper = ColorApplication.getInstance().getHelperForDaemon((LedDDaemon) daemonSpinner.getSelectedItem());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ if (helper != null) {
+ try {
+ helper.testChannel((Controller) controllerSpinner.getSelectedItem(), Integer.parseInt(text.getText().toString()), val);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ private void refreshController(final LedDDaemon ledDDaemon) {
+ controllerArrayAdapter.clear();
+ LedDHelper helper = null;
+ try {
+ helper = ColorApplication.getInstance().getHelperForDaemon(ledDDaemon);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ if (helper != null) {
+ try {
+ helper.getStripes(new StripesCallback() {
+ @Override
+ public void onSuccess(List stripes) {
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ controllerArrayAdapter.addAll(ledDDaemon.getControllers());
+ toggleAll(stripeMapping, true);
+ }
+ });
+ }
+
+ @Override
+ public void onGetFailed(String message) {
+
+ }
+
+ @Override
+ public void onConnectionFailed(String message) {
+
+ }
+ });
+ } catch (JSONException | IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/idlegandalf/ledd/fragments/DrawerFragment.java b/app/src/main/java/com/idlegandalf/ledd/fragments/DrawerFragment.java
deleted file mode 100644
index c2fe20d..0000000
--- a/app/src/main/java/com/idlegandalf/ledd/fragments/DrawerFragment.java
+++ /dev/null
@@ -1,50 +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 .
- */
-
-package com.idlegandalf.ledd.fragments;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-import com.idlegandalf.ledd.R;
-
-import butterknife.Bind;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-
-public class DrawerFragment extends Fragment {
- @Bind(R.id.lay_add_host)
- LinearLayout addHost;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View v = inflater.inflate(R.layout.drawer_fragment, container, false);
- ButterKnife.bind(this, v);
-
- return v;
- }
-
- @OnClick(R.id.lay_add_host)
- public void addHost() {
- // TODO: add dialog with selection and input things
- }
-}
diff --git a/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java b/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java
index a95275f..78fd9f9 100644
--- a/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java
+++ b/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java
@@ -23,49 +23,65 @@ 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.StripesCallback;
import com.idlegandalf.ledd.components.AnswerTask;
+import com.idlegandalf.ledd.components.Controller;
import com.idlegandalf.ledd.components.HSV;
-import com.idlegandalf.ledd.components.Host;
+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 org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
-
-import hugo.weaving.DebugLog;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
public class LedDHelper {
final String ACTION_SETCOLOR = "set_color";
final String ACTION_GETCOLOR = "get_color";
final String ACTION_ADDCONTROLLER = "add_controller";
- final String ACTION_GETCONTROLLER = "get_controller";
- final String ACTION_ADDSTRIPES = "add_stripes";
- private Host host;
+ final String ACTION_GETALLSTRIPES = "get_stripes";
+ final String ACTION_ADDSTRIPES = "add_stripe";
+ final String ACTION_TESTCHANNEL = "test_channel";
+ final String ACTION_DISCOVER = "discover";
private Context context;
- private ColorService.ColorBinder binderService;
private boolean mBound = false;
+ private LedDDaemon ledDDaemon;
+ private Worker requestWorker;
+ private LinkedBlockingQueue dRequests;
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
- System.out.println("service bound!");
- binderService = (ColorService.ColorBinder) service;
+ Log.d(ColorApplication.TAG, "ColorService bound!");
+ requestWorker = new Worker<>(dRequests, (ColorService.ColorBinder) service, ledDDaemon);
mBound = true;
+ new Thread(requestWorker).start();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
+ requestWorker.stop();
mBound = false;
}
};
- public LedDHelper(Host host, Context appl) throws IOException {
- this.host = host;
+ public LedDHelper(LedDDaemon ledDDaemon, Context appl) throws IOException {
this.context = appl;
+ this.dRequests = new LinkedBlockingQueue<>();
+ this.ledDDaemon = ledDDaemon;
Intent intent = new Intent(appl, ColorService.class);
appl.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
@@ -74,25 +90,30 @@ public class LedDHelper {
/**
* Add controller to ledd daemon
*
- * @param channels channel amount that this controller holds
- * @param i2c_dev number of i2c device, e.g. /dev/i2c-1 would be 1
+ * @param c controller object
* @throws JSONException no valid json
* @throws IOException socket error
*/
- public void addController(int channels, int i2c_dev, String address, final AddControllerCallback callback) throws JSONException, IOException {
+ public void addController(final Controller c, final AddControllerCallback callback) throws JSONException, IOException {
JSONObject jnson = new JSONObject();
jnson.put("action", ACTION_ADDCONTROLLER);
- jnson.put("channels", channels);
- jnson.put("i2c_dev", i2c_dev);
- jnson.put("address", address);
+ jnson.put("channels", c.getChannels());
+ jnson.put("i2c_dev", c.getI2c_device());
+ jnson.put("address", c.getAddress());
- sendJSON(jnson, new AnswerTask() {
+ addRequestToQueue(jnson, new AnswerTask() {
@Override
- public void run() {
+ public void onConnectionFailed(String message) {
+ callback.onAddFailed(message, "");
+ }
+
+ @Override
+ public void onResponse(JSONObject response) {
try {
if (response.getBoolean("success")) {
- callback.onControllerAdded(response.getInt("cid"));
+ c.setId(response.getInt("cid"));
+ callback.onControllerAdded(c);
} else {
callback.onAddFailed(response.getString("message"), response.getString("message_detail"));
}
@@ -104,51 +125,123 @@ public class LedDHelper {
}
/**
- * Set color using the stripeid
+ * Get stripes known to daemon
*
- * @param sid Stripeid
- * @param color Color in HSV format
* @throws JSONException no valid json
* @throws IOException socket error
*/
- public void setColor(int sid, HSV color) throws JSONException, IOException {
+ public void getStripes(final StripesCallback callback) throws JSONException, IOException {
+ JSONObject jnson = new JSONObject();
+
+ jnson.put("action", ACTION_GETALLSTRIPES);
+
+ addRequestToQueue(jnson, new AnswerTask() {
+ @Override
+ public void onConnectionFailed(String message) {
+ callback.onGetFailed(message);
+ }
+
+ @Override
+ public void onResponse(JSONObject response) {
+ try {
+ if (response.getBoolean("success")) {
+ ledDDaemon.getControllers().clear();
+ List list = new ArrayList<>();
+ JSONArray jcontrollers = response.getJSONArray("controller");
+
+ for (int i = 0; i < jcontrollers.length(); i++) {
+ JSONObject row = jcontrollers.getJSONObject(i);
+ Controller nController = new Controller();
+ nController.setAddress(row.getString("address"));
+ nController.setChannels(row.getInt("channel"));
+ nController.setI2c_device(row.getInt("i2c_device"));
+ nController.setId(row.getInt("id"));
+
+ JSONArray jstripes = row.getJSONArray("stripes");
+
+ for (int o = 0; o < jstripes.length(); o++) {
+ JSONObject srow = jstripes.getJSONObject(i);
+ LedStripe nStripe = new LedStripe();
+ nStripe.setId(srow.getInt("id"));
+ nStripe.setRGB(srow.getBoolean("rgb"));
+ nStripe.setChannelRed(srow.getJSONArray("channel").getInt(0));
+ nStripe.setChannelGreen(srow.getJSONArray("channel").getInt(1));
+ nStripe.setChannelBlue(srow.getJSONArray("channel").getInt(2));
+ nStripe.setName(srow.getString("name"));
+ nStripe.setController(nController);
+ nStripe.setLedDDaemon(ledDDaemon);
+ list.add(nStripe);
+ }
+
+ ledDDaemon.getControllers().add(nController);
+ }
+
+ callback.onSuccess(list);
+ } else {
+ if (response.has("message")) callback.onGetFailed(response.getString("message"));
+ else callback.onGetFailed("unknown error");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ /**
+ * Set color using the stripeid
+ *
+ * @param ledStripe Stripe
+ */
+ public void setColor(LedStripe ledStripe) {
+
JSONObject jnson = new JSONObject();
JSONObject hsv = new JSONObject();
- hsv.put("h", color.getHue());
- hsv.put("s", color.getSaturation());
- hsv.put("v", color.getValue());
+ try {
+ hsv.put("h", ledStripe.getColor().getHue());
+ hsv.put("s", ledStripe.getColor().getSaturation());
- jnson.put("action", ACTION_SETCOLOR);
- jnson.put("sid", sid);
- jnson.put("color", hsv);
+ hsv.put("v", ledStripe.getColor().getValue());
- sendJSON(jnson, null);
+
+ jnson.put("action", ACTION_SETCOLOR);
+ jnson.put("sid", ledStripe.getId());
+ jnson.put("hsv", hsv);
+
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ addRequestToQueue(jnson, null);
}
/**
* Get color using the stripeid
*
- * @param sid Stripeid
+ * @param ledStripe Stripe
* @throws JSONException no valid json
* @throws IOException socket error
*/
- public void getColor(int sid, final RecieveColorCallback callback) throws JSONException, IOException {
+ public void getColor(final LedStripe ledStripe, final RecieveColorCallback callback) throws JSONException, IOException {
JSONObject jnson = new JSONObject();
jnson.put("action", ACTION_GETCOLOR);
- jnson.put("sid", sid);
+ jnson.put("sid", ledStripe.getId());
- sendJSON(jnson, new AnswerTask() {
+ addRequestToQueue(jnson, new AnswerTask() {
@Override
- public void run() {
+ public void onConnectionFailed(String message) {
+ callback.onRecievFailed(message);
+ }
+
+ @Override
+ public void onResponse(JSONObject response) {
try {
if (response.getBoolean("success")) {
-
- JSONObject hsv = null;
-
- hsv = response.getJSONObject("hsv");
- callback.onColorRecieved(new HSV(hsv.getDouble("h"), hsv.getDouble("s"), hsv.getDouble("v")));
+ 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"));
}
@@ -159,15 +252,151 @@ public class LedDHelper {
});
}
- private void sendJSON(JSONObject json, AnswerTask task) throws IOException, JSONException {
- if (mBound) binderService.queueSend(host, json, task);
+ /**
+ * Test a channel on the controller
+ *
+ * @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();
+
+ jnson.put("action", ACTION_TESTCHANNEL);
+ jnson.put("cid", c.getId());
+ jnson.put("channel", channel);
+ jnson.put("value", value);
+
+ addRequestToQueue(jnson, new AnswerTask() {
+ @Override
+ public void onConnectionFailed(String message) {
+
+ }
+
+ @Override
+ public void onResponse(JSONObject response) {
+
+ }
+ });
+ }
+
+ /**
+ * 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() {
+ @Override
+ public void onConnectionFailed(String message) {
+ callback.onConnectionFailed(message);
+ }
+
+ @Override
+ public void onResponse(JSONObject response) {
+ try {
+ if (response.getBoolean("success")) {
+ callback.onDiscoverSuccessfully(response.getString("version"));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ /**
+ * 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();
+
+ jnson.put("action", ACTION_ADDSTRIPES);
+ JSONObject stripe = new JSONObject();
+
+ 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);
+
+ addRequestToQueue(jnson, new AnswerTask() {
+ @Override
+ public void onConnectionFailed(String message) {
+ callback.onConnectionFailed(message);
+ }
+
+ @Override
+ public void onResponse(JSONObject response) {
+ try {
+ if (response.getBoolean("success")) {
+ ledStripe.setId(response.getInt("sid"));
+ callback.onAddSuccessfully(ledStripe);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ private void addRequestToQueue(JSONObject json, AnswerTask task) {
+ dRequests.add(new LedDRequest(json, task));
}
- @DebugLog
public void teardown() {
if (mBound) {
context.unbindService(mConnection);
mBound = false;
}
+ requestWorker.stop();
+ }
+
+ private static class Worker implements Runnable {
+ private final LinkedBlockingQueue workQueue;
+ private final ColorService.ColorBinder binder;
+ private final LedDDaemon ledDDaemon;
+
+ public Worker(LinkedBlockingQueue workQueue, ColorService.ColorBinder colorBinder, LedDDaemon dDaemon) {
+ this.workQueue = workQueue;
+ this.binder = colorBinder;
+ this.ledDDaemon = dDaemon;
+ }
+
+ @Override
+ public void run() {
+ while (!Thread.currentThread().isInterrupted()) {
+ try {
+ final T item = workQueue.take();
+
+ if (item instanceof LedDRequest) {
+ binder.queueSend(ledDDaemon, ((LedDRequest) item).getRequest(), ((LedDRequest) item).getTask());
+ }
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ break;
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void stop() {
+ Thread.currentThread().interrupt();
+ }
}
}
diff --git a/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java b/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java
index 59ba9a7..06d141b 100644
--- a/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java
+++ b/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java
@@ -24,7 +24,7 @@ import android.os.Binder;
import android.os.IBinder;
import com.idlegandalf.ledd.components.AnswerTask;
-import com.idlegandalf.ledd.components.Host;
+import com.idlegandalf.ledd.components.LedDDaemon;
import com.idlegandalf.ledd.components.Sendable;
import com.koushikdutta.async.AsyncServer;
import com.koushikdutta.async.AsyncSocket;
@@ -41,10 +41,12 @@ import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.concurrent.LinkedBlockingQueue;
-
-import hugo.weaving.DebugLog;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
public class ColorService extends Service {
+ private static ScheduledThreadPoolExecutor poolExecutor = new ScheduledThreadPoolExecutor(5);
private final IBinder mBinder = new ColorBinder();
private LinkedBlockingQueue queue;
private Worker worker;
@@ -63,15 +65,22 @@ public class ColorService extends Service {
return mBinder;
}
+ @Override
+ public boolean onUnbind(Intent intent) {
+ return super.onUnbind(intent);
+ }
+
@Override
public void onDestroy() {
worker.stop();
+ poolExecutor.shutdownNow();
}
private static class Worker implements Runnable {
private final LinkedBlockingQueue workQueue;
- private HashMap socketHashMap;
+ private HashMap socketHashMap;
private HashMap sendableHashMap;
+ private HashMap timeoutHashMap;
DataCallback dataCallback = new DataCallback() {
@Override
@@ -88,6 +97,9 @@ public class ColorService extends Service {
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();
@@ -100,10 +112,10 @@ public class ColorService extends Service {
this.workQueue = workQueue;
this.socketHashMap = new HashMap<>();
this.sendableHashMap = new HashMap<>();
+ this.timeoutHashMap = new HashMap<>();
}
@Override
- @DebugLog
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
@@ -113,9 +125,19 @@ public class ColorService extends Service {
if (socketHashMap.containsKey(((Sendable) item).getRecipient()) && socketHashMap.get(((Sendable) item).getRecipient())
.getServer().isRunning()) {
- Util.writeAll(socketHashMap.get(((Sendable) item).getRecipient()), ((Sendable) item).getMessage().toString().getBytes
+ Util.writeAll(socketHashMap.get(((Sendable) item).getRecipient()), (((Sendable) item).getMessage().toString() + "\n")
+ .getBytes
("UTF-8"), null);
sendableHashMap.put(((Sendable) item).getRef(), (Sendable) item);
+ 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());
+ }
+ }, 1000, TimeUnit.MILLISECONDS));
} else {
AsyncServer.getDefault().connectSocket(new InetSocketAddress(((Sendable) item).getRecipient().getAddress(), ((Sendable)
item).getRecipient().getPort()), new ConnectCallback() {
@@ -126,11 +148,10 @@ public class ColorService extends Service {
socketHashMap.put(((Sendable) item).getRecipient(), socket);
- if (!workQueue.contains(item)) {
- workQueue.add(item);
- }
+ //if (!workQueue.contains(item)) -> needs equals implementaion
+ workQueue.add(item);
} else {
- ex.printStackTrace();
+ ((Sendable) item).onConnectionFailed(ex.getMessage());
}
}
});
@@ -151,10 +172,9 @@ public class ColorService extends Service {
}
public class ColorBinder extends Binder {
- public String queueSend(Host rec, JSONObject msg, AnswerTask answerTask) throws JSONException {
+ public String queueSend(LedDDaemon rec, JSONObject msg, AnswerTask answerTask) throws JSONException {
Sendable sendable = new Sendable(msg, answerTask, rec);
queue.add(sendable);
- System.out.println("qlen: " + queue.size());
return sendable.getRef();
}
}
diff --git a/app/src/main/res/layout/activity_color.xml b/app/src/main/res/layout/activity_color.xml
index 37e88f6..758b7e6 100644
--- a/app/src/main/res/layout/activity_color.xml
+++ b/app/src/main/res/layout/activity_color.xml
@@ -19,9 +19,10 @@
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
@@ -38,21 +39,29 @@
android:background="?attr/colorPrimary"
android:minHeight="?android:attr/actionBarSize"/>
-
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="25dp"/>
+
+
-
+ app:headerLayout="@layout/navigation_header"
+ app:menu="@menu/navigation_drawer"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/drawer_fragment.xml b/app/src/main/res/layout/drawer_fragment.xml
deleted file mode 100644
index 7cf765f..0000000
--- a/app/src/main/res/layout/drawer_fragment.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/fragment_addcontroller.xml b/app/src/main/res/layout/fragment_addcontroller.xml
new file mode 100644
index 0000000..edad69e
--- /dev/null
+++ b/app/src/main/res/layout/fragment_addcontroller.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_adddaemon.xml b/app/src/main/res/layout/fragment_adddaemon.xml
new file mode 100644
index 0000000..72d1bab
--- /dev/null
+++ b/app/src/main/res/layout/fragment_adddaemon.xml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_addstripe.xml b/app/src/main/res/layout/fragment_addstripe.xml
new file mode 100644
index 0000000..87a9639
--- /dev/null
+++ b/app/src/main/res/layout/fragment_addstripe.xml
@@ -0,0 +1,275 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/host_row.xml b/app/src/main/res/layout/host_row.xml
index e05d5a4..3d3db90 100644
--- a/app/src/main/res/layout/host_row.xml
+++ b/app/src/main/res/layout/host_row.xml
@@ -18,21 +18,31 @@
-->
+ 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">
+
+
+ android:textAppearance="?android:textAppearanceMedium"
+ android:textColor="@color/primaryColorDark"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/navigation_header.xml b/app/src/main/res/layout/navigation_header.xml
new file mode 100644
index 0000000..7d4688a
--- /dev/null
+++ b/app/src/main/res/layout/navigation_header.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/spinner_dropdown_item.xml b/app/src/main/res/layout/spinner_dropdown_item.xml
new file mode 100644
index 0000000..8a662f2
--- /dev/null
+++ b/app/src/main/res/layout/spinner_dropdown_item.xml
@@ -0,0 +1,28 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/spinner_item.xml b/app/src/main/res/layout/spinner_item.xml
new file mode 100644
index 0000000..0dee485
--- /dev/null
+++ b/app/src/main/res/layout/spinner_item.xml
@@ -0,0 +1,29 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/navigation_drawer.xml b/app/src/main/res/menu/navigation_drawer.xml
new file mode 100644
index 0000000..ce872d8
--- /dev/null
+++ b/app/src/main/res/menu/navigation_drawer.xml
@@ -0,0 +1,35 @@
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 1b7886d..aac6a05 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,3 +1,21 @@
+/*
+ * 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 .
+ */
+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
@@ -5,7 +23,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:1.3.0'
+ classpath 'com.android.tools.build:gradle:1.3.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files