diff options
Diffstat (limited to 'app')
52 files changed, 1117 insertions, 0 deletions
diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..adb5b49 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 29 + buildToolsVersion "29.0.2" + defaultConfig { + applicationId "com.javispedro.wallmotion" + minSdkVersion 23 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.google.android.material:material:1.0.0' + implementation 'androidx.preference:preference:1.1.0-alpha05' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + implementation 'org.jetbrains:annotations-java5:15.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..2d010dd --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.javispedro.wallmotion"> + + <uses-feature + android:name="android.software.live_wallpaper" + android:required="true" /> + + <application + android:allowBackup="true" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:roundIcon="@mipmap/ic_launcher_round" + android:supportsRtl="true" + android:theme="@style/AppTheme"> + + <service + android:name=".WallService" + android:permission="android.permission.BIND_WALLPAPER"> + <intent-filter> + <action android:name="android.service.wallpaper.WallpaperService" /> + </intent-filter> + <meta-data android:name="android.service.wallpaper" + android:resource="@xml/wallpaper" /> + </service> + + <activity + android:name=".SettingsActivity" + android:label="@string/title_activity_settings" + android:exported="true"> + </activity> + + <activity + android:name=".MainActivity" + android:label="@string/app_name" + android:theme="@style/AppTheme.NoActionBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> + +</manifest>
\ No newline at end of file diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png Binary files differnew file mode 100644 index 0000000..c80c1c7 --- /dev/null +++ b/app/src/main/ic_launcher-web.png diff --git a/app/src/main/java/com/javispedro/wallmotion/MainActivity.java b/app/src/main/java/com/javispedro/wallmotion/MainActivity.java new file mode 100644 index 0000000..c6859ae --- /dev/null +++ b/app/src/main/java/com/javispedro/wallmotion/MainActivity.java @@ -0,0 +1,117 @@ +package com.javispedro.wallmotion; + +import android.app.WallpaperManager; +import android.content.ComponentName; +import android.content.Intent; +import android.os.Bundle; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.Menu; +import android.view.MenuItem; + +public class MainActivity extends AppCompatActivity { + private static final String TAG = "MainActivity"; + + private Renderer renderer; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + FloatingActionButton fab = findViewById(R.id.set_wallpaper); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + openWallpaperSelector(); + } + }); + + SurfaceView view = findViewById(R.id.wallpaper_view); + view.getHolder().addCallback(new WallpaperViewCallback()); + + renderer = new Renderer(this); + } + + @Override + protected void onDestroy() { + renderer.stop(); + renderer = null; + + super.onDestroy(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + if (id == R.id.action_settings) { + openSettingsActivity(); + return true; + } + + return super.onOptionsItemSelected(item); + } + + @Override + protected void onResume() { + super.onResume(); + } + + @Override + protected void onPause() { + renderer.stop(); + super.onPause(); + } + + private class WallpaperViewCallback implements SurfaceHolder.Callback { + @Override + public void surfaceCreated(SurfaceHolder holder) { + Log.d(TAG, "surfaceCreated"); + renderer.start(holder.getSurface()); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + Log.d(TAG, "surfaceDestroyed"); + renderer.stop(); + } + } + + private void openSettingsActivity() { + Intent intent = new Intent(this, SettingsActivity.class); + startActivity(intent); + } + + private void openWallpaperSelector() { + Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER); + intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, + new ComponentName(this, WallService.class)); + startActivity(intent); + } +} diff --git a/app/src/main/java/com/javispedro/wallmotion/Renderer.java b/app/src/main/java/com/javispedro/wallmotion/Renderer.java new file mode 100644 index 0000000..6730afe --- /dev/null +++ b/app/src/main/java/com/javispedro/wallmotion/Renderer.java @@ -0,0 +1,183 @@ +package com.javispedro.wallmotion; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.SharedPreferences; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.Build; +import android.text.TextUtils; +import android.util.Log; +import android.view.Surface; + +import androidx.preference.PreferenceManager; + +import java.io.IOException; + +public class Renderer extends ContextWrapper { + private static final String TAG = "Renderer"; + + private SharedPreferences prefs; + private MediaPlayer player; + + private int savedPosition; + + public Renderer(Context context) { + super(context); + + prefs = PreferenceManager.getDefaultSharedPreferences(context); + prefs.registerOnSharedPreferenceChangeListener(new PrefsListener()); + } + + public boolean isActive() { + return player != null; + } + + public void start(Surface surface) { + preparePlayer(surface); + } + + public void stop() { + if (player != null && player.isPlaying() && shouldSaveRestorePosition()) { + savedPosition = player.getCurrentPosition(); + Log.d(TAG, "storing current position: " + savedPosition + " ms"); + } + releasePlayer(); + } + + public void reset() { + releasePlayer(); + savedPosition = 0; + } + + private class PrefsListener implements SharedPreferences.OnSharedPreferenceChangeListener { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals(getString(R.string.settings_video_file_key))) { + Log.d(TAG, "video file key changed"); + reset(); + } else if (key.equals(getString(R.string.settings_display_restart_key))) { + savedPosition = 0; + } + } + } + + private class PlayerListener implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener { + @Override + public boolean onError(MediaPlayer mp, int what, int extra) { + Log.e(TAG, "MediaPlayer error: " + what + " extra:" + extra); + return false; + } + + @Override + public void onPrepared(MediaPlayer mp) { + Log.d(TAG, "onPrepared"); + if (player != null && !player.isPlaying()) { + Log.d(TAG, "start playing"); + if (savedPosition > 0 && shouldSaveRestorePosition()) { + restorePlayerPosition(); + } + player.start(); + } + } + + @Override + public void onSeekComplete(MediaPlayer mp) { + Log.d(TAG, "onSeekComplete: " + mp.getCurrentPosition() + " ms"); + } + } + + private void preparePlayer(Surface surface) { + releasePlayer(); + + int scaling = getVideoScaling(); + Log.d(TAG, "video scaling mode: " + scaling); + + Uri uri = getVideoFileUri(); + if (uri == null) { + Log.d(TAG, "no video URI: using missing video URI"); + uri = getResourceVideoFileUri(R.raw.video_file_missing); + scaling = MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT; + } + + try { + preparePlayer(surface, uri, scaling); + } catch (Exception ex) { + Log.e(TAG, "Could not open video URI: " + uri.toString() + " : " + ex.toString()); + ex.printStackTrace(); + releasePlayer(); + + uri = getResourceVideoFileUri(R.raw.video_file_error); + scaling = MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT; + + try { + preparePlayer(surface, uri, scaling); + } catch (Exception ex2) { + Log.e(TAG, "Could not open error video URI either: " + ex2.toString()); + ex2.printStackTrace(); + releasePlayer(); + } + } + } + + private void preparePlayer(Surface surface, Uri uri, int scaling) throws IOException { + Log.d(TAG, "creating player"); + player = new MediaPlayer(); + PlayerListener listener = new PlayerListener(); + player.setOnErrorListener(listener); + player.setOnPreparedListener(listener); + player.setOnSeekCompleteListener(listener); + player.setLooping(true); + player.setVolume(0, 0); + player.setSurface(surface); + Log.d(TAG, "setting data source to " + uri.toString()); + player.setDataSource(this, uri); + player.setVideoScalingMode(scaling); + player.prepareAsync(); + } + + private void releasePlayer() { + if (player != null) { + Log.d(TAG, "releasing player"); + player.release(); + player = null; + } + } + + private void restorePlayerPosition() { + Log.d(TAG, "seeking to " + savedPosition + " ms"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + player.seekTo(savedPosition, MediaPlayer.SEEK_CLOSEST); + } else { + player.seekTo(savedPosition); + } + } + + private Uri getVideoFileUri() { + String new_value = prefs.getString(getString(R.string.settings_video_file_key), null); + if (new_value != null) { + return Uri.parse(new_value); + } else { + return null; + } + } + + private Uri getResourceVideoFileUri(int resId) { + Uri.Builder builder = new Uri.Builder(); + builder.scheme("android.resource").authority(getPackageName()).appendPath(Integer.toString(resId)); + return builder.build(); + } + + private int getVideoScaling() { + String value = prefs.getString(getString(R.string.settings_display_scale_key), null); + if (TextUtils.equals(value, getString(R.string.settings_display_scale_to_fit_with_cropping_key))) { + return MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING; + } else { + return MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT; + } + } + + private boolean shouldSaveRestorePosition() { + return !prefs.getBoolean(getString(R.string.settings_display_restart_key), false); + } +} diff --git a/app/src/main/java/com/javispedro/wallmotion/SettingsActivity.java b/app/src/main/java/com/javispedro/wallmotion/SettingsActivity.java new file mode 100644 index 0000000..6919ea1 --- /dev/null +++ b/app/src/main/java/com/javispedro/wallmotion/SettingsActivity.java @@ -0,0 +1,174 @@ +package com.javispedro.wallmotion; + +import android.app.Activity; +import android.content.ContentResolver; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.provider.OpenableColumns; +import android.text.TextUtils; +import android.util.Log; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceManager; + +public class SettingsActivity extends AppCompatActivity { + private static final String TAG = "SettingsActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.settings_activity); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.settings, new SettingsFragment()) + .commit(); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + } + } + + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; + } + + public static class SettingsFragment extends PreferenceFragmentCompat { + private final static int PICK_VIDEO_FILE = 1; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.root_preferences, rootKey); + Preference video_file = findPreference(getString(R.string.settings_video_file_key)); + video_file.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("video/*"); + intent.setFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + startActivityForResult(intent, PICK_VIDEO_FILE); + return true; + } + }); + video_file.setSummary(getVideoFileSummary()); + Preference video_file_clear = findPreference(getString(R.string.settings_video_file_clear_key)); + video_file_clear.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + setVideoFile(null); + return true; + } + }); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, + Intent resultData) { + switch (requestCode) { + case PICK_VIDEO_FILE: + if (resultCode == Activity.RESULT_OK && resultData != null) { + Uri uri = resultData.getData(); + setVideoFile(uri); + } + break; + } + } + + private void setVideoFile(Uri uri) { + ContentResolver resolver = getContext().getContentResolver(); + + // First, release any permission request on the current uri + String cur_value = getStringPref(getString(R.string.settings_video_file_key)); + if (!TextUtils.isEmpty(cur_value)) { + Uri cur_uri = Uri.parse(cur_value); + Log.d(TAG, "release persistable uri permission on uri: " + cur_uri.toString()); + try { + resolver.releasePersistableUriPermission(cur_uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); + } catch (Exception ex) { + Log.w(TAG, "could not release persistable uri permission on uri: " + cur_uri.toString()); + ex.printStackTrace(); + } + } + + // Then, store the new setting + if (uri != null) { + Log.d(TAG, "storing video_file pref uri: " + uri.toString()); + setStringPref(getString(R.string.settings_video_file_key), uri.toString()); + + // Take a persistent permission on it + Log.d(TAG, "take persistable uri permission on uri: " + uri.toString()); + resolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + Log.d(TAG, "clearing video_file pref uri"); + clearPref(getString(R.string.settings_video_file_key)); + } + + // Refresh the UI summary + Preference video_file = findPreference(getString(R.string.settings_video_file_key)); + video_file.setSummary(getVideoFileSummary()); + } + + private String getVideoFileSummary() { + String cur_value = getStringPref(getString(R.string.settings_video_file_key)); + if (!TextUtils.isEmpty(cur_value)) { + ContentResolver resolver = getContext().getContentResolver(); + Uri uri = Uri.parse(cur_value); + String[] projection = {OpenableColumns.DISPLAY_NAME}; + try { + Cursor cursor = resolver.query(uri, projection, null, null, null); + if (cursor != null) { + int col = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + if (col >= 0 && cursor.moveToFirst()) { + String name = cursor.getString(col); + cursor.close(); + Log.d(TAG, "got video file display_name: " + name); + return name; + } else { + Log.w(TAG, "Could not navigate cursor for URI: " + uri.toString()); + } + cursor.close(); + } else { + Log.w(TAG, "Could not get cursor for URI: " + uri.toString()); + } + } catch (java.lang.SecurityException ex) { + ex.printStackTrace(); + Log.w(TAG, "Security exception while reading URI: " + uri.toString()); + } + return uri.getLastPathSegment(); + } + return getString(R.string.settings_not_set); + } + + protected String getStringPref(String pref) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + return prefs.getString(pref, null); + } + + protected void setStringPref(String pref, String new_value) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + String cur_value = prefs.getString(pref, null); + if (!TextUtils.equals(cur_value, new_value)) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(pref, new_value); + editor.apply(); + } + } + + protected void clearPref(String pref) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + if (prefs.contains(pref)) { + SharedPreferences.Editor editor = prefs.edit(); + editor.remove(pref); + editor.apply(); + } + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/com/javispedro/wallmotion/WallService.java b/app/src/main/java/com/javispedro/wallmotion/WallService.java new file mode 100644 index 0000000..6a004ff --- /dev/null +++ b/app/src/main/java/com/javispedro/wallmotion/WallService.java @@ -0,0 +1,65 @@ +package com.javispedro.wallmotion; + +import android.service.wallpaper.WallpaperService; +import android.util.Log; +import android.view.SurfaceHolder; + +public class WallService extends WallpaperService { + private static final String TAG = "WallService"; + + @Override + public Engine onCreateEngine() { + return new WallpaperEngine(); + } + + private class WallpaperEngine extends Engine { + private static final String TAG = "WallpaperEngine"; + + private Renderer renderer; + + @Override + public void onCreate(SurfaceHolder surfaceHolder) { + Log.d(TAG, "onCreate"); + renderer = new Renderer(WallService.this); + } + + @Override + public void onDestroy() { + Log.d(TAG, "onDestroy"); + renderer.stop(); + renderer = null; + } + + @Override + public void onSurfaceDestroyed(SurfaceHolder holder) { + Log.d(TAG, "onSurfaceDestroyed"); + renderer.stop(); + } + + @Override + public void onSurfaceCreated(SurfaceHolder holder) { + Log.d(TAG, "onSurfaceCreated"); + } + + @Override + public void onSurfaceChanged(SurfaceHolder holder, int format, + int width, int height) { + Log.d(TAG, "onSurfaceChanged"); + } + + @Override + public void onSurfaceRedrawNeeded(SurfaceHolder holder) { + Log.d(TAG, "onSurfaceRedrawNeeded"); + } + + @Override + public void onVisibilityChanged(boolean visible) { + Log.d(TAG, "onVisibilityChanged(visible: " + visible + ")"); + if (visible) { + renderer.start(getSurfaceHolder().getSurface()); + } else { + renderer.stop(); + } + } + } +} diff --git a/app/src/main/res/drawable-anydpi/ic_action_settings.xml b/app/src/main/res/drawable-anydpi/ic_action_settings.xml new file mode 100644 index 0000000..01b2fba --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_action_settings.xml @@ -0,0 +1,11 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="#FFFFFF" + android:alpha="0.8"> + <path + android:fillColor="#FF000000" + android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/> +</vector> diff --git a/app/src/main/res/drawable-anydpi/ic_action_wallpaper.xml b/app/src/main/res/drawable-anydpi/ic_action_wallpaper.xml new file mode 100644 index 0000000..028d51e --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_action_wallpaper.xml @@ -0,0 +1,11 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="#FFFFFF" + android:alpha="0.8"> + <path + android:fillColor="#FF000000" + android:pathData="M4,4h7L11,2L4,2c-1.1,0 -2,0.9 -2,2v7h2L4,4zM10,13l-4,5h12l-3,-4 -2.03,2.71L10,13zM17,8.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S14,7.67 14,8.5s0.67,1.5 1.5,1.5S17,9.33 17,8.5zM20,2h-7v2h7v7h2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,20h-7v2h7c1.1,0 2,-0.9 2,-2v-7h-2v7zM4,13L2,13v7c0,1.1 0.9,2 2,2h7v-2L4,20v-7z"/> +</vector> diff --git a/app/src/main/res/drawable-hdpi/ic_action_settings.png b/app/src/main/res/drawable-hdpi/ic_action_settings.png Binary files differnew file mode 100644 index 0000000..a99894b --- /dev/null +++ b/app/src/main/res/drawable-hdpi/ic_action_settings.png diff --git a/app/src/main/res/drawable-hdpi/ic_action_wallpaper.png b/app/src/main/res/drawable-hdpi/ic_action_wallpaper.png Binary files differnew file mode 100644 index 0000000..941f061 --- /dev/null +++ b/app/src/main/res/drawable-hdpi/ic_action_wallpaper.png diff --git a/app/src/main/res/drawable-mdpi/ic_action_settings.png b/app/src/main/res/drawable-mdpi/ic_action_settings.png Binary files differnew file mode 100644 index 0000000..69c67dd --- /dev/null +++ b/app/src/main/res/drawable-mdpi/ic_action_settings.png diff --git a/app/src/main/res/drawable-mdpi/ic_action_wallpaper.png b/app/src/main/res/drawable-mdpi/ic_action_wallpaper.png Binary files differnew file mode 100644 index 0000000..740fb8a --- /dev/null +++ b/app/src/main/res/drawable-mdpi/ic_action_wallpaper.png diff --git a/app/src/main/res/drawable-xhdpi/ic_action_settings.png b/app/src/main/res/drawable-xhdpi/ic_action_settings.png Binary files differnew file mode 100644 index 0000000..3d88a9e --- /dev/null +++ b/app/src/main/res/drawable-xhdpi/ic_action_settings.png diff --git a/app/src/main/res/drawable-xhdpi/ic_action_wallpaper.png b/app/src/main/res/drawable-xhdpi/ic_action_wallpaper.png Binary files differnew file mode 100644 index 0000000..1547cac --- /dev/null +++ b/app/src/main/res/drawable-xhdpi/ic_action_wallpaper.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_settings.png b/app/src/main/res/drawable-xxhdpi/ic_action_settings.png Binary files differnew file mode 100644 index 0000000..80e49bb --- /dev/null +++ b/app/src/main/res/drawable-xxhdpi/ic_action_settings.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_wallpaper.png b/app/src/main/res/drawable-xxhdpi/ic_action_wallpaper.png Binary files differnew file mode 100644 index 0000000..45a7f14 --- /dev/null +++ b/app/src/main/res/drawable-xxhdpi/ic_action_wallpaper.png diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..e0b9f70 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,29 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="108dp" + android:height="108dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="m4,4h7V2H4C2.9,2 2,2.9 2,4v7h2z"/> + <path + android:fillColor="#FF000000" + android:pathData="m20,2h-7v2h7v7h2V4C22,2.9 21.1,2 20,2Z"/> + <path + android:fillColor="#FF000000" + android:pathData="m20,20h-7v2h7c1.1,0 2,-0.9 2,-2v-7h-2z"/> + <path + android:fillColor="#FF000000" + android:pathData="M4,13H2v7c0,1.1 0.9,2 2,2h7V20H4Z"/> + <path + android:pathData="M16.978,4.5339L16.978,6.2133L15.2986,6.2133L15.2986,4.5339L8.5811,4.5339L8.5811,6.2133L6.9017,6.2133L6.9017,4.5339L5.2223,4.5339L5.2223,19.6483h1.6794v-1.6794h1.6794v1.6794h6.7175v-1.6794h1.6794v1.6794h1.6794L18.6573,4.5339ZM8.5811,16.2895L6.9017,16.2895v-1.6794h1.6794zM8.5811,12.9308L6.9017,12.9308v-1.6794h1.6794zM8.5811,9.572L6.9017,9.572L6.9017,7.8927h1.6794zM16.978,16.2895h-1.6794v-1.6794h1.6794zM16.978,12.9308h-1.6794v-1.6794h1.6794zM16.978,9.572L15.2986,9.572L15.2986,7.8927h1.6794z" + android:strokeWidth="0.83968925" + android:fillColor="#000000"/> + <path + android:pathData="m10.061,12.3404 l-3.1593,3.9492h9.478l-2.3695,-3.1593 -1.6034,2.1404z" + android:strokeWidth="0.78983057" + android:fillColor="#ffffff"/> + <path + android:pathData="m14.5593,8.8051c0,-0.83 -0.67,-1.5 -1.5,-1.5 -0.83,0 -1.5,0.67 -1.5,1.5 0,0.83 0.67,1.5 1.5,1.5 0.83,0 1.5,-0.67 1.5,-1.5z" + android:fillColor="#ffffff"/> +</vector> diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml new file mode 100644 index 0000000..4eb6d06 --- /dev/null +++ b/app/src/main/res/drawable/ic_logo.xml @@ -0,0 +1,29 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="m4,4h7V2H4C2.9,2 2,2.9 2,4v7h2z"/> + <path + android:fillColor="#FF000000" + android:pathData="m20,2h-7v2h7v7h2V4C22,2.9 21.1,2 20,2Z"/> + <path + android:fillColor="#FF000000" + android:pathData="m20,20h-7v2h7c1.1,0 2,-0.9 2,-2v-7h-2z"/> + <path + android:fillColor="#FF000000" + android:pathData="M4,13H2v7c0,1.1 0.9,2 2,2h7V20H4Z"/> + <path + android:pathData="M16.978,4.5339L16.978,6.2133L15.2986,6.2133L15.2986,4.5339L8.5811,4.5339L8.5811,6.2133L6.9017,6.2133L6.9017,4.5339L5.2223,4.5339L5.2223,19.6483h1.6794v-1.6794h1.6794v1.6794h6.7175v-1.6794h1.6794v1.6794h1.6794L18.6573,4.5339ZM8.5811,16.2895L6.9017,16.2895v-1.6794h1.6794zM8.5811,12.9308L6.9017,12.9308v-1.6794h1.6794zM8.5811,9.572L6.9017,9.572L6.9017,7.8927h1.6794zM16.978,16.2895h-1.6794v-1.6794h1.6794zM16.978,12.9308h-1.6794v-1.6794h1.6794zM16.978,9.572L15.2986,9.572L15.2986,7.8927h1.6794z" + android:strokeWidth="0.83968925" + android:fillColor="#000000"/> + <path + android:pathData="m10.061,12.3404 l-3.1593,3.9492h9.478l-2.3695,-3.1593 -1.6034,2.1404z" + android:strokeWidth="0.78983057" + android:fillColor="#ffffff"/> + <path + android:pathData="m14.5593,8.8051c0,-0.83 -0.67,-1.5 -1.5,-1.5 -0.83,0 -1.5,0.67 -1.5,1.5 0,0.83 0.67,1.5 1.5,1.5 0.83,0 1.5,-0.67 1.5,-1.5z" + android:fillColor="#ffffff"/> +</vector> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..f195562 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".MainActivity"> + + <SurfaceView + android:id="@+id/wallpaper_view" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <com.google.android.material.appbar.AppBarLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimary" + app:popupTheme="@style/AppTheme.PopupOverlay" /> + + </com.google.android.material.appbar.AppBarLayout> + + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/set_wallpaper" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|end" + android:layout_margin="@dimen/fab_margin" + app:srcCompat="@drawable/ic_action_wallpaper" /> + +</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/settings_activity.xml b/app/src/main/res/layout/settings_activity.xml new file mode 100644 index 0000000..de6591a --- /dev/null +++ b/app/src/main/res/layout/settings_activity.xml @@ -0,0 +1,9 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <FrameLayout + android:id="@+id/settings" + android:layout_width="match_parent" + android:layout_height="match_parent" /> +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml new file mode 100644 index 0000000..1f5570a --- /dev/null +++ b/app/src/main/res/menu/menu_main.xml @@ -0,0 +1,11 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + tools:context="com.javispedro.wallmotion.MainActivity"> + <item + android:id="@+id/action_settings" + android:icon="@drawable/ic_action_settings" + android:orderInCategory="100" + android:title="@string/action_settings" + app:showAsAction="ifRoom" /> +</menu> diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..7353dbd --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@color/ic_launcher_background"/> + <foreground android:drawable="@drawable/ic_launcher_foreground"/> +</adaptive-icon>
\ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..7353dbd --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@color/ic_launcher_background"/> + <foreground android:drawable="@drawable/ic_launcher_foreground"/> +</adaptive-icon>
\ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..9045b44 --- /dev/null +++ b/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png Binary files differnew file mode 100644 index 0000000..3def45d --- /dev/null +++ b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..78e6f12 --- /dev/null +++ b/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png Binary files differnew file mode 100644 index 0000000..c7f9915 --- /dev/null +++ b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..dd4c9e1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png Binary files differnew file mode 100644 index 0000000..4ee79f8 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..553d0d3 --- /dev/null +++ b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png Binary files differnew file mode 100644 index 0000000..895d9eb --- /dev/null +++ b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..5baec4f --- /dev/null +++ b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png Binary files differnew file mode 100644 index 0000000..c5998f7 --- /dev/null +++ b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/app/src/main/res/raw/video_file_error.mp4 b/app/src/main/res/raw/video_file_error.mp4 Binary files differnew file mode 100644 index 0000000..64b8c83 --- /dev/null +++ b/app/src/main/res/raw/video_file_error.mp4 diff --git a/app/src/main/res/raw/video_file_missing.mp4 b/app/src/main/res/raw/video_file_missing.mp4 Binary files differnew file mode 100644 index 0000000..050dc56 --- /dev/null +++ b/app/src/main/res/raw/video_file_missing.mp4 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml new file mode 100644 index 0000000..073ac70 --- /dev/null +++ b/app/src/main/res/values/arrays.xml @@ -0,0 +1,11 @@ +<resources> + <!-- Settings display zoom values --> + <string-array name="settings_display_scale_entries"> + <item>Stretch to fit</item> + <item>Scale and crop to fit</item> + </string-array> + <string-array name="settings_display_scale_values"> + <item>@string/settings_display_scale_to_fit_key</item> + <item>@string/settings_display_scale_to_fit_with_cropping_key</item> + </string-array> +</resources>
\ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..69b2233 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="colorPrimary">#008577</color> + <color name="colorPrimaryDark">#00574B</color> + <color name="colorAccent">#D81B60</color> +</resources> diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..59a0b0c --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,3 @@ +<resources> + <dimen name="fab_margin">16dp</dimen> +</resources> diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..2a54660 --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="ic_launcher_background">#A4A633</color> +</resources>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..a8111a0 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,26 @@ +<resources> + <string name="app_name">Wallmotion</string> + + <string name="wallpaper_description">Use a video file as wallpaper</string> + + <!-- Main activity --> + <string name="action_settings">Settings</string> + + <!-- Preferences --> + <string name="title_activity_settings">Wallmotion settings</string> + <string name="settings_source_header">Source video</string> + <string name="settings_video_file_key">video_file</string> + <string name="settings_video_file_title">Video file</string> + <string name="settings_video_file_clear_key">video_file_clear</string> + <string name="settings_video_file_clear_title">Reset to (none)</string> + <string name="settings_not_set">(None)</string> + <string name="settings_display_header">Display options</string> + <string name="settings_display_scale_key">scale</string> + <string name="settings_display_scale_title">Scaling</string> + <string name="settings_display_scale_to_fit_key">scale_to_fit</string> + <string name="settings_display_scale_to_fit_with_cropping_key">scale_to_fit_with_cropping</string> + <string name="settings_display_restart_key">restart</string> + <string name="settings_display_restart_title">Restart video on each display</string> + <string name="settings_display_restart_title_on">Video will be restarted every time wallpaper is shown</string> + <string name="settings_display_restart_title_off">Video time will be remembered every time wallpaper is shown</string> +</resources> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..545b9c6 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ +<resources> + + <!-- Base application theme. --> + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> + <!-- Customize your theme here. --> + <item name="colorPrimary">@color/colorPrimary</item> + <item name="colorPrimaryDark">@color/colorPrimaryDark</item> + <item name="colorAccent">@color/colorAccent</item> + </style> + + <style name="AppTheme.NoActionBar"> + <item name="windowActionBar">false</item> + <item name="windowNoTitle">true</item> + </style> + + <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> + + <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> + +</resources> diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml new file mode 100644 index 0000000..14b05d7 --- /dev/null +++ b/app/src/main/res/xml/root_preferences.xml @@ -0,0 +1,32 @@ +<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"> + + <PreferenceCategory app:title="@string/settings_source_header"> + <Preference + app:key="@string/settings_video_file_key" + app:title="@string/settings_video_file_title" + app:persistent="true" /> + <Preference + app:key="@string/settings_video_file_clear_key" + app:title="@string/settings_video_file_clear_title" + /> + </PreferenceCategory> + + <PreferenceCategory app:title="@string/settings_display_header"> + <ListPreference + app:key="@string/settings_display_scale_key" + app:title="@string/settings_display_scale_title" + app:entries="@array/settings_display_scale_entries" + app:entryValues="@array/settings_display_scale_values" + app:defaultValue="@string/settings_display_scale_to_fit_key" + app:useSimpleSummaryProvider="true" + app:persistent="true" /> + <SwitchPreferenceCompat + app:key="@string/settings_display_restart_key" + app:title="@string/settings_display_restart_title" + app:summaryOn="@string/settings_display_restart_title_on" + app:summaryOff="@string/settings_display_restart_title_off" + app:persistent="true" + /> + </PreferenceCategory> + +</PreferenceScreen> diff --git a/app/src/main/res/xml/wallpaper.xml b/app/src/main/res/xml/wallpaper.xml new file mode 100644 index 0000000..d4af285 --- /dev/null +++ b/app/src/main/res/xml/wallpaper.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" + android:description="@string/wallpaper_description" + android:settingsActivity="com.javispedro.wallmotion.SettingsActivity" + android:thumbnail="@drawable/ic_logo" + /> diff --git a/app/svgs/generate_video.sh b/app/svgs/generate_video.sh new file mode 100755 index 0000000..450a7eb --- /dev/null +++ b/app/svgs/generate_video.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +for i in video_file_missing video_file_error; do + ffmpeg -stream_loop 16 -i $i.png -vc libx264 -pix_fmt yuv420p -vprofile baseline -vf setpts=N/TB -movflags +faststart $i.mp4 +done + + diff --git a/app/svgs/video_file_error.png b/app/svgs/video_file_error.png Binary files differnew file mode 100644 index 0000000..fae4451 --- /dev/null +++ b/app/svgs/video_file_error.png diff --git a/app/svgs/video_file_error.svg b/app/svgs/video_file_error.svg new file mode 100644 index 0000000..adee487 --- /dev/null +++ b/app/svgs/video_file_error.svg @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + height="26" + viewBox="0 0 26 26" + width="26" + version="1.1" + id="svg116" + sodipodi:docname="video_file_error.svg" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)" + inkscape:export-xdpi="1890.4615" + inkscape:export-ydpi="1890.4615"> + <metadata + id="metadata122"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs120" /> + <sodipodi:namedview + pagecolor="#000000" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="3708" + inkscape:window-height="2032" + id="namedview118" + showgrid="false" + inkscape:snap-page="true" + inkscape:snap-center="true" + inkscape:snap-object-midpoints="true" + inkscape:object-paths="true" + inkscape:snap-intersection-paths="true" + inkscape:snap-bbox="true" + inkscape:bbox-paths="true" + inkscape:snap-bbox-edge-midpoints="true" + inkscape:snap-bbox-midpoints="true" + inkscape:bbox-nodes="true" + inkscape:snap-smooth-nodes="true" + inkscape:snap-midpoints="false" + inkscape:snap-text-baseline="true" + inkscape:zoom="21.05" + inkscape:cx="-7.8574822" + inkscape:cy="10.342829" + inkscape:window-x="132" + inkscape:window-y="54" + inkscape:window-maximized="1" + inkscape:current-layer="svg116" + inkscape:pagecheckerboard="false" /> + <rect + style="fill:#000000;stroke-width:1.0620501" + id="rect4719" + width="31.130642" + height="30.750593" + x="-2.5653207" + y="-1.615202" /> + <path + d="m 19.090649,5.0023748 2,4 h -3 l -2,-4 h -2 l 2,4 h -3 l -2,-4 H 9.0906487 l 2.0000003,4 H 8.0906487 l -2,-4 h -1 c -1.1,0 -1.99,0.9 -1.99,2 l -0.01,12.0000002 c 0,1.1 0.9,2 2,2 H 21.090649 c 1.1,0 2,-0.9 2,-2 V 5.0023748 Z" + id="path112" + inkscape:connector-curvature="0" + style="fill:#ffffff" /> + <g + id="g4785" + transform="matrix(0.50000001,0,0,0.50000001,7.0735941,9.0023748)"> + <path + id="path4771" + d="M 0,0 H 24 V 24 H 0 Z" + inkscape:connector-curvature="0" + style="fill:none" /> + <path + id="path4773" + d="M 12,2 C 6.48,2 2,6.48 2,12 2,17.52 6.48,22 12,22 17.52,22 22,17.52 22,12 22,6.48 17.52,2 12,2 Z m 1,15 h -2 v -2 h 2 z m 0,-4 H 11 V 7 h 2 z" + inkscape:connector-curvature="0" /> + </g> +</svg> diff --git a/app/svgs/video_file_missing.png b/app/svgs/video_file_missing.png Binary files differnew file mode 100644 index 0000000..51d3e79 --- /dev/null +++ b/app/svgs/video_file_missing.png diff --git a/app/svgs/video_file_missing.svg b/app/svgs/video_file_missing.svg new file mode 100644 index 0000000..0291c75 --- /dev/null +++ b/app/svgs/video_file_missing.svg @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + id="svg116" + version="1.1" + width="26" + viewBox="0 0 26 26" + height="26"> + <metadata + id="metadata122"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs120" /> + <path + id="path112" + d="m 19.090649,5.0023748 2,4 h -3 l -2,-4 h -2 l 2,4 h -3 l -2,-4 H 9.0906487 l 2.0000003,4 H 8.0906487 l -2,-4 h -1 c -1.1,0 -1.99,0.9 -1.99,2 l -0.01,12.0000002 c 0,1.1 0.9,2 2,2 H 21.090649 c 1.1,0 2,-0.9 2,-2 V 5.0023748 Z" /> + <flowRoot + transform="matrix(0.35923173,0,0,0.35923173,0.90313202,6.2805158)" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto weight=255';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none" + id="flowRoot124" + xml:space="preserve"><flowRegion + style="font-style:normal;font-variant:normal;font-stretch:normal;font-family:Roboto;-inkscape-font-specification:'Roboto weight=255';text-align:center;text-anchor:middle;fill:#ffffff" + id="flowRegion126"><rect + style="font-style:normal;font-variant:normal;font-stretch:normal;font-family:Roboto;-inkscape-font-specification:'Roboto weight=255';text-align:center;text-anchor:middle;fill:#ffffff" + y="1.5866983" + x="6.223278" + height="55.106888" + width="56.722092" + id="rect128" /></flowRegion><flowPara + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Roboto;-inkscape-font-specification:'Roboto Bold';text-align:center;text-anchor:middle;fill:#ffffff" + id="flowPara130">?</flowPara></flowRoot></svg> diff --git a/app/svgs/videowall.svg b/app/svgs/videowall.svg new file mode 100644 index 0000000..e1f6367 --- /dev/null +++ b/app/svgs/videowall.svg @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + height="24" + viewBox="0 0 24 24" + width="24" + version="1.1" + id="svg898" + sodipodi:docname="videowall.svg" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + <metadata + id="metadata904"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs902" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="3708" + inkscape:window-height="2032" + id="namedview900" + showgrid="false" + inkscape:zoom="9.8333333" + inkscape:cx="-30.508475" + inkscape:cy="9.9775549" + inkscape:window-x="132" + inkscape:window-y="54" + inkscape:window-maximized="1" + inkscape:current-layer="svg898" /> + <path + d="m 4,4 h 7 V 2 H 4 C 2.9,2 2,2.9 2,4 v 7 h 2 z" + id="path1474" /> + <path + d="m 20,2 h -7 v 2 h 7 v 7 h 2 V 4 C 22,2.9 21.1,2 20,2 Z" + id="path1468" /> + <path + d="m 20,20 h -7 v 2 h 7 c 1.1,0 2,-0.9 2,-2 v -7 h -2 z" + id="path1466" /> + <path + d="M 4,13 H 2 v 7 c 0,1.1 0.9,2 2,2 h 7 V 20 H 4 Z" + id="path894" /> + <path + d="M0 0h24v24H0z" + fill="none" + id="path896" /> + <path + inkscape:connector-curvature="0" + d="M 16.977966,4.5338995 V 6.213278 H 15.298587 V 4.5338995 H 8.581073 V 6.213278 H 6.901695 V 4.5338995 H 5.222316 V 19.648305 h 1.679379 v -1.679377 h 1.679378 v 1.679377 h 6.717514 v -1.679377 h 1.679379 v 1.679377 h 1.679379 V 4.5338995 Z M 8.581073,16.289548 H 6.901695 v -1.679379 h 1.679378 z m 0,-3.358757 H 6.901695 v -1.679377 h 1.679378 z m 0,-3.358755 H 6.901695 V 7.892657 h 1.679378 z m 8.396893,6.717512 h -1.679379 v -1.679379 h 1.679379 z m 0,-3.358757 h -1.679379 v -1.679377 h 1.679379 z m 0,-3.358755 H 15.298587 V 7.892657 h 1.679379 z" + id="path882" + style="fill:#000000;stroke-width:0.83968925" /> + <path + d="m 10.061018,12.340395 -3.159323,3.949153 h 9.477966 l -2.369492,-3.159323 -1.603356,2.140441 z" + id="path1472" + inkscape:connector-curvature="0" + style="fill:#ffffff;stroke-width:0.78983057" /> + <path + d="m 14.559322,8.8050847 c 0,-0.83 -0.67,-1.5 -1.5,-1.5 -0.83,0 -1.5,0.67 -1.5,1.5 0,0.83 0.67,1.5000003 1.5,1.5000003 0.83,0 1.5,-0.6700003 1.5,-1.5000003 z" + id="path1470" + style="fill:#ffffff" + inkscape:connector-curvature="0" /> +</svg> |