diff --git a/app-android/app/build.gradle b/app-android/app/build.gradle
index bab7253..6cc8923 100644
--- a/app-android/app/build.gradle
+++ b/app-android/app/build.gradle
@@ -19,5 +19,5 @@ android {
}
dependencies {
- compile "com.android.support:appcompat-v7:21.0.+"
+ compile "com.android.support:appcompat-v7:22.+"
}
diff --git a/app-android/app/src/main/AndroidManifest.xml b/app-android/app/src/main/AndroidManifest.xml
index 8e883cb..eaa6569 100644
--- a/app-android/app/src/main/AndroidManifest.xml
+++ b/app-android/app/src/main/AndroidManifest.xml
@@ -4,9 +4,7 @@
android:versionCode="4"
android:versionName="1.3" >
-
+
@@ -18,7 +16,8 @@
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:theme="@style/AppTheme"
- android:label="@string/app_name" >
+ android:label="@string/app_name"
+ android:largeHeap="true">
= 16)
uiFlags ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
- if (Build.VERSION.SDK_INT >= 18)
+ if (Build.VERSION.SDK_INT >= 19)
uiFlags ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setOnSystemUiVisibilityChangeListener(this);
@@ -106,16 +130,21 @@ public class CanvasActivity extends ActionBarActivity implements View.OnSystemUi
@Override
public void onSystemUiVisibilityChange(int visibility) {
+ Log.i("GfxTablet", "System UI changed " + visibility);
+
+ fullScreen = (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
+
// show/hide action bar according to full-screen mode
- if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) {
+ if (fullScreen) {
CanvasActivity.this.getSupportActionBar().hide();
- fullScreen = true;
Toast.makeText(CanvasActivity.this, "Press Back button to leave full-screen mode.", Toast.LENGTH_LONG).show();
} else
CanvasActivity.this.getSupportActionBar().show();
}
+ // template image logic
+
private String getTemplateImagePath() {
return preferences.getString(SettingsActivity.KEY_TEMPLATE_IMAGE, null);
}
@@ -143,6 +172,7 @@ public class CanvasActivity extends ActionBarActivity implements View.OnSystemUi
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && data != null) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
@@ -159,32 +189,41 @@ public class CanvasActivity extends ActionBarActivity implements View.OnSystemUi
} finally {
cursor.close();
}
- } else
- super.onActivityResult(requestCode, resultCode, data);
+ }
}
public void showTemplateImage() {
- String picturePath = preferences.getString(SettingsActivity.KEY_TEMPLATE_IMAGE, null);
- if (picturePath != null) {
- Drawable drawable = BitmapDrawable.createFromPath(picturePath);
- getWindow().setBackgroundDrawable(drawable);
- } else
- getWindow().setBackgroundDrawableResource(android.R.drawable.screen_background_light);
+ ImageView template = (ImageView)findViewById(R.id.canvas_template);
+ template.setImageDrawable(null);
+
+ if (template.getVisibility() == View.VISIBLE) {
+ String picturePath = preferences.getString(SettingsActivity.KEY_TEMPLATE_IMAGE, null);
+ if (picturePath != null)
+ try {
+ // TODO load bitmap efficiently, for intended view size and display resolution
+ // https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
+ final Drawable drawable = new BitmapDrawable(getResources(), picturePath);
+ template.setImageDrawable(drawable);
+ } catch (Exception e) {
+ Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
+ }
+ }
}
private class ConfigureNetworkingTask extends AsyncTask {
@Override
protected Boolean doInBackground(Void... params) {
- return netClient.configureNetworking();
+ return netClient.reconfigureNetworking();
}
protected void onPostExecute(Boolean success) {
- if (success) {
- setContentView(canvas);
+ if (success)
Toast.makeText(CanvasActivity.this, "Touch events will be sent to " + netClient.destAddress.getHostAddress() + ":" + NetworkClient.GFXTABLET_PORT, Toast.LENGTH_LONG).show();
- } else
- setContentView(R.layout.activity_no_host);
+
+ findViewById(R.id.canvas_template).setVisibility(success ? View.VISIBLE : View.GONE);
+ findViewById(R.id.canvas).setVisibility(success ? View.VISIBLE : View.GONE);
+ findViewById(R.id.canvas_message).setVisibility(success ? View.GONE : View.VISIBLE);
}
}
diff --git a/app-android/app/src/main/java/at/bitfire/gfxtablet/CanvasView.java b/app-android/app/src/main/java/at/bitfire/gfxtablet/CanvasView.java
index a1866b8..74c72d1 100644
--- a/app-android/app/src/main/java/at/bitfire/gfxtablet/CanvasView.java
+++ b/app-android/app/src/main/java/at/bitfire/gfxtablet/CanvasView.java
@@ -5,6 +5,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
@@ -13,32 +14,63 @@ import android.view.View;
import at.bitfire.gfxtablet.NetEvent.Type;
@SuppressLint("ViewConstructor")
-public class CanvasView extends View {
+public class CanvasView extends View implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "GfxTablet.CanvasView";
final SharedPreferences settings;
- final NetworkClient netClient;
+ NetworkClient netClient;
boolean acceptStylusOnly;
int maxX, maxY;
- public CanvasView(Context context, NetworkClient networkClient) {
- super(context);
- this.netClient = networkClient;
- // process preferences
+ // setup
+
+ public CanvasView(Context context, AttributeSet attributeSet) {
+ super(context, attributeSet);
+
+ // view is disabled until a network client is set
+ setEnabled(false);
+
settings = PreferenceManager.getDefaultSharedPreferences(context);
- acceptStylusOnly = settings.getBoolean(SettingsActivity.KEY_PREF_STYLUS_ONLY, false);
+ settings.registerOnSharedPreferenceChangeListener(this);
+ setBackground();
+ setInputMethods();
}
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
+ public void setNetworkClient(NetworkClient networkClient) {
+ netClient = networkClient;
+ setEnabled(true);
+ }
+
+
+ // settings
+
+ protected void setBackground() {
if (settings.getBoolean(SettingsActivity.KEY_DARK_CANVAS, false))
setBackgroundColor(Color.BLACK);
else
setBackgroundResource(R.drawable.bg_grid_pattern);
}
+ protected void setInputMethods() {
+ acceptStylusOnly = settings.getBoolean(SettingsActivity.KEY_PREF_STYLUS_ONLY, false);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ switch (key) {
+ case SettingsActivity.KEY_PREF_STYLUS_ONLY:
+ setInputMethods();
+ break;
+ case SettingsActivity.KEY_DARK_CANVAS:
+ setBackground();
+ break;
+ }
+ }
+
+
+ // drawing
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.i(TAG, "Canvas size changed: " + w + "x" + h + " (before: " + oldw + "x" + oldh + ")");
@@ -65,7 +97,7 @@ public class CanvasView extends View {
}
@Override
- public boolean onTouchEvent(MotionEvent event) {
+ public boolean onTouchEvent(@NonNull MotionEvent event) {
if (isEnabled()) {
for (int ptr = 0; ptr < event.getPointerCount(); ptr++)
if (!acceptStylusOnly || (event.getToolType(ptr) == MotionEvent.TOOL_TYPE_STYLUS)) {
@@ -104,4 +136,5 @@ public class CanvasView extends View {
short normalizePressure(float x) {
return (short)(Math.min(Math.max(0, x), 2.0) * Short.MAX_VALUE/2.0);
}
+
}
diff --git a/app-android/app/src/main/java/at/bitfire/gfxtablet/NetworkClient.java b/app-android/app/src/main/java/at/bitfire/gfxtablet/NetworkClient.java
index ad7e04d..c437725 100644
--- a/app-android/app/src/main/java/at/bitfire/gfxtablet/NetworkClient.java
+++ b/app-android/app/src/main/java/at/bitfire/gfxtablet/NetworkClient.java
@@ -13,19 +13,19 @@ import at.bitfire.gfxtablet.NetEvent.Type;
public class NetworkClient implements Runnable {
- static int GFXTABLET_PORT = 40118;
+ static final int GFXTABLET_PORT = 40118;
- LinkedBlockingQueue motionQueue = new LinkedBlockingQueue<>();
+ final LinkedBlockingQueue motionQueue = new LinkedBlockingQueue<>();
LinkedBlockingQueue getQueue() { return motionQueue; }
InetAddress destAddress;
- SharedPreferences preferences;
+ final SharedPreferences preferences;
NetworkClient(SharedPreferences preferences) {
this.preferences = preferences;
}
- boolean configureNetworking() {
+ boolean reconfigureNetworking() {
try {
String hostName = preferences.getString(SettingsActivity.KEY_PREF_HOST, "unknown.invalid");
destAddress = InetAddress.getByName(hostName);
diff --git a/app-android/app/src/main/java/at/bitfire/gfxtablet/SettingsActivity.java b/app-android/app/src/main/java/at/bitfire/gfxtablet/SettingsActivity.java
index 29baea8..d81257b 100644
--- a/app-android/app/src/main/java/at/bitfire/gfxtablet/SettingsActivity.java
+++ b/app-android/app/src/main/java/at/bitfire/gfxtablet/SettingsActivity.java
@@ -1,10 +1,10 @@
package at.bitfire.gfxtablet;
-import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
-public class SettingsActivity extends ActionBarActivity {
+public class SettingsActivity extends AppCompatActivity {
public static final String
KEY_PREF_HOST = "host_preference",
KEY_PREF_STYLUS_ONLY = "stylus_only_preference",
diff --git a/app-android/app/src/main/res/drawable-hdpi/ic_action_picture.png b/app-android/app/src/main/res/drawable-hdpi/ic_action_picture.png
new file mode 100644
index 0000000..00216ea
Binary files /dev/null and b/app-android/app/src/main/res/drawable-hdpi/ic_action_picture.png differ
diff --git a/app-android/app/src/main/res/drawable-mdpi/ic_action_picture.png b/app-android/app/src/main/res/drawable-mdpi/ic_action_picture.png
index 3fb1134..5c994c6 100644
Binary files a/app-android/app/src/main/res/drawable-mdpi/ic_action_picture.png and b/app-android/app/src/main/res/drawable-mdpi/ic_action_picture.png differ
diff --git a/app-android/app/src/main/res/drawable-xhdpi/ic_action_picture.png b/app-android/app/src/main/res/drawable-xhdpi/ic_action_picture.png
index a41fb71..28506b2 100644
Binary files a/app-android/app/src/main/res/drawable-xhdpi/ic_action_picture.png and b/app-android/app/src/main/res/drawable-xhdpi/ic_action_picture.png differ
diff --git a/app-android/app/src/main/res/drawable-xxhdpi/ic_action_picture.png b/app-android/app/src/main/res/drawable-xxhdpi/ic_action_picture.png
index eeb5a8f..b81237f 100644
Binary files a/app-android/app/src/main/res/drawable-xxhdpi/ic_action_picture.png and b/app-android/app/src/main/res/drawable-xxhdpi/ic_action_picture.png differ
diff --git a/app-android/app/src/main/res/layout/activity_canvas.xml b/app-android/app/src/main/res/layout/activity_canvas.xml
new file mode 100644
index 0000000..4f3ee16
--- /dev/null
+++ b/app-android/app/src/main/res/layout/activity_canvas.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app-android/app/src/main/res/layout/activity_no_host.xml b/app-android/app/src/main/res/layout/activity_no_host.xml
deleted file mode 100644
index 88f43b7..0000000
--- a/app-android/app/src/main/res/layout/activity_no_host.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app-android/app/src/main/res/layout/activity_settings.xml b/app-android/app/src/main/res/layout/activity_settings.xml
index d4023ec..05060f7 100644
--- a/app-android/app/src/main/res/layout/activity_settings.xml
+++ b/app-android/app/src/main/res/layout/activity_settings.xml
@@ -1,12 +1,15 @@
-
+
-
\ No newline at end of file
+ android:name="at.bitfire.gfxtablet.SettingsFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal|top"
+ tools:layout="@layout/activity_settings"/>
+
\ No newline at end of file
diff --git a/app-android/app/src/main/res/menu/activity_canvas.xml b/app-android/app/src/main/res/menu/activity_canvas.xml
index 01a1e19..4fac79f 100644
--- a/app-android/app/src/main/res/menu/activity_canvas.xml
+++ b/app-android/app/src/main/res/menu/activity_canvas.xml
@@ -1,20 +1,20 @@
-
\ No newline at end of file
diff --git a/app-android/app/src/main/res/values/strings.xml b/app-android/app/src/main/res/values/strings.xml
index 5036642..7b35d63 100644
--- a/app-android/app/src/main/res/values/strings.xml
+++ b/app-android/app/src/main/res/values/strings.xml
@@ -4,6 +4,12 @@
GfxTablet
Settings
About / Help
+ Donate
+
+ Full-screen mode
+ Set template image
+ Clear template image
+ Select another image
No valid recipient host defined. Please configure in \"Settings / Recipient host\".
@@ -13,8 +19,8 @@
Only stylus input will be processed
Finger and stylus input will be processed
Use dark canvas
- Black canvas will be used
- White canvas will be used
+ Black canvas will be used (covers template image)
+ White/transparent gridded canvas will be used
Keep display active
Display won\'t turn off while GfxTablet is active
Display will turn off according to system settings
diff --git a/app-android/app/src/main/res/xml/preferences.xml b/app-android/app/src/main/res/xml/preferences.xml
index 88c4254..a5b2e74 100644
--- a/app-android/app/src/main/res/xml/preferences.xml
+++ b/app-android/app/src/main/res/xml/preferences.xml
@@ -1,7 +1,7 @@