From aaa9c5da02f8eb7a05a6c747d63a2f76d18545b0 Mon Sep 17 00:00:00 2001 From: Giovanni Harting Date: Tue, 1 Sep 2015 05:56:48 +0200 Subject: [PATCH] reworked a whole bunch of stuff moved from assistant to one single activity model with dialogs and navigation drawer as main content holder completed separate threaded queue based service to communicate with daemon(s) added first few elements to the nav drawer --- app/build.gradle | 20 +- app/src/main/AndroidManifest.xml | 15 +- .../idlegandalf/ledd/AssistantActivity.java | 73 ---- .../com/idlegandalf/ledd/ColorActivity.java | 52 +-- .../idlegandalf/ledd/ColorApplication.java | 71 ++-- .../com/idlegandalf/ledd/ColorService.java | 99 ----- .../com/idlegandalf/ledd/DrawerFragment.java | 26 +- .../ledd/ProgressBarActionBarActivity.java | 32 -- .../idlegandalf/ledd/SettingsActivity.java | 11 +- .../ledd/callbacks/AddControllerCallback.java | 13 + .../ledd/callbacks/RecieveColorCallback.java | 9 + .../ledd/components/AnswerTask.java | 10 + .../ledd/components/Controller.java | 3 + .../com/idlegandalf/ledd/components/HSV.java | 16 +- .../com/idlegandalf/ledd/components/Host.java | 18 + .../ledd/components/LEDDHelper.java | 68 --- .../ledd/components/RGBStripe.java | 14 +- .../idlegandalf/ledd/components/Sendable.java | 35 ++ .../ledd/components/StripeGroup.java | 98 ++--- .../ledd/fragments/StepOneFragment.java | 233 ---------- .../ledd/fragments/StepStripesFragment.java | 7 - .../ledd/fragments/WelcomeFragment.java | 218 ---------- .../idlegandalf/ledd/helper/LedDHelper.java | 155 +++++++ .../ledd/services/ColorService.java | 143 +++++++ .../idlegandalf/ledd/utils/ColorPicker.java | 352 --------------- .../ledd/utils/ColorPickerDialog.java | 54 --- .../ledd/utils/ColorPickerPreference.java | 73 ---- .../ledd/utils/MultiColorPicker.java | 401 ------------------ .../res/drawable-hdpi/drawer_shadow.9.png | Bin 161 -> 0 bytes app/src/main/res/drawable-hdpi/ic_drawer.png | Bin 2829 -> 0 bytes .../res/drawable-mdpi/drawer_shadow.9.png | Bin 142 -> 0 bytes app/src/main/res/drawable-mdpi/ic_drawer.png | Bin 2820 -> 0 bytes .../res/drawable-xhdpi/drawer_shadow.9.png | Bin 174 -> 0 bytes app/src/main/res/drawable-xhdpi/ic_drawer.png | Bin 2836 -> 0 bytes .../res/drawable-xxhdpi/drawer_shadow.9.png | Bin 208 -> 0 bytes .../main/res/drawable-xxhdpi/ic_drawer.png | Bin 202 -> 0 bytes app/src/main/res/drawable/dimme.xml | 6 - app/src/main/res/layout/act_demo.xml | 15 - app/src/main/res/layout/act_multi_picker.xml | 21 - app/src/main/res/layout/act_picker.xml | 21 - app/src/main/res/layout/act_pref.xml | 11 - app/src/main/res/layout/activity_color.xml | 33 +- app/src/main/res/layout/drawer_fragment.xml | 83 +++- app/src/main/res/layout/fragment_step1.xml | 84 ---- app/src/main/res/layout/fragment_welcome.xml | 93 ---- app/src/main/res/menu/color.xml | 9 +- app/src/main/res/menu/step1.xml | 4 - app/src/main/res/menu/welcome.xml | 3 - app/src/main/res/values/color.xml | 5 + app/src/main/res/values/dimens.xml | 2 + app/src/main/res/values/styles.xml | 5 + 51 files changed, 677 insertions(+), 2037 deletions(-) delete mode 100644 app/src/main/java/com/idlegandalf/ledd/AssistantActivity.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/ColorService.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/ProgressBarActionBarActivity.java create mode 100644 app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java create mode 100644 app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java create mode 100644 app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/components/LEDDHelper.java create mode 100644 app/src/main/java/com/idlegandalf/ledd/components/Sendable.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/fragments/StepOneFragment.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/fragments/StepStripesFragment.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/fragments/WelcomeFragment.java create mode 100644 app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java create mode 100644 app/src/main/java/com/idlegandalf/ledd/services/ColorService.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/utils/ColorPicker.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/utils/ColorPickerDialog.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/utils/ColorPickerPreference.java delete mode 100644 app/src/main/java/com/idlegandalf/ledd/utils/MultiColorPicker.java delete mode 100644 app/src/main/res/drawable-hdpi/drawer_shadow.9.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_drawer.png delete mode 100644 app/src/main/res/drawable-mdpi/drawer_shadow.9.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_drawer.png delete mode 100644 app/src/main/res/drawable-xhdpi/drawer_shadow.9.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_drawer.png delete mode 100644 app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_drawer.png delete mode 100644 app/src/main/res/drawable/dimme.xml delete mode 100644 app/src/main/res/layout/act_demo.xml delete mode 100644 app/src/main/res/layout/act_multi_picker.xml delete mode 100644 app/src/main/res/layout/act_picker.xml delete mode 100644 app/src/main/res/layout/act_pref.xml delete mode 100644 app/src/main/res/layout/fragment_step1.xml delete mode 100644 app/src/main/res/layout/fragment_welcome.xml delete mode 100644 app/src/main/res/menu/step1.xml delete mode 100644 app/src/main/res/menu/welcome.xml create mode 100644 app/src/main/res/values/color.xml diff --git a/app/build.gradle b/app/build.gradle index 538a8a1..f38315c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,13 +15,13 @@ apply plugin: 'com.jakewharton.hugo' apply plugin: 'com.github.ben-manes.versions' android { - compileSdkVersion 22 - buildToolsVersion "22.0.1" + compileSdkVersion 23 + buildToolsVersion '23.0.0' defaultConfig { applicationId "com.idlegandalf.ledd" minSdkVersion 16 - targetSdkVersion 22 + targetSdkVersion 23 versionCode 1 versionName "1.0" } @@ -34,12 +34,14 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:22.2.1' - compile 'com.android.support:support-v4:22.2.1' - compile 'com.squareup.okhttp:okhttp:2.4.0' + 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.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:22.2.1' - provided "org.projectlombok:lombok:1.16.4" + compile 'com.android.support:design:23.0.0' + compile 'com.rarepebble:colorpicker:1.3.0' + provided 'org.projectlombok:lombok:1.16.6' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0fcf6db..76c732e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,13 +1,14 @@ - + @@ -33,11 +34,7 @@ android:value="com.idlegandalf.ledd.ColorActivity" /> - - - + diff --git a/app/src/main/java/com/idlegandalf/ledd/AssistantActivity.java b/app/src/main/java/com/idlegandalf/ledd/AssistantActivity.java deleted file mode 100644 index 9a18c62..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/AssistantActivity.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.idlegandalf.ledd; - -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.view.Menu; -import android.widget.FrameLayout; - -import com.idlegandalf.ledd.fragments.WelcomeFragment; - -import butterknife.Bind; -import butterknife.ButterKnife; - -public class AssistantActivity extends AppCompatActivity { - - @Bind(R.id.fragmentContainer) - FrameLayout container; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_asistent); - ButterKnife.bind(this); - - // Check that the activity is using the layout version with - // the fragment_container FrameLayout - if (container != null) { - - // However, if we're being restored from a previous state, - // then we don't need to do anything and should return or else - // we could end up with overlapping fragments. - if (savedInstanceState != null) { - return; - } - - // Create a new Fragment to be placed in the activity layout - WelcomeFragment welcomeFragment = new WelcomeFragment(); - - // In case this activity was started with special instructions from an - // Intent, pass the Intent's extras to the fragment as arguments - welcomeFragment.setArguments(getIntent().getExtras()); - - // Add the fragment to the 'fragment_container' FrameLayout - getFragmentManager().beginTransaction() - .add(R.id.fragmentContainer, welcomeFragment).commit(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.welcome, menu); - return true; - } - - public void switchFragment(Fragment fragment) { - FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); - - fragmentTransaction.replace(R.id.fragmentContainer, fragment); - fragmentTransaction.addToBackStack(null); - - fragmentTransaction.commit(); - } - - @Override - public void onBackPressed() { - if (getFragmentManager().getBackStackEntryCount() > 0) { - getFragmentManager().popBackStack(); - } else { - super.onBackPressed(); - } - } -} diff --git a/app/src/main/java/com/idlegandalf/ledd/ColorActivity.java b/app/src/main/java/com/idlegandalf/ledd/ColorActivity.java index 2020457..0d93cad 100644 --- a/app/src/main/java/com/idlegandalf/ledd/ColorActivity.java +++ b/app/src/main/java/com/idlegandalf/ledd/ColorActivity.java @@ -1,37 +1,36 @@ package com.idlegandalf.ledd; import android.content.Context; -import android.content.Intent; import android.content.res.Configuration; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; -import android.preference.PreferenceManager; 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.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import com.idlegandalf.ledd.components.LEDDHelper; import com.idlegandalf.ledd.components.RGBStripe; import com.idlegandalf.ledd.components.StripeGroup; -import com.idlegandalf.ledd.utils.ColorPicker; +import com.idlegandalf.ledd.helper.LedDHelper; import butterknife.Bind; import butterknife.ButterKnife; +import hugo.weaving.DebugLog; public class ColorActivity extends AppCompatActivity { - @Bind(R.id.colorPicker) - ColorPicker mWheel; @Bind(R.id.drawer_layout) DrawerLayout mDrawerLayout; + @Bind(R.id.toolbar) + Toolbar toolbar; private ActionBarDrawerToggle mDrawerToggle; - private LEDDHelper mAPI; + private LedDHelper mAPI; private RGBStripe mActiveStripe; private StripeGroup mActiveGroup; private boolean firstRun = false; @@ -49,6 +48,9 @@ public class ColorActivity extends AppCompatActivity { // TODO: Display error } + setSupportActionBar(toolbar); + toolbar.setTitle("LedD"); + mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.app_name, R.string.app_name) { /** Called when a drawer has settled in a completely closed state. */ @@ -66,24 +68,9 @@ public class ColorActivity extends AppCompatActivity { mDrawerLayout.setDrawerListener(mDrawerToggle); // enable Homebutton navigation to drawer - //getSupportActionBar().setDisplayHomeAsUpEnabled(true); - //getSupportActionBar().setHomeButtonEnabled(true); - // getSupportActionBar().setIcon(R.drawable.ic_bar); - - if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean( - "firstRun", true)) { - System.out.println("first run!"); - firstRun = true; - Intent intent = new Intent(this, AssistantActivity.class); - startActivity(intent); - } - - if (ColorApplication.getInstance().isAPIActive()) { - this.mAPI = ColorApplication.getInstance().getAPI(); - System.out.println("API active!"); - } else { - System.out.println("API not active :("); - this.finish(); + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(true); } } @@ -116,12 +103,6 @@ public class ColorActivity extends AppCompatActivity { } // Handle your other action bar items... - switch (item.getItemId()) { - case R.id.action_settings: - Intent intent = new Intent(this, SettingsActivity.class); - startActivity(intent); - return super.onOptionsItemSelected(item); - } return super.onOptionsItemSelected(item); } @@ -140,8 +121,17 @@ public class ColorActivity extends AppCompatActivity { return super.onKeyDown(keyCode, event); } + @DebugLog + @Override + protected void onPause() { + super.onPause(); + ColorApplication.getInstance().teardown(); + } + + @DebugLog @Override protected void onDestroy() { super.onDestroy(); + ColorApplication.getInstance().teardown(); } } diff --git a/app/src/main/java/com/idlegandalf/ledd/ColorApplication.java b/app/src/main/java/com/idlegandalf/ledd/ColorApplication.java index 2ce0b90..3e0bb71 100644 --- a/app/src/main/java/com/idlegandalf/ledd/ColorApplication.java +++ b/app/src/main/java/com/idlegandalf/ledd/ColorApplication.java @@ -3,14 +3,20 @@ package com.idlegandalf.ledd; import android.app.Application; import android.preference.PreferenceManager; -import com.idlegandalf.ledd.components.LEDDHelper; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.idlegandalf.ledd.components.Host; +import com.idlegandalf.ledd.helper.LedDHelper; import java.io.IOException; +import java.util.HashMap; +import java.util.Set; + +import hugo.weaving.DebugLog; public class ColorApplication extends Application { private static ColorApplication singleton; - private LEDDHelper mAPI = null; - private boolean mAPIActive = false; + private HashMap ledDHelpers; public static ColorApplication getInstance() { return singleton; @@ -20,36 +26,43 @@ public class ColorApplication extends Application { public void onCreate() { super.onCreate(); singleton = this; - try { - initAPI(); - } catch (IOException e) { - e.printStackTrace(); + + 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()); + } + + public LedDHelper getHelperForHost(Host host) throws IOException { + System.out.println("host: " + host.toString()); + if (ledDHelpers.containsKey(host)) { + return ledDHelpers.get(host); + } else { + LedDHelper dHelper = new LedDHelper(host, getApplicationContext()); + ledDHelpers.put(host, dHelper); + return dHelper; } } - public LEDDHelper getAPI() { - return this.mAPI; - } - - public void initAPI() throws IOException { - if (PreferenceManager.getDefaultSharedPreferences(this) - .contains("pref_key_host")) { - - mAPI = new LEDDHelper(PreferenceManager - .getDefaultSharedPreferences(this).getString( - "pref_key_host", ""), - PreferenceManager - .getDefaultSharedPreferences(this).getInt( - "pref_key_port", 8825), - getApplicationContext() - ); - - this.mAPIActive = true; - System.out.println("api is declared as active now"); + @DebugLog + public void teardown() { + for (LedDHelper dHelper : ledDHelpers.values()) { + dHelper.teardown(); } - } - public boolean isAPIActive() { - return mAPIActive; + PreferenceManager.getDefaultSharedPreferences(this).edit().putString("hosts", new Gson().toJson(ledDHelpers.keySet())).commit(); } } diff --git a/app/src/main/java/com/idlegandalf/ledd/ColorService.java b/app/src/main/java/com/idlegandalf/ledd/ColorService.java deleted file mode 100644 index c5c137f..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/ColorService.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.idlegandalf.ledd; - -import android.app.Service; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.Process; -import android.widget.Toast; - -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.SocketException; - -public class ColorService extends Service { - private Looper mServiceLooper; - private ServiceHandler mServiceHandler; - private DatagramSocket socket; - - // Handler that receives messages from the thread - private final class ServiceHandler extends Handler { - public ServiceHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - Bundle msgdata = msg.getData(); - - if (msgdata != null) { - try { - byte[] data = msgdata.getString("json").getBytes(); - DatagramPacket packet = new DatagramPacket(data, data.length, - InetAddress.getByName(msgdata.getString("ip")), msgdata.getInt("port")); - socket.send(packet); - } catch (Exception e) { - e.printStackTrace(); - } - } - - // Stop the service using the startId, so that we don't stop - // the service in the middle of handling another job - //stopSelf(msg.arg1); - } - } - - @Override - public void onCreate() { - Toast.makeText(this, "ColorService started", Toast.LENGTH_SHORT).show(); - - try { - socket = new DatagramSocket(); - } catch (SocketException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - // Start up the thread running the service. Note that we create a - // separate thread because the service normally runs in the process's - // main thread, which we don't want to block. We also make it - // background priority so CPU-intensive work will not disrupt our UI. - HandlerThread thread = new HandlerThread("ServiceStartArguments", - Process.THREAD_PRIORITY_BACKGROUND); - thread.start(); - - // Get the HandlerThread's Looper and use it for our Handler - mServiceLooper = thread.getLooper(); - mServiceHandler = new ServiceHandler(mServiceLooper); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - // For each start request, send a message to start a job and deliver the - // start ID so we know which request we're stopping when we finish the - // job - Message msg = mServiceHandler.obtainMessage(); - msg.arg1 = startId; - msg.setData(intent.getExtras()); - mServiceHandler.sendMessage(msg); - - // If we get killed, after returning from here, restart - return START_STICKY; - } - - @Override - public IBinder onBind(Intent intent) { - // We don't provide binding, so return null - return null; - } - - @Override - public void onDestroy() { - socket.close(); - Toast.makeText(this, "ColorService stopped", Toast.LENGTH_SHORT).show(); - } -} diff --git a/app/src/main/java/com/idlegandalf/ledd/DrawerFragment.java b/app/src/main/java/com/idlegandalf/ledd/DrawerFragment.java index 5187e2a..d9d4556 100644 --- a/app/src/main/java/com/idlegandalf/ledd/DrawerFragment.java +++ b/app/src/main/java/com/idlegandalf/ledd/DrawerFragment.java @@ -5,12 +5,26 @@ import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.LinearLayout; + +import butterknife.Bind; +import butterknife.ButterKnife; +import butterknife.OnClick; public class DrawerFragment extends Fragment { - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.drawer_fragment, container, false); - } + @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/ProgressBarActionBarActivity.java b/app/src/main/java/com/idlegandalf/ledd/ProgressBarActionBarActivity.java deleted file mode 100644 index cfa606e..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/ProgressBarActionBarActivity.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.idlegandalf.ledd; - -import android.support.v7.app.AppCompatActivity; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; - -public abstract class ProgressBarActionBarActivity extends AppCompatActivity { - private ProgressBar mProgressBar; - - public void setContentView(View view) { - init().addView(view); - } - - public void setContentView(int layoutResID) { - getLayoutInflater().inflate(layoutResID, init(), true); - } - - public void setContentView(View view, ViewGroup.LayoutParams params) { - init().addView(view, params); - } - - private ViewGroup init() { - super.setContentView(R.layout.progress); - mProgressBar = (ProgressBar) findViewById(R.id.activity_bar); - return (ViewGroup) findViewById(R.id.activity_frame); - } - - protected ProgressBar getProgressBar() { - return mProgressBar; - } -} diff --git a/app/src/main/java/com/idlegandalf/ledd/SettingsActivity.java b/app/src/main/java/com/idlegandalf/ledd/SettingsActivity.java index 3f06731..22818c9 100644 --- a/app/src/main/java/com/idlegandalf/ledd/SettingsActivity.java +++ b/app/src/main/java/com/idlegandalf/ledd/SettingsActivity.java @@ -7,11 +7,12 @@ public class SettingsActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + // Display the fragment as the main content. - getFragmentManager().beginTransaction() - .replace(android.R.id.content, new SettingsFragment()) - .commit(); + getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit(); } } diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java new file mode 100644 index 0000000..13b102a --- /dev/null +++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java @@ -0,0 +1,13 @@ +package com.idlegandalf.ledd.callbacks; + +public interface AddControllerCallback { + /** + * Returns when a controller was added successfully + * + * @param cid the new controller's id + */ + void onControllerAdded(int cid); + + void onAddFailed(String msg, String detail); +} + diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java new file mode 100644 index 0000000..535456c --- /dev/null +++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java @@ -0,0 +1,9 @@ +package com.idlegandalf.ledd.callbacks; + +import com.idlegandalf.ledd.components.HSV; + +public interface RecieveColorCallback { + void onColorRecieved(HSV color); + + void onRecievFailed(String msg); +} diff --git a/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java b/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java new file mode 100644 index 0000000..49e07ba --- /dev/null +++ b/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java @@ -0,0 +1,10 @@ +package com.idlegandalf.ledd.components; + + +import org.json.JSONObject; + +public abstract class AnswerTask implements Runnable { + + public 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 3192bf4..600c7cc 100644 --- a/app/src/main/java/com/idlegandalf/ledd/components/Controller.java +++ b/app/src/main/java/com/idlegandalf/ledd/components/Controller.java @@ -9,5 +9,8 @@ import lombok.Setter; @Getter @Setter public class Controller { + private int channels; + private String address; + private int i2c_device; private ArrayList stripes; } 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 8cf72f6..77502e0 100644 --- a/app/src/main/java/com/idlegandalf/ledd/components/HSV.java +++ b/app/src/main/java/com/idlegandalf/ledd/components/HSV.java @@ -6,7 +6,17 @@ import lombok.Setter; @Getter @Setter public class HSV { - private float hue; - private float saturation; - private float value; + private double hue; + private double saturation; + private double value; + + public HSV(double h, double s, double v) { + this.hue = h; + this.saturation = s; + this.value = v; + } + + public HSV() { + + } } diff --git a/app/src/main/java/com/idlegandalf/ledd/components/Host.java b/app/src/main/java/com/idlegandalf/ledd/components/Host.java index 6f98b79..0768040 100644 --- a/app/src/main/java/com/idlegandalf/ledd/components/Host.java +++ b/app/src/main/java/com/idlegandalf/ledd/components/Host.java @@ -24,4 +24,22 @@ public class Host { public String toString() { return address + ":" + port; } + + @Override + public boolean equals(Object o) { + if (o instanceof Host) { + if (address.equals(((Host) o).address) && port == ((Host) o).port) return true; + } + return false; + } + + @Override + public int hashCode() { + int result = 23; + + result = 45 * result + port; + result = 45 * result + address.hashCode(); + + return result; + } } diff --git a/app/src/main/java/com/idlegandalf/ledd/components/LEDDHelper.java b/app/src/main/java/com/idlegandalf/ledd/components/LEDDHelper.java deleted file mode 100644 index 85f06b1..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/components/LEDDHelper.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.idlegandalf.ledd.components; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; - -import com.idlegandalf.ledd.ColorService; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; - -public class LEDDHelper { - private String mAddr; - private int mPort; - private Context context; - - final String ACTION_SETCOLOR = "set_color"; - final String ACTION_GETCOLOR = "get_color"; - - public LEDDHelper(String ip, int port, Context appl) throws UnsupportedEncodingException, - IOException { - this.mAddr = ip; - this.mPort = port; - this.context = appl; - } - - /** - * Send RGB values to dameon using the stripeid - * @param sid Stripeid - * @param color Color in HSV format - * @throws JSONException not valid json - * @throws IOException socket error - */ - public void sendColor(int sid, HSV color) - throws JSONException, IOException { - JSONObject jnson = new JSONObject(); - JSONArray hsv = new JSONArray(); - - hsv.put(color.getHue()); - hsv.put(color.getSaturation()); - hsv.put(color.getValue()); - - jnson.put("action", ACTION_SETCOLOR); - jnson.put("sid", sid); - jnson.put("color", hsv); - - sendJSON(jnson.toString()); - } - - private void sendJSON(String json) throws IOException { - Intent intent = new Intent(context, ColorService.class); - Bundle bndl = new Bundle(); - bndl.putString("json", json); - bndl.putString("host", this.mAddr); - bndl.putInt("port", mPort); - intent.putExtras(bndl); - context.startService(intent); - } - - public void onDestroy() { - Intent intent = new Intent(context, ColorService.class); - context.stopService(intent); - } -} diff --git a/app/src/main/java/com/idlegandalf/ledd/components/RGBStripe.java b/app/src/main/java/com/idlegandalf/ledd/components/RGBStripe.java index d964868..bf360b5 100644 --- a/app/src/main/java/com/idlegandalf/ledd/components/RGBStripe.java +++ b/app/src/main/java/com/idlegandalf/ledd/components/RGBStripe.java @@ -6,12 +6,12 @@ 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; + private int id; + private int channelRed; + private int channelGreen; + private int channelBlue; + private String nice_name; + private HSV color; + private double gammaCorrection; } \ 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 new file mode 100644 index 0000000..b06b475 --- /dev/null +++ b/app/src/main/java/com/idlegandalf/ledd/components/Sendable.java @@ -0,0 +1,35 @@ +package com.idlegandalf.ledd.components; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.UUID; + +import lombok.Getter; + +@Getter +public class Sendable { + private Host recipient; + private JSONObject message; + private String ref; + private AnswerTask onAnswer; + + public Sendable(JSONObject msg, AnswerTask task, Host host) throws JSONException { + this(msg, UUID.randomUUID().toString(), task, host); + } + + public Sendable(JSONObject msg, String ref, AnswerTask task, Host recipient) throws JSONException { + this.message = msg; + this.ref = ref; + this.message.put("ref", ref); + this.onAnswer = task; + this.recipient = recipient; + } + + public void onResponse(JSONObject object) { + if (onAnswer != null) { + onAnswer.response = object; + onAnswer.run(); + } + } +} 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 d625d53..f114546 100644 --- a/app/src/main/java/com/idlegandalf/ledd/components/StripeGroup.java +++ b/app/src/main/java/com/idlegandalf/ledd/components/StripeGroup.java @@ -1,62 +1,64 @@ 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 { - private String mNiceName; - private String mDescription; - private ArrayList mStripes; + private String mNiceName; + private String mDescription; + private ArrayList mStripes; - public String getNiceName() { - return mNiceName; - } + public String getNiceName() { + return mNiceName; + } - public void setNiceName(String mNiceName) { - this.mNiceName = mNiceName; - } + public void setNiceName(String mNiceName) { + this.mNiceName = mNiceName; + } - public String getDescription() { - return mDescription; - } + public String getDescription() { + return mDescription; + } - public void setDescription(String mDescription) { - this.mDescription = mDescription; - } - - public RGBStripe getStripeByPos(int pos) { - return mStripes.get(pos); - } - - public RGBStripe getStripeById(int sid) { - for (int i = 0; i < mStripes.size(); i++) { - if (mStripes.get(i).getId() == sid) { - return mStripes.get(i); - } - } - return null; - } - - public void setRGB(int r, int g, int b, LEDDHelper api) throws JSONException, IOException { - for (int i = 0; i < mStripes.size(); i++) { - //mStripes.get(i).setRGB(r, g, b, api); - } - } - - public int addStripe(RGBStripe stripe) { - mStripes.add(stripe); - return mStripes.size()-1; - } - - public void removeStripeByObject(RGBStripe stripe) { - for (int i = 0; i < mStripes.size(); i++) { - if (mStripes.get(i).getId() == stripe.getId()) { - mStripes.remove(i); - return; - } - } - } + public void setDescription(String mDescription) { + this.mDescription = mDescription; + } + + public RGBStripe getStripeByPos(int pos) { + return mStripes.get(pos); + } + + public RGBStripe getStripeById(int sid) { + for (int i = 0; i < mStripes.size(); i++) { + if (mStripes.get(i).getId() == sid) { + return mStripes.get(i); + } + } + return null; + } + + public void setRGB(int r, int g, int b, LedDHelper api) throws JSONException, IOException { + for (int i = 0; i < mStripes.size(); i++) { + //mStripes.get(i).setRGB(r, g, b, api); + } + } + + public int addStripe(RGBStripe stripe) { + mStripes.add(stripe); + return mStripes.size() - 1; + } + + public void removeStripeByObject(RGBStripe stripe) { + for (int i = 0; i < mStripes.size(); i++) { + if (mStripes.get(i).getId() == stripe.getId()) { + mStripes.remove(i); + return; + } + } + } } diff --git a/app/src/main/java/com/idlegandalf/ledd/fragments/StepOneFragment.java b/app/src/main/java/com/idlegandalf/ledd/fragments/StepOneFragment.java deleted file mode 100644 index 91491af..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/fragments/StepOneFragment.java +++ /dev/null @@ -1,233 +0,0 @@ -package com.idlegandalf.ledd.fragments; - -import android.app.Fragment; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.design.widget.Snackbar; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Toast; - -import com.idlegandalf.ledd.R; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.util.ArrayList; - -import butterknife.Bind; -import butterknife.ButterKnife; - -public class StepOneFragment extends Fragment { - @Bind(R.id.step2_back) - Button mBack; - @Bind(R.id.ipSelect) - EditText mAutoIP; - @Bind(R.id.step2_next) - Button mTest; - @Bind(R.id.portSelect) - EditText mAutoPort; - ArrayList mIPList = new ArrayList<>(); - boolean isAutoDetected = false; - - - public static StepOneFragment newInstance(String addrs) { - Bundle args = new Bundle(); - - args.putString("ips", addrs); - - StepOneFragment fragment = new StepOneFragment(); - fragment.setArguments(args); - return fragment; - } - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.fragment_step1, container, false); - ButterKnife.bind(this, v); - - return v; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - String ips = getArguments().getString("ips"); - - if (ips != null) { - if (!ips.isEmpty()) { - for (String string : ips.split(";")) { - if (string.isEmpty()) { - System.out.println("added addr " + string); - mIPList.add(string); - } - } - if (mIPList.size() > 0) isAutoDetected = true; - } - } - - mBack.setOnClickListener(nextClickListener); - mTest.setOnClickListener(nextClickListener); - } - - private OnClickListener nextClickListener = new OnClickListener() { - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.step2_back: - getActivity().onBackPressed(); - break; - case R.id.step2_next: - System.out.println("forward calling!"); - testController(); - break; - default: - break; - } - } - }; - - private void testController() { - ConnectivityManager connManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); - - if (mWifi.isConnected()) { - setInputState(false); - if (!isValidAddrInput(mAutoIP, mAutoPort)) { - setInputState(true); - return; - } - getActivity().setProgressBarIndeterminateVisibility(true); - getActivity().setProgressBarVisibility(true); - new pokeController().execute(mAutoIP.toString(), mAutoPort.toString()); - } else { - Toast.makeText(getActivity().getApplicationContext(), "please connect WiFi", Toast.LENGTH_LONG).show(); - } - } - - private class pokeController extends AsyncTask { - protected Boolean doInBackground(String... ippo) { - try { - InetAddress controller = InetAddress.getByName(ippo[0]); - int port = Integer.parseInt(ippo[1]); - - DatagramSocket socket = new DatagramSocket(); - String hstr = new JSONObject().put("action", 5).toString(); - - DatagramPacket hello = new DatagramPacket(hstr.getBytes(), hstr.getBytes().length); - - hello.setPort(port); - socket.setSoTimeout(100); - - if (!controller.isReachable(50)) { - socket.close(); - return false; - } - - hello.setAddress(controller); - socket.send(hello); - - DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); - try { - socket.receive(packet); - } catch (SocketTimeoutException e) { - socket.close(); - return false; - } - - Toast.makeText(getActivity().getApplicationContext(), new String(packet.getData(), 0, packet.getLength()), Toast.LENGTH_LONG).show(); - - JSONObject resjson = new JSONObject(new String(packet.getData(), 0, packet.getLength())); - - if (resjson.getInt("action") != 5) { - socket.close(); - return false; - } - - socket.close(); - } catch (SocketException e1) { - return false; - } catch (IOException e1) { - return false; - } catch (JSONException e) { - return false; - } - - return true; - } - - protected void onProgressUpdate(Void... progress) { - - } - - protected void onPostExecute(Boolean result) { - getActivity().setProgressBarIndeterminateVisibility(false); - getActivity().setProgressBarVisibility(false); - setInputState(true); - if (result) { - Snackbar.make(getActivity().findViewById(R.id.linlayp), "found daemon running on " + - "address " + mAutoIP.toString() + ":" + mAutoPort.toString(), Snackbar.LENGTH_LONG).show(); - } else { - Snackbar.make(getActivity().findViewById(R.id.linlayp), "No running daemon " + "found", Snackbar.LENGTH_LONG).show(); - } - } - } - - private boolean isValidIPFromEditText(EditText atv) { - String exip[] = atv.toString().trim().split("\\."); - if (exip.length != 4) return false; - - for (String string : exip) { - if (!string.isEmpty()) { - try { - if (Integer.parseInt(string) < 0 || Integer.parseInt(string) > 255) return false; - } catch (NumberFormatException e) { - return false; - } - } - } - - return true; - } - - private boolean isValidPortFromEditText(EditText atv) { - return !atv.toString().isEmpty() && Integer.parseInt(atv.toString()) > 1023 && Integer.parseInt(atv.toString()) <= 65535; - } - - private boolean isValidAddrInput(EditText ipatv, EditText portatv) { - if (!isValidIPFromEditText(ipatv)) { - Snackbar.make(getActivity().findViewById(R.id.linlayp), "Please enter valid IP " + "address", Snackbar.LENGTH_LONG).show(); - - return false; - } - if (!isValidPortFromEditText(portatv)) { - Snackbar.make(getActivity().findViewById(R.id.linlayp), "Please enter valid port " + "(1024-65535)", Snackbar.LENGTH_LONG).show(); - - return false; - } - return true; - } - - private void setInputState(boolean state) { - mAutoIP.setEnabled(state); - mAutoPort.setEnabled(state); - mBack.setEnabled(state); - mTest.setEnabled(state); - } -} diff --git a/app/src/main/java/com/idlegandalf/ledd/fragments/StepStripesFragment.java b/app/src/main/java/com/idlegandalf/ledd/fragments/StepStripesFragment.java deleted file mode 100644 index 1e8ecc5..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/fragments/StepStripesFragment.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.idlegandalf.ledd.fragments; - -import android.app.Fragment; - -public class StepStripesFragment extends Fragment { - -} diff --git a/app/src/main/java/com/idlegandalf/ledd/fragments/WelcomeFragment.java b/app/src/main/java/com/idlegandalf/ledd/fragments/WelcomeFragment.java deleted file mode 100644 index b63ac5c..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/fragments/WelcomeFragment.java +++ /dev/null @@ -1,218 +0,0 @@ -package com.idlegandalf.ledd.fragments; - -import android.app.Fragment; -import android.content.Context; -import android.net.nsd.NsdManager; -import android.net.nsd.NsdServiceInfo; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.idlegandalf.ledd.AssistantActivity; -import com.idlegandalf.ledd.R; -import com.idlegandalf.ledd.components.Host; - -import java.net.Inet4Address; -import java.util.ArrayList; - -import butterknife.Bind; -import butterknife.ButterKnife; - -public class WelcomeFragment extends Fragment { - - @Bind(R.id.step1_auto) - Button mAuto; - @Bind(R.id.step1_manual) - Button mManual; - @Bind(R.id.host_container) - LinearLayout hostContainer; - @Bind(R.id.toolbar) - Toolbar toolbar; - - NsdManager mNsdManager; - final String TAG = "ColorD"; - NsdManager.DiscoveryListener mDiscoveryListener; - NsdManager.ResolveListener mResolveListener; - ArrayList hosts; - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.fragment_welcome, container, false); - ButterKnife.bind(this, v); - return v; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - mAuto.setOnClickListener(nextClickListener); - mManual.setOnClickListener(nextClickListener); - - ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); - - hosts = new ArrayList<>(); - - mResolveListener = new NsdManager.ResolveListener() { - - @Override - public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { - // Called when the resolve fails. Use the error code to debug. - Log.e(TAG, "Resolve failed" + errorCode); - } - - @Override - public void onServiceResolved(final NsdServiceInfo serviceInfo) { - Log.e(TAG, "Resolve Succeeded. " + serviceInfo); - - if (serviceInfo.getHost() instanceof Inet4Address) { - Log.d(TAG, "Found IPv4! Yay!"); - - final Host fHost = new Host(serviceInfo.getHost().getHostAddress(), serviceInfo.getPort()); - - if (!hosts.contains(fHost)) { - 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.welcome_host); - - host.setText(serviceInfo.getHost().getHostAddress() + ":" + serviceInfo.getPort()); - host.setTag(serviceInfo); - - View.OnClickListener listener = new View.OnClickListener() { - @Override - public void onClick(View v) { - StepOneFragment stepOneFragment = StepOneFragment.newInstance(hosts.get((int) v.getTag()).toString()); - ((AssistantActivity) getActivity()).switchFragment(stepOneFragment); - } - }; - - v.setOnClickListener(listener); - host.setOnClickListener(listener); - - v.setTag(hosts.size()); - host.setTag(hosts.size()); - - hostContainer.addView(v); - hosts.add(fHost); - } - }); - } - } - } - }; - - mDiscoveryListener = new NsdManager.DiscoveryListener() { - - // Called as soon as service discovery begins. - @Override - public void onDiscoveryStarted(String regType) { - Log.d(TAG, "Service discovery started"); - } - - @Override - public void onServiceFound(NsdServiceInfo service) { - // A service was found! Do something with it. - Log.d(TAG, "Service discovery success " + service); - if (!service.getServiceType().equals("_ledd._tcp.")) { - // Service type is the string containing the protocol and - // transport layer for this service. - Log.d(TAG, "Unknown Service Type: " + service.getServiceType()); - } else { - mNsdManager.resolveService(service, mResolveListener); - } - } - - @Override - public void onServiceLost(NsdServiceInfo service) { - // When the network service is no longer available. - // Internal bookkeeping code goes here. - Log.e(TAG, "service lost" + service); - } - - @Override - public void onDiscoveryStopped(String serviceType) { - Log.i(TAG, "Discovery stopped: " + serviceType); - } - - @Override - public void onStartDiscoveryFailed(String serviceType, int errorCode) { - Log.e(TAG, "Discovery failed: Error code:" + errorCode); - mNsdManager.stopServiceDiscovery(this); - } - - @Override - public void onStopDiscoveryFailed(String serviceType, int errorCode) { - Log.e(TAG, "Discovery failed: Error code:" + errorCode); - mNsdManager.stopServiceDiscovery(this); - } - }; - } - - private View.OnClickListener nextClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.step1_auto: - System.out.println("auto pressed"); - //getProgressBar().setIndeterminate(true); - //setProgressBarIndeterminateVisibility(true); - //setProgressBarVisibility(true); - //setProgressBarIndeterminate(true); - setButtonState(false); - - mNsdManager = (NsdManager) getActivity().getSystemService(Context.NSD_SERVICE); - mNsdManager.discoverServices("_ledd._tcp", NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener); - - break; - case R.id.step1_manual: - System.out.println("manual pressed"); - setButtonState(false); - StepOneFragment stepOneFragment = StepOneFragment.newInstance(null); - ((AssistantActivity) getActivity()).switchFragment(stepOneFragment); - setButtonState(true); - break; - default: - break; - } - } - }; - - void setButtonState(boolean state) { - mAuto.setEnabled(state); - mManual.setEnabled(state); - } - - @Override - public void onPause() { - if (mNsdManager != null) { - tearDown(); - setButtonState(true); - } - - super.onPause(); - } - - @Override - public void onDestroy() { - if (mNsdManager != null) tearDown(); - super.onDestroy(); - } - - // NsdHelper's tearDown method - public void tearDown() { - mNsdManager.stopServiceDiscovery(mDiscoveryListener); - } -} diff --git a/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java b/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java new file mode 100644 index 0000000..e25f798 --- /dev/null +++ b/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java @@ -0,0 +1,155 @@ +package com.idlegandalf.ledd.helper; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; + +import com.idlegandalf.ledd.callbacks.AddControllerCallback; +import com.idlegandalf.ledd.callbacks.RecieveColorCallback; +import com.idlegandalf.ledd.components.AnswerTask; +import com.idlegandalf.ledd.components.HSV; +import com.idlegandalf.ledd.components.Host; +import com.idlegandalf.ledd.services.ColorService; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; + +import hugo.weaving.DebugLog; + +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; + private Context context; + private ColorService.ColorBinder binderService; + private boolean mBound = false; + ServiceConnection mConnection = new ServiceConnection() { + + @Override + public void onServiceConnected(ComponentName className, IBinder service) { + System.out.println("service bound!"); + binderService = (ColorService.ColorBinder) service; + mBound = true; + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mBound = false; + } + }; + + public LedDHelper(Host host, Context appl) throws IOException { + this.host = host; + this.context = appl; + + Intent intent = new Intent(appl, ColorService.class); + appl.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + } + + /** + * 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 + * @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 { + JSONObject jnson = new JSONObject(); + + jnson.put("action", ACTION_ADDCONTROLLER); + jnson.put("channels", channels); + jnson.put("i2c_dev", i2c_dev); + jnson.put("address", address); + + sendJSON(jnson, new AnswerTask() { + @Override + public void run() { + try { + if (response.getBoolean("success")) { + callback.onControllerAdded(response.getInt("cid")); + } else { + callback.onAddFailed(response.getString("message"), response.getString("message_detail")); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + /** + * Set color using the stripeid + * + * @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 { + JSONObject jnson = new JSONObject(); + JSONObject hsv = new JSONObject(); + + hsv.put("h", color.getHue()); + hsv.put("s", color.getSaturation()); + hsv.put("v", color.getValue()); + + jnson.put("action", ACTION_SETCOLOR); + jnson.put("sid", sid); + jnson.put("color", hsv); + + sendJSON(jnson, null); + } + + /** + * Get color using the stripeid + * + * @param sid Stripeid + * @throws JSONException no valid json + * @throws IOException socket error + */ + public void getColor(int sid, final RecieveColorCallback callback) throws JSONException, IOException { + JSONObject jnson = new JSONObject(); + + jnson.put("action", ACTION_GETCOLOR); + jnson.put("sid", sid); + + sendJSON(jnson, new AnswerTask() { + @Override + public void run() { + 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"))); + } else { + callback.onRecievFailed(response.getString("message")); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + private void sendJSON(JSONObject json, AnswerTask task) throws IOException, JSONException { + if (mBound) binderService.queueSend(host, json, task); + } + + @DebugLog + public void teardown() { + if (mBound) { + context.unbindService(mConnection); + mBound = false; + } + } +} diff --git a/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java b/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java new file mode 100644 index 0000000..d29a524 --- /dev/null +++ b/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java @@ -0,0 +1,143 @@ +package com.idlegandalf.ledd.services; + +import android.app.Service; +import android.content.Intent; +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.Sendable; +import com.koushikdutta.async.AsyncServer; +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 org.json.JSONException; +import org.json.JSONObject; + +import java.io.UnsupportedEncodingException; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.concurrent.LinkedBlockingQueue; + +import hugo.weaving.DebugLog; + +public class ColorService extends Service { + private final IBinder mBinder = new ColorBinder(); + private LinkedBlockingQueue queue; + private Worker worker; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return -1; + } + + @Override + public IBinder onBind(Intent intent) { + queue = new LinkedBlockingQueue<>(); + worker = new Worker<>(queue); + new Thread(worker).start(); + + return mBinder; + } + + @Override + public void onDestroy() { + worker.stop(); + } + + private static class Worker implements Runnable { + private final LinkedBlockingQueue workQueue; + private HashMap socketHashMap; + private HashMap sendableHashMap; + + 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(); + } + + if (resp != null) { + try { + if (sendableHashMap.containsKey(resp.getString("ref"))) { + sendableHashMap.get(resp.getString("ref")).onResponse(resp); + sendableHashMap.remove(resp.getString("ref")); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + }; + + public Worker(LinkedBlockingQueue workQueue) { + this.workQueue = workQueue; + this.socketHashMap = new HashMap<>(); + this.sendableHashMap = new HashMap<>(); + } + + @Override + @DebugLog + public void run() { + while (!Thread.currentThread().isInterrupted()) { + try { + final T item = workQueue.take(); + + if (item instanceof Sendable) { + 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 + ("UTF-8"), null); + sendableHashMap.put(((Sendable) item).getRef(), (Sendable) item); + } 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) item).getRecipient(), socket); + + if (!workQueue.contains(item)) { + workQueue.add(item); + } + } else { + ex.printStackTrace(); + } + } + }); + } + } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + break; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + } + + public void stop() { + Thread.currentThread().interrupt(); + } + } + + public class ColorBinder extends Binder { + public String queueSend(Host 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/java/com/idlegandalf/ledd/utils/ColorPicker.java b/app/src/main/java/com/idlegandalf/ledd/utils/ColorPicker.java deleted file mode 100644 index 52ebfd6..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/utils/ColorPicker.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2013 Piotr Adamus - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.idlegandalf.ledd.utils; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ComposeShader; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Paint.Join; -import android.graphics.Paint.Style; -import android.graphics.Path; -import android.graphics.PorterDuff; -import android.graphics.RadialGradient; -import android.graphics.RectF; -import android.graphics.Shader.TileMode; -import android.graphics.SweepGradient; -import android.os.Bundle; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; - -public class ColorPicker extends View { - - /** - * Customizable display parameters (in percents) - */ - private final int paramOuterPadding = 2; // outer padding of the whole color picker view - private final int paramInnerPadding = 5; // distance between value slider wheel and inner color wheel - private final int paramValueSliderWidth = 10; // width of the value slider - private final int paramArrowPointerSize = 4; // size of the arrow pointer; set to 0 to hide the pointer - - private Paint colorWheelPaint; - private Paint valueSliderPaint; - - private Paint colorViewPaint; - - private Paint colorPointerPaint; - private RectF colorPointerCoords; - - private Paint valuePointerPaint; - private Paint valuePointerArrowPaint; - - private RectF outerWheelRect; - private RectF innerWheelRect; - - private Path colorViewPath; - private Path valueSliderPath; - private Path arrowPointerPath; - - private Bitmap colorWheelBitmap; - - private int valueSliderWidth; - private int innerPadding; - private int outerPadding; - - private int arrowPointerSize; - private int outerWheelRadius; - private int innerWheelRadius; - private int colorWheelRadius; - - private Matrix gradientRotationMatrix; - - /** Currently selected color */ - private float[] colorHSV = new float[] { 0f, 0f, 1f }; - - public ColorPicker(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } - - public ColorPicker(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - public ColorPicker(Context context) { - super(context); - init(); - } - - private void init() { - - colorPointerPaint = new Paint(); - colorPointerPaint.setStyle(Style.STROKE); - colorPointerPaint.setStrokeWidth(2f); - colorPointerPaint.setARGB(128, 0, 0, 0); - - valuePointerPaint = new Paint(); - valuePointerPaint.setStyle(Style.STROKE); - valuePointerPaint.setStrokeWidth(2f); - - valuePointerArrowPaint = new Paint(); - - colorWheelPaint = new Paint(); - colorWheelPaint.setAntiAlias(true); - colorWheelPaint.setDither(true); - - valueSliderPaint = new Paint(); - valueSliderPaint.setAntiAlias(true); - valueSliderPaint.setDither(true); - - colorViewPaint = new Paint(); - colorViewPaint.setAntiAlias(true); - - colorViewPath = new Path(); - valueSliderPath = new Path(); - arrowPointerPath = new Path(); - - outerWheelRect = new RectF(); - innerWheelRect = new RectF(); - - colorPointerCoords = new RectF(); - - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int widthSize = MeasureSpec.getSize(widthMeasureSpec); - int heightSize = MeasureSpec.getSize(heightMeasureSpec); - int size = Math.min(widthSize, heightSize); - setMeasuredDimension(size, size); - } - - @SuppressLint("DrawAllocation") - @Override - protected void onDraw(Canvas canvas) { - - int centerX = getWidth() / 2; - int centerY = getHeight() / 2; - - // drawing color wheel - - canvas.drawBitmap(colorWheelBitmap, centerX - colorWheelRadius, centerY - colorWheelRadius, null); - - // drawing color view - - colorViewPaint.setColor(Color.HSVToColor(colorHSV)); - canvas.drawPath(colorViewPath, colorViewPaint); - - // drawing value slider - - float[] hsv = new float[] { colorHSV[0], colorHSV[1], 1f }; - - SweepGradient sweepGradient = new SweepGradient(centerX, centerY, new int[] { Color.BLACK, Color.HSVToColor(hsv), Color.WHITE }, null); - sweepGradient.setLocalMatrix(gradientRotationMatrix); - valueSliderPaint.setShader(sweepGradient); - - canvas.drawPath(valueSliderPath, valueSliderPaint); - - // drawing color wheel pointer - - float hueAngle = (float) Math.toRadians(colorHSV[0]); - int colorPointX = (int) (-Math.cos(hueAngle) * colorHSV[1] * colorWheelRadius) + centerX; - int colorPointY = (int) (-Math.sin(hueAngle) * colorHSV[1] * colorWheelRadius) + centerY; - - float pointerRadius = 0.075f * colorWheelRadius; - int pointerX = (int) (colorPointX - pointerRadius / 2); - int pointerY = (int) (colorPointY - pointerRadius / 2); - - colorPointerCoords.set(pointerX, pointerY, pointerX + pointerRadius, pointerY + pointerRadius); - canvas.drawOval(colorPointerCoords, colorPointerPaint); - - // drawing value pointer - - valuePointerPaint.setColor(Color.HSVToColor(new float[] { 0f, 0f, 1f - colorHSV[2] })); - - double valueAngle = (colorHSV[2] - 0.5f) * Math.PI; - float valueAngleX = (float) Math.cos(valueAngle); - float valueAngleY = (float) Math.sin(valueAngle); - - canvas.drawLine(valueAngleX * innerWheelRadius + centerX, valueAngleY * innerWheelRadius + centerY, valueAngleX * outerWheelRadius + centerX, - valueAngleY * outerWheelRadius + centerY, valuePointerPaint); - - // drawing pointer arrow - - if (arrowPointerSize > 0) { - drawPointerArrow(canvas); - } - - } - - private void drawPointerArrow(Canvas canvas) { - - int centerX = getWidth() / 2; - int centerY = getHeight() / 2; - - double tipAngle = (colorHSV[2] - 0.5f) * Math.PI; - double leftAngle = tipAngle + Math.PI / 96; - double rightAngle = tipAngle - Math.PI / 96; - - double tipAngleX = Math.cos(tipAngle) * outerWheelRadius; - double tipAngleY = Math.sin(tipAngle) * outerWheelRadius; - double leftAngleX = Math.cos(leftAngle) * (outerWheelRadius + arrowPointerSize); - double leftAngleY = Math.sin(leftAngle) * (outerWheelRadius + arrowPointerSize); - double rightAngleX = Math.cos(rightAngle) * (outerWheelRadius + arrowPointerSize); - double rightAngleY = Math.sin(rightAngle) * (outerWheelRadius + arrowPointerSize); - - arrowPointerPath.reset(); - arrowPointerPath.moveTo((float) tipAngleX + centerX, (float) tipAngleY + centerY); - arrowPointerPath.lineTo((float) leftAngleX + centerX, (float) leftAngleY + centerY); - arrowPointerPath.lineTo((float) rightAngleX + centerX, (float) rightAngleY + centerY); - arrowPointerPath.lineTo((float) tipAngleX + centerX, (float) tipAngleY + centerY); - - valuePointerArrowPaint.setColor(Color.HSVToColor(colorHSV)); - valuePointerArrowPaint.setStyle(Style.FILL); - canvas.drawPath(arrowPointerPath, valuePointerArrowPaint); - - valuePointerArrowPaint.setStyle(Style.STROKE); - valuePointerArrowPaint.setStrokeJoin(Join.ROUND); - valuePointerArrowPaint.setColor(Color.BLACK); - canvas.drawPath(arrowPointerPath, valuePointerArrowPaint); - - } - - @Override - protected void onSizeChanged(int width, int height, int oldw, int oldh) { - - int centerX = width / 2; - int centerY = height / 2; - - innerPadding = (int) (paramInnerPadding * width / 100); - outerPadding = (int) (paramOuterPadding * width / 100); - arrowPointerSize = (int) (paramArrowPointerSize * width / 100); - valueSliderWidth = (int) (paramValueSliderWidth * width / 100); - - outerWheelRadius = width / 2 - outerPadding - arrowPointerSize; - innerWheelRadius = outerWheelRadius - valueSliderWidth; - colorWheelRadius = innerWheelRadius - innerPadding; - - outerWheelRect.set(centerX - outerWheelRadius, centerY - outerWheelRadius, centerX + outerWheelRadius, centerY + outerWheelRadius); - innerWheelRect.set(centerX - innerWheelRadius, centerY - innerWheelRadius, centerX + innerWheelRadius, centerY + innerWheelRadius); - - colorWheelBitmap = createColorWheelBitmap(colorWheelRadius * 2, colorWheelRadius * 2); - - gradientRotationMatrix = new Matrix(); - gradientRotationMatrix.preRotate(270, width / 2, height / 2); - - colorViewPath.arcTo(outerWheelRect, 270, -180); - colorViewPath.arcTo(innerWheelRect, 90, 180); - - valueSliderPath.arcTo(outerWheelRect, 270, 180); - valueSliderPath.arcTo(innerWheelRect, 90, -180); - - } - - private Bitmap createColorWheelBitmap(int width, int height) { - - Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); - - int colorCount = 12; - int colorAngleStep = 360 / 12; - int colors[] = new int[colorCount + 1]; - float hsv[] = new float[] { 0f, 1f, 1f }; - for (int i = 0; i < colors.length; i++) { - hsv[0] = (i * colorAngleStep + 180) % 360; - colors[i] = Color.HSVToColor(hsv); - } - colors[colorCount] = colors[0]; - - SweepGradient sweepGradient = new SweepGradient(width / 2, height / 2, colors, null); - RadialGradient radialGradient = new RadialGradient(width / 2, height / 2, colorWheelRadius, 0xFFFFFFFF, 0x00FFFFFF, TileMode.CLAMP); - ComposeShader composeShader = new ComposeShader(sweepGradient, radialGradient, PorterDuff.Mode.SRC_OVER); - - colorWheelPaint.setShader(composeShader); - - Canvas canvas = new Canvas(bitmap); - canvas.drawCircle(width / 2, height / 2, colorWheelRadius, colorWheelPaint); - - return bitmap; - - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - int action = event.getAction(); - switch (action) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_MOVE: - - int x = (int) event.getX(); - int y = (int) event.getY(); - int cx = x - getWidth() / 2; - int cy = y - getHeight() / 2; - double d = Math.sqrt(cx * cx + cy * cy); - - if (d <= colorWheelRadius) { - - colorHSV[0] = (float) (Math.toDegrees(Math.atan2(cy, cx)) + 180f); - colorHSV[1] = Math.max(0f, Math.min(1f, (float) (d / colorWheelRadius))); - - invalidate(); - - } else if (x >= getWidth() / 2 && d >= innerWheelRadius) { - - colorHSV[2] = (float) Math.max(0, Math.min(1, Math.atan2(cy, cx) / Math.PI + 0.5f)); - - invalidate(); - } - - return true; - } - return super.onTouchEvent(event); - } - - public void setColor(int color) { - Color.colorToHSV(color, colorHSV); - } - - public int getColor() { - return Color.HSVToColor(colorHSV); - } - - @Override - protected Parcelable onSaveInstanceState() { - Bundle state = new Bundle(); - state.putFloatArray("color", colorHSV); - state.putParcelable("super", super.onSaveInstanceState()); - return state; - } - - @Override - protected void onRestoreInstanceState(Parcelable state) { - if (state instanceof Bundle) { - Bundle bundle = (Bundle) state; - colorHSV = bundle.getFloatArray("color"); - super.onRestoreInstanceState(bundle.getParcelable("super")); - } else { - super.onRestoreInstanceState(state); - } - } - -} diff --git a/app/src/main/java/com/idlegandalf/ledd/utils/ColorPickerDialog.java b/app/src/main/java/com/idlegandalf/ledd/utils/ColorPickerDialog.java deleted file mode 100644 index 097d2f1..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/utils/ColorPickerDialog.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.idlegandalf.ledd.utils; - - -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.widget.RelativeLayout; -import android.widget.RelativeLayout.LayoutParams; - -public class ColorPickerDialog extends AlertDialog { - - private ColorPicker colorPickerView; - private final OnColorSelectedListener onColorSelectedListener; - - public ColorPickerDialog(Context context, int initialColor, OnColorSelectedListener onColorSelectedListener) { - super(context); - - this.onColorSelectedListener = onColorSelectedListener; - - RelativeLayout relativeLayout = new RelativeLayout(context); - LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); - - colorPickerView = new ColorPicker(context); - colorPickerView.setColor(initialColor); - - relativeLayout.addView(colorPickerView, layoutParams); - - setButton(BUTTON_POSITIVE, context.getString(android.R.string.ok), onClickListener); - setButton(BUTTON_NEGATIVE, context.getString(android.R.string.cancel), onClickListener); - - setView(relativeLayout); - - } - - private OnClickListener onClickListener = new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - switch (which) { - case BUTTON_POSITIVE: - int selectedColor = colorPickerView.getColor(); - onColorSelectedListener.onColorSelected(selectedColor); - break; - case BUTTON_NEGATIVE: - dialog.dismiss(); - break; - } - } - }; - - public interface OnColorSelectedListener { - public void onColorSelected(int color); - } - -} diff --git a/app/src/main/java/com/idlegandalf/ledd/utils/ColorPickerPreference.java b/app/src/main/java/com/idlegandalf/ledd/utils/ColorPickerPreference.java deleted file mode 100644 index 576b0c0..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/utils/ColorPickerPreference.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.idlegandalf.ledd.utils; - - -import android.app.AlertDialog.Builder; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Color; -import android.preference.DialogPreference; -import android.util.AttributeSet; -import android.view.View; -import android.widget.RelativeLayout; -import android.widget.RelativeLayout.LayoutParams; - -public class ColorPickerPreference extends DialogPreference { - - public static final int DEFAULT_COLOR = Color.WHITE; - - private int selectedColor; - private ColorPicker colorPickerView; - - public ColorPickerPreference(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected View onCreateDialogView() { - - RelativeLayout relativeLayout = new RelativeLayout(getContext()); - LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); - - colorPickerView = new ColorPicker(getContext()); - colorPickerView.setId(1); - - relativeLayout.addView(colorPickerView, layoutParams); - - return relativeLayout; - - } - - @Override - protected void onBindDialogView(View view) { - super.onBindDialogView(view); - colorPickerView.setColor(selectedColor); - } - - @Override - protected void onPrepareDialogBuilder(Builder builder) { - super.onPrepareDialogBuilder(builder); - builder.setTitle(null); // remove dialog title to get more space for color picker - } - - @Override - protected void onDialogClosed(boolean positiveResult) { - if (positiveResult && shouldPersist()) { - if (callChangeListener(colorPickerView.getColor())) { - selectedColor = colorPickerView.getColor(); - persistInt(selectedColor); - } - } - } - - @Override - protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { - selectedColor = restoreValue ? getPersistedInt(DEFAULT_COLOR) : (Integer) defaultValue; - } - - @Override - protected Object onGetDefaultValue(TypedArray a, int index) { - return a.getInt(index, DEFAULT_COLOR); - } - -} diff --git a/app/src/main/java/com/idlegandalf/ledd/utils/MultiColorPicker.java b/app/src/main/java/com/idlegandalf/ledd/utils/MultiColorPicker.java deleted file mode 100644 index b6a20fe..0000000 --- a/app/src/main/java/com/idlegandalf/ledd/utils/MultiColorPicker.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright 2013 Piotr Adamus - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.idlegandalf.ledd.utils; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ComposeShader; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Paint.Join; -import android.graphics.Paint.Style; -import android.graphics.Path; -import android.graphics.PorterDuff; -import android.graphics.RadialGradient; -import android.graphics.RectF; -import android.graphics.Shader.TileMode; -import android.graphics.SweepGradient; -import android.os.Bundle; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; - -public class MultiColorPicker extends View { - - /** - * Customizable display parameters (in percents) - */ - private final int paramOuterPadding = 2; // outer padding of the whole color picker view - private final int paramInnerPadding = 5; // distance between value slider wheel and inner color wheel - private final int paramValueSliderWidth = 10; // width of the value slider - private final int paramArrowPointerSize = 4; // size of the arrow pointer; set to 0 to hide the pointer - - private final int paramColorCount = 5; - private final float paramHueSpreadAngle = 30f; // in degrees - - private Paint colorWheelPaint; - private Paint valueSliderPaint; - - private Paint colorViewPaint; - - private Paint colorPointerPaint; - private RectF colorPointerCoords; - - private Paint valuePointerPaint; - private Paint valuePointerArrowPaint; - - private RectF outerWheelRect; - private RectF innerWheelRect; - - private Path colorViewPath; - private Path valueSliderPath; - private Path arrowPointerPath; - - private Bitmap colorWheelBitmap; - - private int valueSliderWidth; - private int innerPadding; - private int outerPadding; - - private int arrowPointerSize; - private int outerWheelRadius; - private int innerWheelRadius; - private int colorWheelRadius; - - private Matrix gradientRotationMatrix; - - /** Currently selected color */ - private float[] colorHSV = new float[] { 0f, 0f, 1f }; - private float[] adjacentHue = new float[paramColorCount]; - - public MultiColorPicker(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } - - public MultiColorPicker(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - public MultiColorPicker(Context context) { - super(context); - init(); - } - - private void init() { - - colorPointerPaint = new Paint(); - colorPointerPaint.setStyle(Style.STROKE); - colorPointerPaint.setStrokeWidth(2f); - colorPointerPaint.setARGB(128, 0, 0, 0); - - valuePointerPaint = new Paint(); - valuePointerPaint.setStyle(Style.STROKE); - valuePointerPaint.setStrokeWidth(2f); - - valuePointerArrowPaint = new Paint(); - - colorWheelPaint = new Paint(); - colorWheelPaint.setAntiAlias(true); - colorWheelPaint.setDither(true); - - valueSliderPaint = new Paint(); - valueSliderPaint.setAntiAlias(true); - valueSliderPaint.setDither(true); - - colorViewPaint = new Paint(); - colorViewPaint.setAntiAlias(true); - - colorViewPath = new Path(); - valueSliderPath = new Path(); - arrowPointerPath = new Path(); - - outerWheelRect = new RectF(); - innerWheelRect = new RectF(); - - colorPointerCoords = new RectF(); - - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int widthSize = MeasureSpec.getSize(widthMeasureSpec); - int heightSize = MeasureSpec.getSize(heightMeasureSpec); - int size = Math.min(widthSize, heightSize); - setMeasuredDimension(size, size); - } - - @SuppressLint("DrawAllocation") - @Override - protected void onDraw(Canvas canvas) { - - int centerX = getWidth() / 2; - int centerY = getHeight() / 2; - - // drawing color wheel - - canvas.drawBitmap(colorWheelBitmap, centerX - colorWheelRadius, centerY - colorWheelRadius, null); - - // drawing color view - - int[] segmentColors = getColors(); - float sweepAngleStep = 180f / paramColorCount; - for (int i = 0; i < paramColorCount; i++) { - - colorViewPath.reset(); - colorViewPath.arcTo(outerWheelRect, 270 - i * sweepAngleStep, -sweepAngleStep); - colorViewPath.arcTo(innerWheelRect, 90 + (paramColorCount - i - 1) * sweepAngleStep, sweepAngleStep); - - colorViewPaint.setColor(segmentColors[i]); - - canvas.drawPath(colorViewPath, colorViewPaint); - - } - - // drawing value slider - - float[] hsv = new float[] { colorHSV[0], colorHSV[1], 1f }; - - SweepGradient sweepGradient = new SweepGradient(centerX, centerY, new int[] { Color.BLACK, Color.HSVToColor(hsv), Color.WHITE }, null); - sweepGradient.setLocalMatrix(gradientRotationMatrix); - valueSliderPaint.setShader(sweepGradient); - - canvas.drawPath(valueSliderPath, valueSliderPaint); - - // drawing color wheel pointer - - for (int i = 0; i < paramColorCount; i++) { - drawColorWheelPointer(canvas, (float) Math.toRadians(adjacentHue[i])); - } - - // drawing value pointer - - valuePointerPaint.setColor(Color.HSVToColor(new float[] { 0f, 0f, 1f - colorHSV[2] })); - - double valueAngle = (colorHSV[2] - 0.5f) * Math.PI; - float valueAngleX = (float) Math.cos(valueAngle); - float valueAngleY = (float) Math.sin(valueAngle); - - canvas.drawLine(valueAngleX * innerWheelRadius + centerX, valueAngleY * innerWheelRadius + centerY, valueAngleX * outerWheelRadius + centerX, - valueAngleY * outerWheelRadius + centerY, valuePointerPaint); - - // drawing pointer arrow - - if (arrowPointerSize > 0) { - drawPointerArrow(canvas); - } - - } - - private void drawColorWheelPointer(Canvas canvas, float hueAngle) { - - int centerX = getWidth() / 2; - int centerY = getHeight() / 2; - - int colorPointX = (int) (-Math.cos(hueAngle) * colorHSV[1] * colorWheelRadius) + centerX; - int colorPointY = (int) (-Math.sin(hueAngle) * colorHSV[1] * colorWheelRadius) + centerY; - - float pointerRadius = 0.075f * colorWheelRadius; - int pointerX = (int) (colorPointX - pointerRadius / 2); - int pointerY = (int) (colorPointY - pointerRadius / 2); - - colorPointerCoords.set(pointerX, pointerY, pointerX + pointerRadius, pointerY + pointerRadius); - canvas.drawOval(colorPointerCoords, colorPointerPaint); - - } - - private void drawPointerArrow(Canvas canvas) { - - int centerX = getWidth() / 2; - int centerY = getHeight() / 2; - - double tipAngle = (colorHSV[2] - 0.5f) * Math.PI; - double leftAngle = tipAngle + Math.PI / 96; - double rightAngle = tipAngle - Math.PI / 96; - - double tipAngleX = Math.cos(tipAngle) * outerWheelRadius; - double tipAngleY = Math.sin(tipAngle) * outerWheelRadius; - double leftAngleX = Math.cos(leftAngle) * (outerWheelRadius + arrowPointerSize); - double leftAngleY = Math.sin(leftAngle) * (outerWheelRadius + arrowPointerSize); - double rightAngleX = Math.cos(rightAngle) * (outerWheelRadius + arrowPointerSize); - double rightAngleY = Math.sin(rightAngle) * (outerWheelRadius + arrowPointerSize); - - arrowPointerPath.reset(); - arrowPointerPath.moveTo((float) tipAngleX + centerX, (float) tipAngleY + centerY); - arrowPointerPath.lineTo((float) leftAngleX + centerX, (float) leftAngleY + centerY); - arrowPointerPath.lineTo((float) rightAngleX + centerX, (float) rightAngleY + centerY); - arrowPointerPath.lineTo((float) tipAngleX + centerX, (float) tipAngleY + centerY); - - valuePointerArrowPaint.setColor(Color.HSVToColor(colorHSV)); - valuePointerArrowPaint.setStyle(Style.FILL); - canvas.drawPath(arrowPointerPath, valuePointerArrowPaint); - - valuePointerArrowPaint.setStyle(Style.STROKE); - valuePointerArrowPaint.setStrokeJoin(Join.ROUND); - valuePointerArrowPaint.setColor(Color.BLACK); - canvas.drawPath(arrowPointerPath, valuePointerArrowPaint); - - } - - @Override - protected void onSizeChanged(int width, int height, int oldw, int oldh) { - - int centerX = width / 2; - int centerY = height / 2; - - innerPadding = (int) (paramInnerPadding * width / 100); - outerPadding = (int) (paramOuterPadding * width / 100); - arrowPointerSize = (int) (paramArrowPointerSize * width / 100); - valueSliderWidth = (int) (paramValueSliderWidth * width / 100); - - outerWheelRadius = width / 2 - outerPadding - arrowPointerSize; - innerWheelRadius = outerWheelRadius - valueSliderWidth; - colorWheelRadius = innerWheelRadius - innerPadding; - - outerWheelRect.set(centerX - outerWheelRadius, centerY - outerWheelRadius, centerX + outerWheelRadius, centerY + outerWheelRadius); - innerWheelRect.set(centerX - innerWheelRadius, centerY - innerWheelRadius, centerX + innerWheelRadius, centerY + innerWheelRadius); - - colorWheelBitmap = createColorWheelBitmap(colorWheelRadius * 2, colorWheelRadius * 2); - - gradientRotationMatrix = new Matrix(); - gradientRotationMatrix.preRotate(270, width / 2, height / 2); - - valueSliderPath.arcTo(outerWheelRect, 270, 180); - valueSliderPath.arcTo(innerWheelRect, 90, -180); - - } - - private Bitmap createColorWheelBitmap(int width, int height) { - - Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); - - int colorCount = 12; - int colorAngleStep = 360 / 12; - int colors[] = new int[colorCount + 1]; - float hsv[] = new float[] { 0f, 1f, 1f }; - for (int i = 0; i < colors.length; i++) { - hsv[0] = (i * colorAngleStep + 180) % 360; - colors[i] = Color.HSVToColor(hsv); - } - colors[colorCount] = colors[0]; - - SweepGradient sweepGradient = new SweepGradient(width / 2, height / 2, colors, null); - RadialGradient radialGradient = new RadialGradient(width / 2, height / 2, colorWheelRadius, 0xFFFFFFFF, 0x00FFFFFF, TileMode.CLAMP); - ComposeShader composeShader = new ComposeShader(sweepGradient, radialGradient, PorterDuff.Mode.SRC_OVER); - - colorWheelPaint.setShader(composeShader); - - Canvas canvas = new Canvas(bitmap); - canvas.drawCircle(width / 2, height / 2, colorWheelRadius, colorWheelPaint); - - return bitmap; - - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - int action = event.getAction(); - switch (action) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_MOVE: - - int x = (int) event.getX(); - int y = (int) event.getY(); - int cx = x - getWidth() / 2; - int cy = y - getHeight() / 2; - double d = Math.sqrt(cx * cx + cy * cy); - - if (d <= colorWheelRadius) { - - colorHSV[0] = (float) (Math.toDegrees(Math.atan2(cy, cx)) + 180f); - colorHSV[1] = Math.max(0f, Math.min(1f, (float) (d / colorWheelRadius))); - - updateAdjacentHue(); - invalidate(); - - } else if (x >= getWidth() / 2 && d >= innerWheelRadius) { - - colorHSV[2] = (float) Math.max(0, Math.min(1, Math.atan2(cy, cx) / Math.PI + 0.5f)); - - updateAdjacentHue(); - invalidate(); - - } - - return true; - } - return super.onTouchEvent(event); - } - - private void updateAdjacentHue() { - - for (int i = 0; i < paramColorCount; i++) { - adjacentHue[i] = (colorHSV[0] - paramHueSpreadAngle * (paramColorCount / 2 - i)) % 360.0f; - adjacentHue[i] = (adjacentHue[i] < 0) ? adjacentHue[i] + 360f : adjacentHue[i]; - } - adjacentHue[paramColorCount / 2] = colorHSV[0]; - - } - - public void setColor(int color) { - Color.colorToHSV(color, colorHSV); - updateAdjacentHue(); - } - - public int getColor() { - return Color.HSVToColor(colorHSV); - } - - public int[] getColors() { - int[] colors = new int[paramColorCount]; - float[] hsv = new float[3]; - for (int i = 0; i < paramColorCount; i++) { - hsv[0] = adjacentHue[i]; - hsv[1] = colorHSV[1]; - hsv[2] = colorHSV[2]; - colors[i] = Color.HSVToColor(hsv); - } - return colors; - } - - @Override - protected Parcelable onSaveInstanceState() { - Bundle state = new Bundle(); - state.putFloatArray("color", colorHSV); - state.putParcelable("super", super.onSaveInstanceState()); - return state; - } - - @Override - protected void onRestoreInstanceState(Parcelable state) { - if (state instanceof Bundle) { - Bundle bundle = (Bundle) state; - colorHSV = bundle.getFloatArray("color"); - updateAdjacentHue(); - super.onRestoreInstanceState(bundle.getParcelable("super")); - } else { - super.onRestoreInstanceState(state); - } - } - -} diff --git a/app/src/main/res/drawable-hdpi/drawer_shadow.9.png b/app/src/main/res/drawable-hdpi/drawer_shadow.9.png deleted file mode 100644 index 236bff558af07faa3921ba35e2515edf62d04bb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 161 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 diff --git a/app/src/main/res/drawable-mdpi/drawer_shadow.9.png b/app/src/main/res/drawable-mdpi/drawer_shadow.9.png deleted file mode 100644 index ffe3a28d77c72094021013c6442560803b3d344c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142 zcmeAS@N?(olHy`uVBq!ia0y~yVBlb2U{K;@i%G5OQ!u)5PTrQ67Jew>cIuq~&|~N>6@e$H2hA;OXk;vd$@?2>=ElC$<0p diff --git a/app/src/main/res/drawable-mdpi/ic_drawer.png b/app/src/main/res/drawable-mdpi/ic_drawer.png deleted file mode 100644 index 1ed2c56ee4239ff2987568d4fdae10166650b120..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2820 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 C*F3fW diff --git a/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png b/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png deleted file mode 100644 index fabe9d96563785c7d6b008bb3d8da25e816c343c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0y~yVBlw9U~uAKV_;zD5a{{Az`(##?Bp53!NI{%!;#X# zz`(#+;1OBOz`)%J!i?r8Pp@TQUf1 zO@>Y7rMhp{x__!49~SL?aG;M@TkOmXgQN(QWTKjuBBy{?hvLGUqJakmU0qqEPb}zQ?(1vl5e?Mg>EgP<{zP$6U-ROQ zu2a7sRxi%Jw&(k^v;VeUw|lQz`~GlIyvbvLx3(rf_nY4%M1;3f6T0AWQd-kD9X5C zB7=f(YKIF$hBd>Q^I=`C3=swlB5B@7EE#U-G8lMT#JFBV&*2Bohp{DjnN#sh3w(sdU6`)JjJy| z%o3RrXF2E{s+=il)M�PV*|l=S%D z)AOqf92giLmegJRr=!1Fs==DAA@|=R)pslzaoh_^zjvo?;&<4}u;Asb@XrOHuyI{D zVdu@8PoF%w;dR6*I`LF^?Z5Ox@dv{H=KQR)`SbnjgME)w8jWHb-C2G-ICSQV&r+H5 zlQ>(F?mX*v|FfO@{~y`QN=H1Cc1CE4JPs5p>~opb^Vw*rQm4}-&7-Q9{-->;uk)MP z?!GC*hAcbA>WR85Vw0J_d8-RVlpJ{Uoq^%g?)-ySG&qj}HTE=evN)dL5KdIQ z)xnt56`|b6AwIM9hvGpG7NKqxg_9j3flA&JO+5^QxN*)_l1-a!&&`e3ua#^+9GA!W47@5h1D7SxBBgz zj~g6#A;E5ZB*#GS*kPxQ7CM}hlTU9{TEnyYnAC=_HO#v^zb2pGSk5BU=z4(DjHTR3 zAyLlJBf=-b?}o<;1sN3+!CRc>oXjnOht!oOukhZYwoCBm5s4%t!}bUd9p!66{lfYJ z)g8`9%vFRsosHCYPGIufxFqC~&?UD^c|poAbym(c@sLuUeDYRG_9k}ADLM+;Ct9D( zeRBAT@e}DMil3sn<|a85F8LAsNF(S}mY3vHfu|-<*-~d1IfgEt6?AvS!Vp2z{wSxl z3%3QW4{To{Y*ISQ@@%u1r}xsei>6+d$`H@^p1J--$u7aWQ|0`oUkJZ+`lb7e=`WbS zl=JYmi8deaNY{{@Ex|64E?F+IeumF7$;;i6$3qOv4PVcAK9hfDerSZ&Hmw@biKn=x zdQDZEDy^j-vU1h3RrgkLhkgz{9n!xtF1U7`Tc~mHe>d_u9`{m@QFl-8KgT-vdGO8PyUV$j zi}~7GeO;%wDtoE)!rd*_s-Zv4yNvdDMa_T;rjSw=362#t!}?6!99TGea2*X~{}xO}JIWWUw(uB9K| z@NwJ8Z7a7+Zg_fw?e@BDx!Y zH{DKew)C;PC-y$^D*0L%`>^WL*SWJd&pz~a#qIU)%-&_bYrix9jLCe>d6CA&7Y?6r zeh~QdqCNNgsRr5i*VOqt`!}Xte?weiF{Ks~WZOrc( z-HVJrV}4-!iS4KT59iN|Z@uqaulzsdf7Sns49go-8Pl0N8yy>?nSTGMs!`nEXK!^o z_1mVKZykFU>~s`$>~C7z^z`6b#f%egCahKb{(Q!{iRUu;S_A4{T)V)Y_$;yea2=0& zYkO;Wn|)tFM}*Wx!|A5w7w~uqa%k{cmrdoEZ^s;PjneQ^$Wq(XB zE%MCOh`AA-Io>jsdRptu@^bdw|MT{9`=hy!xF1)G&(J>+TTr?1+@UY6%f(je3F%l( zbMWc#vzYS1Q9x^jSdZ!_;d0eJuF6BQhtiewFPdHKxZxb5CFl3aL(8{n(wm8UOe9?^Mp05k-A*loR+-^iPE^P#l9&$H9T$q+0Ijz(^k*ZKKu5}=2N#P zn9q4X|NmQ|LqZQHZCl#r9j+@I@oev!EXz$cg_XCt9*eSSw}r8-vDwkJO)K}R|LV8l z)7RDQRjcyNZj3v4s_EcX#_ZSJpLO=5U*2G_JbEWM>JG<72+!miM zT7N_1PQ_E{_WV=(XWp5zW##H4J5$c5T}pfT?4IttXufHyrazm`m&bea))wCTVO!pQ z{pNaGfBIRC+q;{$IqzJ&-)6_2)a577owc?PSrYOkt)mB z$?2cY_spF-x3*62=bePxi?&riPd;})i$DMUE`gGVmt6mMKeygveJhIR>@!u2w#o?{vP3ODqSM8(!-MR7pPJPya z@&%tS-f{oV*4ljj-^8!|{LZZXGy6}s@wUC5XJKb)`N+QL@5?{SozJJ7SDPpPZ_&Tg z>%_(M>wa8)ef`|U85b8$|1^E_{@j|Se_tJVExG>ou|vn?_MNOSHjMic_WSL@@;l|S z?-$?a_kU8OP_OYna3$jP7}zo^M^L^0kQd!rh&g3=PQ#X1sn?!oc9r!BEr4$H2fLc%Zz2H)T=zB(_H? R2@DJj44$rjF6*2UngAQMK|lZi diff --git a/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png b/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png deleted file mode 100644 index b91e9d7f285e8110ba3ba4e72cc6f0416eb3a30a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmeAS@N?(olHy`uVBq!ia0y~yU=U+qU`XO%V_;wiVOM^`z`!6`;u=vBoS#-wo>-L1 z;Fyx1l&avFo0y&&l$w}QS$HzlhJk^h$kW9!B;(%O3yNG$j3O=@1JJNr0G;NdTDNjha#F?D7CbCDhSzT_&<2G$Qi^na>d^eKYb - - - diff --git a/app/src/main/res/layout/act_demo.xml b/app/src/main/res/layout/act_demo.xml deleted file mode 100644 index 31ed633..0000000 --- a/app/src/main/res/layout/act_demo.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/act_multi_picker.xml b/app/src/main/res/layout/act_multi_picker.xml deleted file mode 100644 index d064d56..0000000 --- a/app/src/main/res/layout/act_multi_picker.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - -