├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── cyanogenmod │ │ └── designertools │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── org │ │ │ └── cyanogenmod │ │ │ └── designertools │ │ │ ├── DesignerToolsApplication.java │ │ │ ├── overlays │ │ │ ├── ColorPickerOverlay.java │ │ │ ├── GridOverlay.java │ │ │ └── MockOverlay.java │ │ │ ├── qs │ │ │ ├── ColorPickerQuickSettingsTile.java │ │ │ ├── GridQuickSettingsTile.java │ │ │ ├── MockQuickSettingsTile.java │ │ │ └── OnOffTileState.java │ │ │ ├── receiver │ │ │ └── BootReceiver.java │ │ │ ├── service │ │ │ ├── ScreenshotInfoService.java │ │ │ ├── ScreenshotListenerService.java │ │ │ └── qs │ │ │ │ ├── ColorPickerTileService.java │ │ │ │ ├── GridOverlayTileService.java │ │ │ │ └── MockOverlayTileService.java │ │ │ ├── ui │ │ │ ├── ColorPickerCardFragment.java │ │ │ ├── CreditsActivity.java │ │ │ ├── DesignerToolCardFragment.java │ │ │ ├── DesignerToolsActivity.java │ │ │ ├── DualColorPickerDialog.java │ │ │ ├── GridOverlayCardFragment.java │ │ │ ├── MockupOverlayCardFragmnt.java │ │ │ ├── ScreenRecordRequestActivity.java │ │ │ ├── ScreenshotCardFragment.java │ │ │ └── StartOverlayActivity.java │ │ │ ├── utils │ │ │ ├── ColorUtils.java │ │ │ ├── ImageUtils.java │ │ │ ├── LaunchUtils.java │ │ │ ├── LayoutRenderUtils.java │ │ │ ├── MockupUtils.java │ │ │ └── PreferenceUtils.java │ │ │ └── widget │ │ │ ├── DualColorPicker.java │ │ │ ├── GridPreview.java │ │ │ ├── MagnifierNodeView.java │ │ │ ├── MagnifierView.java │ │ │ └── VerticalSeekBar.java │ └── res │ │ ├── drawable-hdpi │ │ ├── color_hex_backer.9.png │ │ └── loop_ring.png │ │ ├── drawable-mdpi │ │ ├── color_hex_backer.9.png │ │ └── loop_ring.png │ │ ├── drawable-nodpi │ │ ├── aaron.png │ │ ├── asher.png │ │ ├── clark.png │ │ ├── img_header_bg.png │ │ └── kover.png │ │ ├── drawable-xhdpi │ │ ├── color_hex_backer.9.png │ │ └── loop_ring.png │ │ ├── drawable-xxhdpi │ │ ├── color_hex_backer.9.png │ │ └── loop_ring.png │ │ ├── drawable-xxxhdpi │ │ ├── color_hex_backer.9.png │ │ └── loop_ring.png │ │ ├── drawable │ │ ├── card_background.xml │ │ ├── half_circle_left.xml │ │ ├── ic_add.xml │ │ ├── ic_header_glyph.xml │ │ ├── ic_marker_horiz_left.xml │ │ ├── ic_marker_horiz_right.xml │ │ ├── ic_marker_vert.xml │ │ ├── ic_qs_colorpicker_off.xml │ │ ├── ic_qs_colorpicker_on.xml │ │ ├── ic_qs_grid_off.xml │ │ ├── ic_qs_grid_on.xml │ │ ├── ic_qs_layoutbounds_off.xml │ │ ├── ic_qs_layoutbounds_on.xml │ │ ├── ic_qs_overlay_off.xml │ │ ├── ic_qs_overlay_on.xml │ │ ├── ic_qs_screenshotinfo_off.xml │ │ ├── ic_qs_screenshotinfo_on.xml │ │ ├── loop_node.xml │ │ ├── pick_mock_overlay_background.xml │ │ └── pick_mockup_frame.xml │ │ ├── layout-land │ │ ├── activity_designer_tools.xml │ │ └── app_header.xml │ │ ├── layout-w600dp │ │ └── activity_designer_tools.xml │ │ ├── layout │ │ ├── activity_credits.xml │ │ ├── activity_designer_tools.xml │ │ ├── app_header.xml │ │ ├── card_header.xml │ │ ├── card_layout.xml │ │ ├── color_picker_magnifier.xml │ │ ├── credits_header.xml │ │ ├── dialog_color_picker.xml │ │ ├── grid_overlay_content.xml │ │ ├── lobsterpicker.xml │ │ ├── mockup_overlay_content.xml │ │ └── screenshot_info.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-land │ │ └── dimens.xml │ │ ├── values-w600dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── integers.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── org │ └── cyanogenmod │ └── designertools │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── designer_tools.png └── quick_settings_tiles.png ├── projectFilesBackup └── .idea │ └── workspace.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/vcs.xml 6 | /.idea/libraries 7 | .DS_Store 8 | /build 9 | /captures 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Designer Tools 2 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.cyngn.designertools" 9 | minSdkVersion 23 10 | targetSdkVersion 25 11 | versionCode 2 12 | versionName "2.0.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:25.1.0' 26 | compile 'org.cyanogenmod:platform.sdk:6.0' 27 | compile 'com.larswerkman:lobsterpicker:1.0.1' 28 | compile 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar' 29 | } 30 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\clark\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/org/cyanogenmod/designertools/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.cyanogenmod.designertools; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 37 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 84 | 85 | 86 | 87 | 88 | 89 | 94 | 95 | 96 | 97 | 98 | 99 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/DesignerToolsApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools; 17 | 18 | import android.app.Activity; 19 | import android.app.Application; 20 | import android.content.Intent; 21 | 22 | public class DesignerToolsApplication extends Application { 23 | 24 | private int mResultCode = Activity.RESULT_CANCELED; 25 | private Intent mResultData; 26 | 27 | private boolean mGridOverlayOn; 28 | private boolean mMockOverlayOn; 29 | private boolean mColorPickerOn; 30 | private boolean mScreenshotOn; 31 | 32 | public void setScreenRecordPermissionData(int resultCode, Intent resultData) { 33 | mResultCode = resultCode; 34 | mResultData = resultData; 35 | } 36 | 37 | public int getScreenRecordResultCode() { 38 | return mResultCode; 39 | } 40 | 41 | public Intent getScreenRecordResultData() { 42 | return mResultData; 43 | } 44 | 45 | public void setGridOverlayOn(boolean on) { 46 | mGridOverlayOn = on; 47 | } 48 | 49 | public boolean getGridOverlayOn() { 50 | return mGridOverlayOn; 51 | } 52 | 53 | public void setMockOverlayOn(boolean on) { 54 | mMockOverlayOn = on; 55 | } 56 | 57 | public boolean getMockOverlayOn() { 58 | return mMockOverlayOn; 59 | } 60 | 61 | public void setColorPickerOn(boolean on) { 62 | mColorPickerOn = on; 63 | } 64 | 65 | public boolean getColorPickerOn() { 66 | return mColorPickerOn; 67 | } 68 | 69 | public void setScreenshotOn(boolean on) { 70 | mScreenshotOn = on; 71 | } 72 | 73 | public boolean getScreenshotOn() { 74 | return mScreenshotOn; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/qs/ColorPickerQuickSettingsTile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.qs; 17 | 18 | import android.app.Activity; 19 | import android.app.PendingIntent; 20 | import android.content.BroadcastReceiver; 21 | import android.content.Context; 22 | import android.content.Intent; 23 | 24 | import org.cyanogenmod.designertools.DesignerToolsApplication; 25 | import org.cyanogenmod.designertools.overlays.ColorPickerOverlay; 26 | import org.cyanogenmod.designertools.ui.ScreenRecordRequestActivity; 27 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 28 | import org.cyanogenmod.designertools.R; 29 | 30 | import cyanogenmod.app.CMStatusBarManager; 31 | import cyanogenmod.app.CustomTile; 32 | 33 | public class ColorPickerQuickSettingsTile { 34 | private static final String TAG = ColorPickerQuickSettingsTile.class.getSimpleName(); 35 | 36 | public static final String ACTION_TOGGLE_STATE = 37 | "org.cyanogenmod.designertools.action.TOGGLE_COLOR_PICKER_STATE"; 38 | 39 | public static final String ACTION_UNPUBLISH = 40 | "org.cyanogenmod.designertools.action.UNPUBLISH_COLOR_PICKER_TILE"; 41 | 42 | public static final int TILE_ID = 5000; 43 | 44 | public static void publishColorPickerTile(Context context) { 45 | publishColorPickerTile(context, OnOffTileState.STATE_OFF); 46 | } 47 | 48 | public static void publishColorPickerTile(Context context, int state) { 49 | Intent intent = new Intent(ACTION_TOGGLE_STATE); 50 | intent.putExtra(OnOffTileState.EXTRA_STATE, state); 51 | PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 52 | PendingIntent.FLAG_UPDATE_CURRENT); 53 | int iconResId = 54 | state == OnOffTileState.STATE_OFF ? R.drawable.ic_qs_colorpicker_off : 55 | R.drawable.ic_qs_colorpicker_on; 56 | CustomTile tile = new CustomTile.Builder(context) 57 | .setOnClickIntent(pi) 58 | .setLabel(context.getString(R.string.color_picker_qs_tile_label)) 59 | .setIcon(iconResId) 60 | .build(); 61 | CMStatusBarManager.getInstance(context).publishTile(TAG, TILE_ID, tile); 62 | PreferenceUtils.setColorPickerQsTileEnabled(context, true); 63 | } 64 | 65 | public static void unpublishColorPickerTile(Context context) { 66 | CMStatusBarManager.getInstance(context).removeTile(TAG, TILE_ID); 67 | PreferenceUtils.setColorPickerQsTileEnabled(context, false); 68 | Intent intent = new Intent(ColorPickerQuickSettingsTile.ACTION_UNPUBLISH); 69 | context.sendBroadcast(intent); 70 | } 71 | 72 | public static class ClickBroadcastReceiver extends BroadcastReceiver { 73 | @Override 74 | public void onReceive(Context context, Intent intent) { 75 | if (PreferenceUtils.getColorPickerQsTileEnabled(context, false)) { 76 | int state = 77 | intent.getIntExtra(OnOffTileState.EXTRA_STATE, OnOffTileState.STATE_OFF); 78 | if (state == OnOffTileState.STATE_OFF) { 79 | publishColorPickerTile(context, OnOffTileState.STATE_ON); 80 | startColorPickerOrRequestPermission(context); 81 | } else { 82 | publishColorPickerTile(context, OnOffTileState.STATE_OFF); 83 | PreferenceUtils.setColorPickerActive(context, false); 84 | } 85 | } 86 | } 87 | 88 | private void startColorPickerOrRequestPermission(Context context) { 89 | DesignerToolsApplication app = 90 | (DesignerToolsApplication) context.getApplicationContext(); 91 | if (app.getScreenRecordResultCode() == Activity.RESULT_OK && app.getScreenRecordResultData() != null) { 92 | Intent newIntent = new Intent(context, ColorPickerOverlay.class); 93 | context.startService(newIntent); 94 | PreferenceUtils.setColorPickerActive(context, true); 95 | } else { 96 | Intent intent = new Intent(context, ScreenRecordRequestActivity.class); 97 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 98 | context.startActivity(intent); 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/qs/GridQuickSettingsTile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.qs; 17 | 18 | import android.app.PendingIntent; 19 | import android.content.BroadcastReceiver; 20 | import android.content.Context; 21 | import android.content.Intent; 22 | 23 | import org.cyanogenmod.designertools.R; 24 | import org.cyanogenmod.designertools.overlays.GridOverlay; 25 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 26 | 27 | import cyanogenmod.app.CMStatusBarManager; 28 | import cyanogenmod.app.CustomTile; 29 | 30 | public class GridQuickSettingsTile { 31 | private static final String TAG = GridQuickSettingsTile.class.getSimpleName(); 32 | 33 | public static final String ACTION_TOGGLE_STATE = 34 | "org.cyanogenmod.designertools.action.TOGGLE_GRID_STATE"; 35 | 36 | public static final String ACTION_UNPUBLISH = 37 | "org.cyanogenmod.designertools.action.UNPUBLISH_GRID_TILE"; 38 | 39 | public static final int TILE_ID = 1000; 40 | 41 | public static void publishGridTile(Context context) { 42 | publishGridTile(context, OnOffTileState.STATE_OFF); 43 | } 44 | 45 | public static void publishGridTile(Context context, int state) { 46 | Intent intent = new Intent(ACTION_TOGGLE_STATE); 47 | intent.putExtra(OnOffTileState.EXTRA_STATE, state); 48 | PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 49 | PendingIntent.FLAG_UPDATE_CURRENT); 50 | int iconResId = state == OnOffTileState.STATE_OFF ? R.drawable.ic_qs_grid_off : 51 | R.drawable.ic_qs_grid_on; 52 | CustomTile tile = new CustomTile.Builder(context) 53 | .setOnClickIntent(pi) 54 | .setLabel(context.getString(R.string.grid_qs_tile_label)) 55 | .setIcon(iconResId) 56 | .build(); 57 | CMStatusBarManager.getInstance(context).publishTile(TAG, TILE_ID, tile); 58 | PreferenceUtils.setGridQsTileEnabled(context, true); 59 | } 60 | 61 | public static void unpublishGridTile(Context context) { 62 | CMStatusBarManager.getInstance(context).removeTile(TAG, TILE_ID); 63 | PreferenceUtils.setGridQsTileEnabled(context, false); 64 | Intent intent = new Intent(GridQuickSettingsTile.ACTION_UNPUBLISH); 65 | context.sendBroadcast(intent); 66 | } 67 | 68 | public static class ClickBroadcastReceiver extends BroadcastReceiver { 69 | @Override 70 | public void onReceive(Context context, Intent intent) { 71 | int state = intent.getIntExtra(OnOffTileState.EXTRA_STATE, OnOffTileState.STATE_OFF); 72 | if (state == OnOffTileState.STATE_OFF) { 73 | publishGridTile(context, OnOffTileState.STATE_ON); 74 | Intent newIntent = new Intent(context, GridOverlay.class); 75 | context.startService(newIntent); 76 | PreferenceUtils.setGridOverlayActive(context, true); 77 | } else { 78 | publishGridTile(context, OnOffTileState.STATE_OFF); 79 | PreferenceUtils.setGridOverlayActive(context, false); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/qs/MockQuickSettingsTile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.qs; 17 | 18 | import android.app.PendingIntent; 19 | import android.content.BroadcastReceiver; 20 | import android.content.Context; 21 | import android.content.Intent; 22 | 23 | import org.cyanogenmod.designertools.R; 24 | import org.cyanogenmod.designertools.overlays.MockOverlay; 25 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 26 | 27 | import cyanogenmod.app.CMStatusBarManager; 28 | import cyanogenmod.app.CustomTile; 29 | 30 | public class MockQuickSettingsTile { 31 | private static final String TAG = MockQuickSettingsTile.class.getSimpleName(); 32 | 33 | public static final String ACTION_TOGGLE_STATE = 34 | "org.cyanogenmod.designertools.action.TOGGLE_MOCK_STATE"; 35 | 36 | public static final String ACTION_UNPUBLISH = 37 | "org.cyanogenmod.designertools.action.UNPUBLISH_MOCK_TILE"; 38 | 39 | public static final int TILE_ID = 2000; 40 | 41 | public static void publishMockTile(Context context) { 42 | publishMockTile(context, OnOffTileState.STATE_OFF); 43 | } 44 | 45 | public static void publishMockTile(Context context, int state) { 46 | Intent intent = new Intent(ACTION_TOGGLE_STATE); 47 | intent.putExtra(OnOffTileState.EXTRA_STATE, state); 48 | PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 49 | PendingIntent.FLAG_UPDATE_CURRENT); 50 | int iconResId = state == OnOffTileState.STATE_OFF ? R.drawable.ic_qs_overlay_off : 51 | R.drawable.ic_qs_overlay_on; 52 | CustomTile tile = new CustomTile.Builder(context) 53 | .setOnClickIntent(pi) 54 | .setLabel(context.getString(R.string.mock_qs_tile_label)) 55 | .setIcon(iconResId) 56 | .build(); 57 | CMStatusBarManager.getInstance(context).publishTile(TAG, TILE_ID, tile); 58 | PreferenceUtils.setMockQsTileEnabled(context, true); 59 | } 60 | 61 | public static void unpublishMockTile(Context context) { 62 | CMStatusBarManager.getInstance(context).removeTile(TAG, TILE_ID); 63 | PreferenceUtils.setMockQsTileEnabled(context, false); 64 | Intent intent = new Intent(MockQuickSettingsTile.ACTION_UNPUBLISH); 65 | context.sendBroadcast(intent); 66 | } 67 | 68 | public static class ClickBroadcastReceiver extends BroadcastReceiver { 69 | @Override 70 | public void onReceive(Context context, Intent intent) { 71 | int state = intent.getIntExtra(OnOffTileState.EXTRA_STATE, OnOffTileState.STATE_OFF); 72 | if (state == OnOffTileState.STATE_OFF) { 73 | publishMockTile(context, OnOffTileState.STATE_ON); 74 | Intent newIntent = new Intent(context, MockOverlay.class); 75 | context.startService(newIntent); 76 | PreferenceUtils.setMockOverlayActive(context, true); 77 | } else { 78 | publishMockTile(context, OnOffTileState.STATE_OFF); 79 | PreferenceUtils.setMockOverlayActive(context, false); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/qs/OnOffTileState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.qs; 17 | 18 | public class OnOffTileState { 19 | public static final String EXTRA_STATE = "state"; 20 | 21 | public static final int STATE_OFF = 0; 22 | public static final int STATE_ON = 1; 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/receiver/BootReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.receiver; 17 | 18 | import android.content.BroadcastReceiver; 19 | import android.content.Context; 20 | import android.content.Intent; 21 | 22 | import org.cyanogenmod.designertools.qs.ColorPickerQuickSettingsTile; 23 | import org.cyanogenmod.designertools.qs.GridQuickSettingsTile; 24 | import org.cyanogenmod.designertools.qs.MockQuickSettingsTile; 25 | import org.cyanogenmod.designertools.service.ScreenshotListenerService; 26 | import org.cyanogenmod.designertools.utils.LaunchUtils; 27 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 28 | 29 | public class BootReceiver extends BroadcastReceiver { 30 | public BootReceiver() { 31 | } 32 | 33 | @Override 34 | public void onReceive(Context context, Intent intent) { 35 | final boolean isCm = LaunchUtils.isCyanogenMod(context); 36 | if (PreferenceUtils.getGridQsTileEnabled(context, false)) { 37 | PreferenceUtils.setGridOverlayActive(context, false); 38 | if (isCm) GridQuickSettingsTile.publishGridTile(context); 39 | } 40 | if (PreferenceUtils.getMockQsTileEnabled(context, false)) { 41 | PreferenceUtils.setMockOverlayActive(context, false); 42 | if (isCm) MockQuickSettingsTile.publishMockTile(context); 43 | } 44 | if (PreferenceUtils.getColorPickerQsTileEnabled(context, false)) { 45 | PreferenceUtils.setColorPickerActive(context, false); 46 | if (isCm) ColorPickerQuickSettingsTile.publishColorPickerTile(context); 47 | } 48 | if (PreferenceUtils.getScreenshotInfoEnabled(context, false)) { 49 | Intent newIntent = new Intent(context, ScreenshotListenerService.class); 50 | context.startService(newIntent); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/service/ScreenshotListenerService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.service; 17 | 18 | import android.app.Notification; 19 | import android.app.PendingIntent; 20 | import android.app.Service; 21 | import android.content.Intent; 22 | import android.content.SharedPreferences; 23 | import android.database.ContentObserver; 24 | import android.database.Cursor; 25 | import android.net.Uri; 26 | import android.os.Handler; 27 | import android.os.IBinder; 28 | import android.provider.MediaStore; 29 | import android.util.Log; 30 | 31 | import org.cyanogenmod.designertools.R; 32 | import org.cyanogenmod.designertools.ui.DesignerToolsActivity; 33 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 34 | 35 | import java.io.File; 36 | 37 | public class ScreenshotListenerService extends Service 38 | implements SharedPreferences.OnSharedPreferenceChangeListener { 39 | 40 | private ScreenShotObserver mScreenshotObserver; 41 | 42 | @Override 43 | public IBinder onBind(Intent intent) { 44 | return null; 45 | } 46 | 47 | @Override 48 | public void onCreate() { 49 | super.onCreate(); 50 | PreferenceUtils.getShardedPreferences(this).registerOnSharedPreferenceChangeListener(this); 51 | startForeground(42, getPersistentNotification()); 52 | } 53 | 54 | @Override 55 | public int onStartCommand(Intent intent, int flags, int startId) { 56 | if (mScreenshotObserver == null) { 57 | mScreenshotObserver = new ScreenShotObserver(new Handler()); 58 | getContentResolver().registerContentObserver( 59 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, mScreenshotObserver); 60 | } 61 | return START_STICKY; 62 | } 63 | 64 | @Override 65 | public void onDestroy() { 66 | super.onDestroy(); 67 | PreferenceUtils.getShardedPreferences(this) 68 | .unregisterOnSharedPreferenceChangeListener(this); 69 | if (mScreenshotObserver != null) { 70 | getContentResolver().unregisterContentObserver(mScreenshotObserver); 71 | } 72 | } 73 | 74 | @Override 75 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 76 | if (PreferenceUtils.KEY_SCREENSHOT_INFO.equals(key)) { 77 | boolean enabled = PreferenceUtils.getScreenshotInfoEnabled(this, false); 78 | if (!enabled) { 79 | stopSelf(); 80 | } 81 | } 82 | } 83 | 84 | private Notification getPersistentNotification() { 85 | PendingIntent pi = PendingIntent.getActivity(this, 0, 86 | new Intent(this, DesignerToolsActivity.class), 0); 87 | Notification.Builder builder = new Notification.Builder(this); 88 | String text = getString(R.string.notif_content_screenshot_info); 89 | builder.setPriority(Notification.PRIORITY_MIN) 90 | .setSmallIcon(R.drawable.ic_qs_screenshotinfo_on) 91 | .setContentTitle(getString(R.string.screenshot_qs_tile_label)) 92 | .setContentText(text) 93 | .setStyle(new Notification.BigTextStyle().bigText(text)) 94 | .setContentIntent(pi); 95 | return builder.build(); 96 | } 97 | 98 | private class ScreenShotObserver extends ContentObserver { 99 | private final String TAG = ScreenShotObserver.class.getSimpleName(); 100 | private final String EXTERNAL_CONTENT_URI_MATCHER = 101 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString(); 102 | private final String[] PROJECTION = new String[] { 103 | MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.DATA, 104 | MediaStore.Images.Media.DATE_ADDED 105 | }; 106 | private static final String SORT_ORDER = MediaStore.Images.Media.DATE_ADDED + " DESC"; 107 | private static final long DEFAULT_DETECT_WINDOW_SECONDS = 10; 108 | 109 | private Handler mHandler; 110 | 111 | public ScreenShotObserver(Handler handler) { 112 | super(handler); 113 | mHandler = handler; 114 | } 115 | 116 | @Override 117 | public void onChange(boolean selfChange, Uri uri) { 118 | if (uri.toString().startsWith(EXTERNAL_CONTENT_URI_MATCHER)) { 119 | Cursor cursor = null; 120 | try { 121 | cursor = getContentResolver().query(uri, PROJECTION, null, null, 122 | SORT_ORDER); 123 | if (cursor != null && cursor.moveToFirst()) { 124 | String path = cursor.getString( 125 | cursor.getColumnIndex(MediaStore.Images.Media.DATA)); 126 | long dateAdded = cursor.getLong(cursor.getColumnIndex( 127 | MediaStore.Images.Media.DATE_ADDED)); 128 | long currentTime = System.currentTimeMillis() / 1000; 129 | Log.d(TAG, "path: " + path + ", dateAdded: " + dateAdded + 130 | ", currentTime: " + currentTime); 131 | if (path.toLowerCase().contains("screenshot") && 132 | Math.abs(currentTime - dateAdded) <= 133 | DEFAULT_DETECT_WINDOW_SECONDS) { 134 | Intent intent = 135 | new Intent(ScreenshotListenerService.this, 136 | ScreenshotInfoService.class); 137 | intent.putExtra(ScreenshotInfoService.EXTRA_PATH, path); 138 | final File file = new File(path); 139 | while (!file.exists()) { 140 | Thread.sleep(100); 141 | } 142 | startService(intent); 143 | } 144 | } 145 | } catch (Exception e) { 146 | Log.d(TAG, "open cursor fail"); 147 | } finally { 148 | if (cursor != null) { 149 | cursor.close(); 150 | } 151 | } 152 | } 153 | super.onChange(selfChange, uri); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/service/qs/ColorPickerTileService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.service.qs; 17 | 18 | import android.annotation.TargetApi; 19 | import android.graphics.drawable.Icon; 20 | import android.os.Build; 21 | import android.service.quicksettings.Tile; 22 | import android.service.quicksettings.TileService; 23 | import android.util.Log; 24 | 25 | import org.cyanogenmod.designertools.DesignerToolsApplication; 26 | import org.cyanogenmod.designertools.R; 27 | import org.cyanogenmod.designertools.utils.LaunchUtils; 28 | 29 | @TargetApi(Build.VERSION_CODES.N) 30 | public class ColorPickerTileService extends TileService { 31 | private static final String TAG = ColorPickerTileService.class.getSimpleName(); 32 | 33 | public ColorPickerTileService() { 34 | super(); 35 | } 36 | 37 | @Override 38 | public void onTileAdded() { 39 | super.onTileAdded(); 40 | } 41 | 42 | @Override 43 | public void onTileRemoved() { 44 | super.onTileRemoved(); 45 | } 46 | 47 | @Override 48 | public void onStartListening() { 49 | super.onStartListening(); 50 | updateTile(((DesignerToolsApplication) getApplication()).getColorPickerOn()); 51 | } 52 | 53 | @Override 54 | public void onStopListening() { 55 | super.onStopListening(); 56 | } 57 | 58 | @Override 59 | public void onClick() { 60 | super.onClick(); 61 | boolean isOn = ((DesignerToolsApplication) getApplicationContext()).getColorPickerOn(); 62 | if (isOn) { 63 | LaunchUtils.cancelColorPickerOrUnpublishTile(this); 64 | } else { 65 | LaunchUtils.lauchColorPickerOrPublishTile(this, 0); 66 | } 67 | updateTile(!isOn); 68 | } 69 | 70 | private void updateTile(boolean isOn) { 71 | final Tile tile = getQsTile(); 72 | tile.setIcon(Icon.createWithResource(this, isOn 73 | ? R.drawable.ic_qs_colorpicker_on 74 | : R.drawable.ic_qs_colorpicker_off)); 75 | tile.updateTile(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/service/qs/GridOverlayTileService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.service.qs; 17 | 18 | import android.annotation.TargetApi; 19 | import android.graphics.drawable.Icon; 20 | import android.os.Build; 21 | import android.service.quicksettings.Tile; 22 | import android.service.quicksettings.TileService; 23 | import android.util.Log; 24 | 25 | import org.cyanogenmod.designertools.DesignerToolsApplication; 26 | import org.cyanogenmod.designertools.R; 27 | import org.cyanogenmod.designertools.utils.LaunchUtils; 28 | 29 | @TargetApi(Build.VERSION_CODES.N) 30 | public class GridOverlayTileService extends TileService { 31 | private static final String TAG = GridOverlayTileService.class.getSimpleName(); 32 | 33 | public GridOverlayTileService() { 34 | super(); 35 | } 36 | 37 | @Override 38 | public void onTileAdded() { 39 | super.onTileAdded(); 40 | } 41 | 42 | @Override 43 | public void onTileRemoved() { 44 | super.onTileRemoved(); 45 | } 46 | 47 | @Override 48 | public void onStartListening() { 49 | super.onStartListening(); 50 | boolean isOn = ((DesignerToolsApplication) getApplicationContext()).getGridOverlayOn(); 51 | updateTile(isOn); 52 | } 53 | 54 | @Override 55 | public void onStopListening() { 56 | super.onStopListening(); 57 | } 58 | 59 | @Override 60 | public void onClick() { 61 | super.onClick(); 62 | boolean isOn = ((DesignerToolsApplication) getApplicationContext()).getGridOverlayOn(); 63 | if (isOn) { 64 | LaunchUtils.cancelGridOverlayOrUnpublishTile(this); 65 | } else { 66 | LaunchUtils.lauchGridOverlayOrPublishTile(this, 0); 67 | } 68 | updateTile(!isOn); 69 | } 70 | 71 | private void updateTile(boolean isOn) { 72 | final Tile tile = getQsTile(); 73 | tile.setIcon(Icon.createWithResource(this, isOn 74 | ? R.drawable.ic_qs_grid_on 75 | : R.drawable.ic_qs_grid_off)); 76 | tile.updateTile(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/service/qs/MockOverlayTileService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.service.qs; 17 | 18 | import android.annotation.TargetApi; 19 | import android.graphics.drawable.Icon; 20 | import android.os.Build; 21 | import android.service.quicksettings.Tile; 22 | import android.service.quicksettings.TileService; 23 | import android.util.Log; 24 | 25 | import org.cyanogenmod.designertools.DesignerToolsApplication; 26 | import org.cyanogenmod.designertools.R; 27 | import org.cyanogenmod.designertools.utils.LaunchUtils; 28 | 29 | @TargetApi(Build.VERSION_CODES.N) 30 | public class MockOverlayTileService extends TileService { 31 | private static final String TAG = MockOverlayTileService.class.getSimpleName(); 32 | 33 | public MockOverlayTileService() { 34 | super(); 35 | } 36 | 37 | @Override 38 | public void onTileAdded() { 39 | super.onTileAdded(); 40 | } 41 | 42 | @Override 43 | public void onTileRemoved() { 44 | super.onTileRemoved(); 45 | } 46 | 47 | @Override 48 | public void onStartListening() { 49 | super.onStartListening(); 50 | updateTile(((DesignerToolsApplication) getApplicationContext()).getMockOverlayOn()); 51 | } 52 | 53 | @Override 54 | public void onStopListening() { 55 | super.onStopListening(); 56 | } 57 | 58 | @Override 59 | public void onClick() { 60 | super.onClick(); 61 | boolean isOn = ((DesignerToolsApplication) getApplicationContext()).getMockOverlayOn(); 62 | if (isOn) { 63 | LaunchUtils.cancelMockOverlayOrUnpublishTile(this); 64 | } else { 65 | LaunchUtils.lauchMockPverlayOrPublishTile(this, 0); 66 | } 67 | updateTile(!isOn); 68 | } 69 | 70 | private void updateTile(boolean isOn) { 71 | final Tile tile = getQsTile(); 72 | tile.setIcon(Icon.createWithResource(this, isOn 73 | ? R.drawable.ic_qs_overlay_on 74 | : R.drawable.ic_qs_overlay_off)); 75 | tile.updateTile(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/ui/ColorPickerCardFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.ui; 17 | 18 | import android.content.Intent; 19 | import android.content.res.ColorStateList; 20 | import android.os.Bundle; 21 | import android.provider.Settings; 22 | import android.view.LayoutInflater; 23 | import android.view.View; 24 | import android.view.ViewGroup; 25 | import android.widget.CompoundButton; 26 | 27 | import org.cyanogenmod.designertools.R; 28 | import org.cyanogenmod.designertools.qs.OnOffTileState; 29 | import org.cyanogenmod.designertools.utils.LaunchUtils; 30 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 31 | 32 | public class ColorPickerCardFragment extends DesignerToolCardFragment { 33 | private static final int REQUEST_OVERLAY_PERMISSION = 0x42; 34 | 35 | @Override 36 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 37 | Bundle savedInstanceState) { 38 | View base = super.onCreateView(inflater, container, savedInstanceState); 39 | setTitleText(R.string.header_title_color_picker); 40 | setTitleSummary(R.string.header_summary_color_picker); 41 | setIconResource(R.drawable.ic_qs_colorpicker_on); 42 | base.setBackgroundTintList(ColorStateList.valueOf( 43 | getResources().getColor(R.color.colorColorPickerCardTint))); 44 | 45 | return base; 46 | } 47 | 48 | @Override 49 | public void onResume() { 50 | super.onResume(); 51 | mEnabledSwitch.setChecked(getApplicationContext().getColorPickerOn()); 52 | } 53 | 54 | @Override 55 | protected int getCardStyleResourceId() { 56 | return R.style.AppTheme_ColorPickerCard; 57 | } 58 | 59 | @Override 60 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 61 | if (isChecked == getApplicationContext().getColorPickerOn()) return; 62 | if (isChecked) { 63 | enableFeature(true); 64 | } else { 65 | enableFeature(false); 66 | } 67 | } 68 | 69 | @Override 70 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 71 | if (requestCode == REQUEST_OVERLAY_PERMISSION) { 72 | if (Settings.canDrawOverlays(getContext())) { 73 | mEnabledSwitch.setChecked(true); 74 | } else { 75 | mEnabledSwitch.setChecked(false); 76 | } 77 | } 78 | super.onActivityResult(requestCode, resultCode, data); 79 | } 80 | 81 | private void enableFeature(boolean enable) { 82 | if (enable) { 83 | LaunchUtils.lauchColorPickerOrPublishTile(getContext(), 84 | PreferenceUtils.getColorPickerActive(getContext(), false) 85 | ? OnOffTileState.STATE_ON 86 | : OnOffTileState.STATE_OFF); 87 | } else { 88 | LaunchUtils.cancelColorPickerOrUnpublishTile(getContext()); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/ui/CreditsActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.ui; 17 | 18 | import android.animation.Animator; 19 | import android.animation.AnimatorSet; 20 | import android.animation.ObjectAnimator; 21 | import android.app.Activity; 22 | import android.os.Bundle; 23 | import android.support.v4.view.animation.FastOutSlowInInterpolator; 24 | import android.view.View; 25 | import android.view.ViewAnimationUtils; 26 | import android.view.ViewTreeObserver; 27 | import android.view.animation.AccelerateDecelerateInterpolator; 28 | import android.view.animation.Interpolator; 29 | 30 | import org.cyanogenmod.designertools.R; 31 | 32 | public class CreditsActivity extends Activity { 33 | 34 | @Override 35 | protected void onCreate(Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | overridePendingTransition(0, 0); 38 | setContentView(R.layout.activity_credits); 39 | if (savedInstanceState == null) { 40 | } 41 | } 42 | 43 | private void circularRevealActivity(View v) { 44 | 45 | int cx = v.getWidth() / 2; 46 | int cy = v.getHeight() / 2; 47 | 48 | float finalRadius = Math.max(v.getWidth(), v.getHeight()); 49 | 50 | // create the animator for this view (the start radius is zero) 51 | Animator circularReveal = ViewAnimationUtils 52 | .createCircularReveal(v, cx, cy, 0, finalRadius); 53 | circularReveal.setDuration(getResources().getInteger( 54 | R.integer.credits_circular_reveal_duration)); 55 | 56 | // make the view visible and start the animation 57 | v.setVisibility(View.VISIBLE); 58 | circularReveal.setInterpolator(new AccelerateDecelerateInterpolator()); 59 | circularReveal.addListener(new Animator.AnimatorListener() { 60 | @Override 61 | public void onAnimationStart(Animator animator) { 62 | } 63 | 64 | @Override 65 | public void onAnimationEnd(Animator animator) { 66 | animateContent(); 67 | } 68 | 69 | @Override 70 | public void onAnimationCancel(Animator animator) { 71 | } 72 | 73 | @Override 74 | public void onAnimationRepeat(Animator animator) { 75 | } 76 | }); 77 | circularReveal.start(); 78 | } 79 | 80 | @Override 81 | protected void onResume() { 82 | super.onResume(); 83 | final View rootLayout = findViewById(R.id.activity_credits); 84 | rootLayout.setVisibility(View.INVISIBLE); 85 | 86 | ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver(); 87 | if (viewTreeObserver.isAlive()) { 88 | viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 89 | @Override 90 | public void onGlobalLayout() { 91 | circularRevealActivity(rootLayout); 92 | rootLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 93 | } 94 | }); 95 | } 96 | } 97 | 98 | private void animateContent() { 99 | View avatar1 = findViewById(R.id.avatar1); 100 | avatar1.setScaleX(0); 101 | avatar1.setScaleY(0); 102 | avatar1.setVisibility(View.VISIBLE); 103 | View text1 = findViewById(R.id.text1); 104 | text1.setAlpha(0); 105 | text1.setVisibility(View.VISIBLE); 106 | View avatar2 = findViewById(R.id.avatar2); 107 | avatar2.setScaleX(0); 108 | avatar2.setScaleY(0); 109 | avatar2.setVisibility(View.VISIBLE); 110 | View text2 = findViewById(R.id.text2); 111 | text2.setAlpha(0); 112 | text2.setVisibility(View.VISIBLE); 113 | View avatar3 = findViewById(R.id.avatar3); 114 | avatar3.setScaleX(0); 115 | avatar3.setScaleY(0); 116 | avatar3.setVisibility(View.VISIBLE); 117 | View text3 = findViewById(R.id.text3); 118 | text3.setAlpha(0); 119 | text3.setVisibility(View.VISIBLE); 120 | View avatar4 = findViewById(R.id.avatar4); 121 | avatar4.setScaleX(0); 122 | avatar4.setScaleY(0); 123 | avatar4.setVisibility(View.VISIBLE); 124 | View text4 = findViewById(R.id.text4); 125 | text4.setAlpha(0); 126 | text4.setVisibility(View.VISIBLE); 127 | 128 | Interpolator interpolator = new FastOutSlowInInterpolator(); 129 | long duration = 375L; 130 | long delay = duration / 3; 131 | 132 | AnimatorSet anim1 = new AnimatorSet(); 133 | anim1.play(ObjectAnimator.ofFloat(avatar1, "scaleX", 1f)) 134 | .with(ObjectAnimator.ofFloat(avatar1, "scaleY", 1f)) 135 | .with(ObjectAnimator.ofFloat(text1, "alpha", 1f)); 136 | anim1.setDuration(duration); 137 | anim1.setInterpolator(interpolator); 138 | AnimatorSet anim2 = new AnimatorSet(); 139 | anim2.play(ObjectAnimator.ofFloat(avatar2, "scaleX", 1f)) 140 | .with(ObjectAnimator.ofFloat(avatar2, "scaleY", 1f)) 141 | .with(ObjectAnimator.ofFloat(text2, "alpha", 1f)); 142 | anim2.setDuration(duration); 143 | anim2.setInterpolator(interpolator); 144 | anim2.setStartDelay(delay); 145 | AnimatorSet anim3 = new AnimatorSet(); 146 | anim3.play(ObjectAnimator.ofFloat(avatar3, "scaleX", 1f)) 147 | .with(ObjectAnimator.ofFloat(avatar3, "scaleY", 1f)) 148 | .with(ObjectAnimator.ofFloat(text3, "alpha", 1f)); 149 | anim3.setDuration(duration); 150 | anim3.setInterpolator(interpolator); 151 | anim3.setStartDelay(delay * 2); 152 | AnimatorSet anim4 = new AnimatorSet(); 153 | anim4.play(ObjectAnimator.ofFloat(avatar4, "scaleX", 1f)) 154 | .with(ObjectAnimator.ofFloat(avatar4, "scaleY", 1f)) 155 | .with(ObjectAnimator.ofFloat(text4, "alpha", 1f)); 156 | anim4.setDuration(duration); 157 | anim4.setInterpolator(interpolator); 158 | anim4.setStartDelay(delay * 3); 159 | AnimatorSet set = new AnimatorSet(); 160 | set.play(anim1).with(anim2); 161 | set.play(anim2).with(anim3); 162 | set.play(anim3).with(anim4); 163 | set.start(); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/ui/DesignerToolCardFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.ui; 17 | 18 | import android.app.Fragment; 19 | import android.content.ContextWrapper; 20 | import android.content.res.ColorStateList; 21 | import android.os.Bundle; 22 | import android.view.LayoutInflater; 23 | import android.view.View; 24 | import android.view.ViewGroup; 25 | import android.widget.CompoundButton; 26 | import android.widget.FrameLayout; 27 | import android.widget.ImageView; 28 | import android.widget.Switch; 29 | import android.widget.TextView; 30 | 31 | import org.cyanogenmod.designertools.DesignerToolsApplication; 32 | import org.cyanogenmod.designertools.R; 33 | 34 | public class DesignerToolCardFragment extends Fragment 35 | implements CompoundButton.OnCheckedChangeListener { 36 | 37 | protected View mParentLayout; 38 | protected ImageView mIcon; 39 | protected TextView mHeaderTitle; 40 | protected TextView mHeaderSummary; 41 | protected Switch mEnabledSwitch; 42 | protected FrameLayout mCardContent; 43 | 44 | @Override 45 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 46 | Bundle savedInstanceState) { 47 | ContextWrapper ctx = new ContextWrapper(inflater.getContext()); 48 | ctx.setTheme(getCardStyleResourceId()); 49 | inflater.cloneInContext(ctx); 50 | View v = inflater.inflate(R.layout.card_layout, container, true); 51 | mParentLayout = v.findViewById(R.id.parent_layout); 52 | mIcon = (ImageView) v.findViewById(R.id.header_icon); 53 | mHeaderTitle = (TextView) v.findViewById(R.id.header_title); 54 | mHeaderSummary = (TextView) v.findViewById(R.id.header_summary); 55 | mEnabledSwitch = (Switch) v.findViewById(R.id.enable_switch); 56 | mCardContent = (FrameLayout) v.findViewById(R.id.card_content); 57 | 58 | mEnabledSwitch.setOnCheckedChangeListener(this); 59 | 60 | return v; 61 | } 62 | 63 | protected void setIconResource(int resId) { 64 | if (mIcon != null) mIcon.setImageResource(resId); 65 | } 66 | 67 | protected void setTitleText(CharSequence text) { 68 | if (mHeaderTitle != null) mHeaderTitle.setText(text); 69 | } 70 | 71 | protected void setTitleText(int resId) { 72 | if (mHeaderTitle != null) mHeaderTitle.setText(resId); 73 | } 74 | 75 | protected void setTitleSummary(CharSequence text) { 76 | if (mHeaderSummary != null) mHeaderSummary.setText(text); 77 | } 78 | 79 | protected void setTitleSummary(int resId) { 80 | if (mHeaderSummary != null) mHeaderSummary.setText(resId); 81 | } 82 | 83 | protected void setBackgroundTintList(ColorStateList tint) { 84 | if (mParentLayout != null) mParentLayout.setBackgroundTintList(tint); 85 | } 86 | 87 | protected int getCardStyleResourceId() { 88 | return R.style.AppTheme; 89 | } 90 | 91 | protected DesignerToolsApplication getApplicationContext() { 92 | return (DesignerToolsApplication) getActivity().getApplicationContext(); 93 | } 94 | 95 | @Override 96 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/ui/DesignerToolsActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.ui; 17 | 18 | import android.app.Activity; 19 | import android.content.Intent; 20 | import android.os.Bundle; 21 | import android.view.View; 22 | import android.widget.TextView; 23 | 24 | import org.cyanogenmod.designertools.R; 25 | import org.cyanogenmod.designertools.utils.LaunchUtils; 26 | 27 | public class DesignerToolsActivity extends Activity { 28 | 29 | @Override 30 | protected void onCreate(Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | setContentView(R.layout.activity_designer_tools); 33 | if (!LaunchUtils.isCyanogenMod(this)) { 34 | TextView tv = (TextView) findViewById(R.id.qs_tiles_section); 35 | tv.setText(R.string.overlays_section_text); 36 | } 37 | View headerGlyph = findViewById(R.id.header_glyph); 38 | if (headerGlyph != null) { 39 | headerGlyph.setOnClickListener(mGlyphClickListener); 40 | } 41 | } 42 | 43 | private View.OnClickListener mGlyphClickListener = new View.OnClickListener() { 44 | @Override 45 | public void onClick(View view) { 46 | startActivity(new Intent(DesignerToolsActivity.this, CreditsActivity.class)); 47 | } 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/ui/DualColorPickerDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.ui; 17 | 18 | import android.app.AlertDialog; 19 | import android.app.Dialog; 20 | import android.app.DialogFragment; 21 | import android.content.DialogInterface; 22 | import android.os.Bundle; 23 | import android.support.v4.view.PagerAdapter; 24 | import android.support.v4.view.ViewPager; 25 | import android.view.ContextThemeWrapper; 26 | import android.view.MotionEvent; 27 | import android.view.View; 28 | import android.view.ViewGroup; 29 | 30 | import org.cyanogenmod.designertools.R; 31 | import org.cyanogenmod.designertools.utils.ColorUtils; 32 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 33 | import com.larswerkman.lobsterpicker.LobsterPicker; 34 | import com.larswerkman.lobsterpicker.sliders.LobsterOpacitySlider; 35 | import com.viewpagerindicator.CirclePageIndicator; 36 | 37 | public class DualColorPickerDialog extends DialogFragment { 38 | private ColorPickerViewHolder[] mColorPickerViews; 39 | private ViewPager mViewPager; 40 | private PagerAdapter mAdapter; 41 | private CirclePageIndicator mPageIndicator; 42 | 43 | @Override 44 | public Dialog onCreateDialog(Bundle savedInstanceState) { 45 | View v = View.inflate(getContext(), R.layout.dialog_color_picker, null); 46 | 47 | initColorPickerViews(); 48 | 49 | mViewPager = (ViewPager) v.findViewById(R.id.view_pager); 50 | mAdapter = new ColorPickerPagerAdapter(); 51 | mViewPager.setAdapter(mAdapter); 52 | 53 | mPageIndicator = (CirclePageIndicator) v.findViewById(R.id.view_pager_indicator); 54 | mPageIndicator.setViewPager(mViewPager); 55 | mPageIndicator.setFillColor(getContext().getColor(R.color.colorGridOverlayCardTint)); 56 | 57 | AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(getContext(), 58 | R.style.AppDialog)); 59 | builder.setView(v) 60 | .setTitle(R.string.color_picker_title) 61 | .setPositiveButton(R.string.color_picker_accept, mClickListener) 62 | .setNegativeButton(R.string.color_picker_cancel, mClickListener); 63 | 64 | return builder.create(); 65 | } 66 | 67 | private void initColorPickerViews() { 68 | mColorPickerViews = new ColorPickerViewHolder[2]; 69 | 70 | mColorPickerViews[0] = new ColorPickerViewHolder(); 71 | mColorPickerViews[0].container = View.inflate(getContext(), R.layout.lobsterpicker, null); 72 | mColorPickerViews[0].picker = (LobsterPicker) mColorPickerViews[0].container 73 | .findViewById(R.id.lobsterpicker); 74 | mColorPickerViews[0].slider = (LobsterOpacitySlider) mColorPickerViews[0].container 75 | .findViewById(R.id.opacityslider); 76 | mColorPickerViews[0].picker.addDecorator(mColorPickerViews[0].slider); 77 | int color = ColorUtils.getGridLineColor(getContext()); 78 | mColorPickerViews[0].picker.setColor(color); 79 | mColorPickerViews[0].picker.setHistory(color); 80 | mColorPickerViews[0].slider.setOnTouchListener(mSliderTouchListener); 81 | 82 | mColorPickerViews[1] = new ColorPickerViewHolder(); 83 | mColorPickerViews[1].container = View.inflate(getContext(), R.layout.lobsterpicker, null); 84 | mColorPickerViews[1].picker = (LobsterPicker) mColorPickerViews[1].container 85 | .findViewById(R.id.lobsterpicker); 86 | mColorPickerViews[1].slider = (LobsterOpacitySlider) mColorPickerViews[1].container 87 | .findViewById(R.id.opacityslider); 88 | mColorPickerViews[1].picker.addDecorator(mColorPickerViews[1].slider); 89 | color = ColorUtils.getKeylineColor(getContext()); 90 | mColorPickerViews[1].picker.setColor(color); 91 | mColorPickerViews[1].picker.setHistory(color); 92 | mColorPickerViews[1].slider.setOnTouchListener(mSliderTouchListener); 93 | } 94 | 95 | private View.OnTouchListener mSliderTouchListener = new View.OnTouchListener() { 96 | @Override 97 | public boolean onTouch(View v, MotionEvent event) { 98 | switch (event.getAction()) { 99 | case MotionEvent.ACTION_DOWN: 100 | v.getParent().requestDisallowInterceptTouchEvent(true); 101 | break; 102 | case MotionEvent.ACTION_UP: 103 | v.getParent().requestDisallowInterceptTouchEvent(false); 104 | break; 105 | } 106 | v.onTouchEvent(event); 107 | return true; 108 | } 109 | }; 110 | 111 | private DialogInterface.OnClickListener mClickListener = new DialogInterface.OnClickListener() { 112 | @Override 113 | public void onClick(DialogInterface dialog, int which) { 114 | switch (which) { 115 | case AlertDialog.BUTTON_POSITIVE: 116 | PreferenceUtils.setGridLineColor(getContext(), 117 | mColorPickerViews[0].picker.getColor()); 118 | PreferenceUtils.setKeylineColor(getContext(), 119 | mColorPickerViews[1].picker.getColor()); 120 | break; 121 | case AlertDialog.BUTTON_NEGATIVE: 122 | break; 123 | } 124 | dialog.dismiss(); 125 | } 126 | }; 127 | 128 | private class ColorPickerPagerAdapter extends PagerAdapter { 129 | 130 | @Override 131 | public int getCount() { 132 | return mColorPickerViews.length; 133 | } 134 | 135 | @Override 136 | public boolean isViewFromObject(View view, Object object) { 137 | return view == object; 138 | } 139 | 140 | @Override 141 | public Object instantiateItem(ViewGroup container, int position) { 142 | container.addView(mColorPickerViews[position].container); 143 | 144 | return mColorPickerViews[position].container; 145 | } 146 | 147 | @Override 148 | public CharSequence getPageTitle(int position) { 149 | if (position == 0) { 150 | return getContext().getString(R.string.color_picker_grid_page_title); 151 | } else { 152 | return getContext().getString(R.string.color_picker_keyline_page_title); 153 | } 154 | } 155 | } 156 | 157 | private class ColorPickerViewHolder { 158 | View container; 159 | LobsterPicker picker; 160 | LobsterOpacitySlider slider; 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/ui/ScreenRecordRequestActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.ui; 17 | 18 | import android.app.Activity; 19 | import android.content.Intent; 20 | import android.media.projection.MediaProjectionManager; 21 | import android.os.Bundle; 22 | 23 | import org.cyanogenmod.designertools.DesignerToolsApplication; 24 | import org.cyanogenmod.designertools.overlays.ColorPickerOverlay; 25 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 26 | 27 | public class ScreenRecordRequestActivity extends Activity { 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | MediaProjectionManager mpm = getSystemService(MediaProjectionManager.class); 32 | startActivityForResult(mpm.createScreenCaptureIntent(), 42); 33 | } 34 | 35 | @Override 36 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 37 | if (resultCode == RESULT_OK) { 38 | ((DesignerToolsApplication) getApplication()).setScreenRecordPermissionData( 39 | resultCode, data); 40 | Intent newIntent = new Intent(this, ColorPickerOverlay.class); 41 | this.startService(newIntent); 42 | PreferenceUtils.setColorPickerActive(this, true); 43 | } 44 | finish(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/ui/ScreenshotCardFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.ui; 17 | 18 | import android.Manifest; 19 | import android.content.Intent; 20 | import android.content.pm.PackageManager; 21 | import android.content.res.ColorStateList; 22 | import android.os.Bundle; 23 | import android.view.LayoutInflater; 24 | import android.view.View; 25 | import android.view.ViewGroup; 26 | import android.widget.CompoundButton; 27 | 28 | import org.cyanogenmod.designertools.R; 29 | import org.cyanogenmod.designertools.service.ScreenshotListenerService; 30 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 31 | 32 | public class ScreenshotCardFragment extends DesignerToolCardFragment { 33 | 34 | @Override 35 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 36 | Bundle savedInstanceState) { 37 | View base = super.onCreateView(inflater, container, savedInstanceState); 38 | setTitleText(R.string.header_title_screenshot); 39 | setTitleSummary(R.string.header_summary_screenshot); 40 | setIconResource(R.drawable.ic_qs_screenshotinfo_on); 41 | base.setBackgroundTintList(ColorStateList.valueOf( 42 | getResources().getColor(R.color.colorScreenshotCardTint))); 43 | 44 | mEnabledSwitch.setChecked(PreferenceUtils.getScreenshotInfoEnabled(getContext(), false)); 45 | 46 | return base; 47 | } 48 | 49 | @Override 50 | public void onRequestPermissionsResult(int requestCode, String[] permissions, 51 | int[] grantResults) { 52 | if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 53 | PreferenceUtils.setScreenshotInfoEnabled(getContext(), true); 54 | Intent newIntent = new Intent(getContext(), ScreenshotListenerService.class); 55 | getContext().startService(newIntent); 56 | mEnabledSwitch.setChecked(true); 57 | } else { 58 | mEnabledSwitch.setChecked(false); 59 | } 60 | } 61 | 62 | @Override 63 | protected int getCardStyleResourceId() { 64 | return R.style.AppTheme_ScreenshotCard; 65 | } 66 | 67 | @Override 68 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 69 | if (!isVisible()) return; 70 | 71 | if (isChecked) { 72 | if (getActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) 73 | == PackageManager.PERMISSION_GRANTED) { 74 | PreferenceUtils.setScreenshotInfoEnabled(getContext(), isChecked); 75 | Intent newIntent = new Intent(getContext(), ScreenshotListenerService.class); 76 | getContext().startService(newIntent); 77 | } else { 78 | mEnabledSwitch.setChecked(false); 79 | requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, 42); 80 | } 81 | } else { 82 | PreferenceUtils.setScreenshotInfoEnabled(getContext(), false); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/ui/StartOverlayActivity.java: -------------------------------------------------------------------------------- 1 | package org.cyanogenmod.designertools.ui; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import android.provider.Settings; 8 | 9 | import org.cyanogenmod.designertools.overlays.GridOverlay; 10 | import org.cyanogenmod.designertools.overlays.MockOverlay; 11 | import org.cyanogenmod.designertools.utils.LaunchUtils; 12 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 13 | 14 | /** 15 | * Created by clark on 12/19/16. 16 | */ 17 | 18 | public class StartOverlayActivity extends Activity { 19 | private static final int REQUEST_OVERLAY_PERMSSISION = 42; 20 | 21 | public static final String EXTRA_OVERLAY_TYPE = "overlayType"; 22 | public static final int GRID_OVERLAY = 0; 23 | public static final int MOCK_OVERLAY = 1; 24 | public static final int COLOR_PICKER_OVERLAY = 2; 25 | 26 | private int mOverlayType = -1; 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | Intent intent = getIntent(); 32 | if (intent.hasExtra(EXTRA_OVERLAY_TYPE)) { 33 | mOverlayType = intent.getIntExtra(EXTRA_OVERLAY_TYPE, -1); 34 | if (Settings.canDrawOverlays(this)) { 35 | startOverlayService(mOverlayType); 36 | finish(); 37 | } else { 38 | Intent closeDialogsIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 39 | sendBroadcast(closeDialogsIntent); 40 | Intent newIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, 41 | Uri.parse("package:" + getPackageName())); 42 | startActivityForResult(newIntent, REQUEST_OVERLAY_PERMSSISION); 43 | } 44 | } else { 45 | finish(); 46 | } 47 | } 48 | 49 | @Override 50 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 51 | if (requestCode == REQUEST_OVERLAY_PERMSSISION) { 52 | if (Settings.canDrawOverlays(this)) { 53 | startOverlayService(mOverlayType); 54 | } 55 | finish(); 56 | } 57 | super.onActivityResult(requestCode, resultCode, data); 58 | } 59 | 60 | private void startOverlayService(int overlayType) { 61 | switch (overlayType) { 62 | case GRID_OVERLAY: 63 | Intent newIntent = new Intent(this, GridOverlay.class); 64 | this.startService(newIntent); 65 | PreferenceUtils.setGridOverlayActive(this, true); 66 | PreferenceUtils.setGridQsTileEnabled(this, true); 67 | break; 68 | case MOCK_OVERLAY: 69 | newIntent = new Intent(this, MockOverlay.class); 70 | this.startService(newIntent); 71 | PreferenceUtils.setMockOverlayActive(this, true); 72 | PreferenceUtils.setMockQsTileEnabled(this, true); 73 | break; 74 | case COLOR_PICKER_OVERLAY: 75 | LaunchUtils.startColorPickerOrRequestPermission(this); 76 | break; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/utils/ColorUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.utils; 17 | 18 | import android.content.Context; 19 | 20 | import org.cyanogenmod.designertools.R; 21 | 22 | public class ColorUtils { 23 | public static int getGridLineColor(Context context) { 24 | return PreferenceUtils.getGridLineColor(context, 25 | context.getColor(R.color.dualColorPickerDefaultPrimaryColor)); 26 | } 27 | 28 | public static int getKeylineColor(Context context) { 29 | return PreferenceUtils.getKeylineColor(context, 30 | context.getColor(R.color.dualColorPickerDefaultSecondaryColor)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/utils/ImageUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.utils; 17 | 18 | import android.content.ContentResolver; 19 | import android.content.Context; 20 | import android.graphics.Bitmap; 21 | import android.graphics.BitmapFactory; 22 | import android.net.Uri; 23 | import android.util.Log; 24 | 25 | import java.io.FileNotFoundException; 26 | import java.io.FileOutputStream; 27 | import java.io.IOException; 28 | import java.io.InputStream; 29 | 30 | public class ImageUtils { 31 | private static final String TAG = ImageUtils.class.getSimpleName(); 32 | 33 | public static Bitmap getBitmapFromUri(Context context, Uri uri) { 34 | String scheme = uri.getScheme(); 35 | Bitmap image = null; 36 | if (ContentResolver.SCHEME_CONTENT.equals(scheme) 37 | || ContentResolver.SCHEME_FILE.equals(scheme)) { 38 | InputStream stream = null; 39 | try { 40 | stream = context.getContentResolver().openInputStream(uri); 41 | image = BitmapFactory.decodeStream(stream); 42 | } catch (Exception e) { 43 | Log.w(TAG, "Unable to open content: " + uri, e); 44 | } finally { 45 | if (stream != null) { 46 | try { 47 | stream.close(); 48 | } catch (IOException e) { 49 | Log.w(TAG, "Unable to close content: " + uri, e); 50 | } 51 | } 52 | } 53 | } 54 | 55 | return image; 56 | } 57 | 58 | public static boolean saveBitmap(Bitmap bmp, String path) throws FileNotFoundException { 59 | if (bmp == null || path == null) return false; 60 | 61 | FileOutputStream outputStream = new FileOutputStream(path); 62 | return bmp.compress(Bitmap.CompressFormat.JPEG, 80, outputStream); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/utils/LaunchUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.utils; 17 | 18 | import android.app.Activity; 19 | import android.content.Context; 20 | import android.content.Intent; 21 | import android.os.Build; 22 | 23 | import org.cyanogenmod.designertools.DesignerToolsApplication; 24 | import org.cyanogenmod.designertools.overlays.ColorPickerOverlay; 25 | import org.cyanogenmod.designertools.overlays.GridOverlay; 26 | import org.cyanogenmod.designertools.overlays.MockOverlay; 27 | import org.cyanogenmod.designertools.qs.ColorPickerQuickSettingsTile; 28 | import org.cyanogenmod.designertools.qs.GridQuickSettingsTile; 29 | import org.cyanogenmod.designertools.qs.MockQuickSettingsTile; 30 | import org.cyanogenmod.designertools.ui.ScreenRecordRequestActivity; 31 | import org.cyanogenmod.designertools.ui.StartOverlayActivity; 32 | 33 | public class LaunchUtils { 34 | public static boolean isCyanogenMod(Context context) { 35 | return context.getPackageManager().hasSystemFeature("org.cyanogenmod.theme"); 36 | } 37 | 38 | public static void lauchGridOverlayOrPublishTile(Context context, int state) { 39 | if (isCyanogenMod(context) && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { 40 | GridQuickSettingsTile.publishGridTile(context, state); 41 | } else { 42 | startOverlayActivity(context, StartOverlayActivity.GRID_OVERLAY); 43 | } 44 | } 45 | 46 | public static void cancelGridOverlayOrUnpublishTile(Context context) { 47 | if (isCyanogenMod(context) && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { 48 | GridQuickSettingsTile.unpublishGridTile(context); 49 | } else { 50 | Intent newIntent = new Intent(context, GridOverlay.class); 51 | context.stopService(newIntent); 52 | PreferenceUtils.setGridOverlayActive(context, false); 53 | PreferenceUtils.setGridQsTileEnabled(context, false); 54 | } 55 | } 56 | 57 | public static void lauchMockPverlayOrPublishTile(Context context, int state) { 58 | if (isCyanogenMod(context) && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { 59 | MockQuickSettingsTile.publishMockTile(context, state); 60 | } else { 61 | startOverlayActivity(context, StartOverlayActivity.MOCK_OVERLAY); 62 | } 63 | } 64 | 65 | public static void cancelMockOverlayOrUnpublishTile(Context context) { 66 | if (isCyanogenMod(context) && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { 67 | MockQuickSettingsTile.unpublishMockTile(context); 68 | } else { 69 | Intent newIntent = new Intent(context, MockOverlay.class); 70 | context.stopService(newIntent); 71 | PreferenceUtils.setMockOverlayActive(context, false); 72 | PreferenceUtils.setMockQsTileEnabled(context, false); 73 | } 74 | } 75 | 76 | public static void lauchColorPickerOrPublishTile(Context context, int state) { 77 | if (isCyanogenMod(context) && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { 78 | ColorPickerQuickSettingsTile.publishColorPickerTile(context, state); 79 | } else { 80 | startOverlayActivity(context, StartOverlayActivity.COLOR_PICKER_OVERLAY); 81 | } 82 | } 83 | 84 | public static void cancelColorPickerOrUnpublishTile(Context context) { 85 | if (isCyanogenMod(context) && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { 86 | ColorPickerQuickSettingsTile.unpublishColorPickerTile(context); 87 | } else { 88 | Intent newIntent = new Intent(context, ColorPickerOverlay.class); 89 | context.stopService(newIntent); 90 | PreferenceUtils.setColorPickerActive(context, false); 91 | PreferenceUtils.setColorPickerQsTileEnabled(context, false); 92 | } 93 | } 94 | 95 | public static void startColorPickerOrRequestPermission(Context context) { 96 | DesignerToolsApplication app = 97 | (DesignerToolsApplication) context.getApplicationContext(); 98 | if (app.getScreenRecordResultCode() == Activity.RESULT_OK && app.getScreenRecordResultData() != null) { 99 | Intent newIntent = new Intent(context, ColorPickerOverlay.class); 100 | context.startService(newIntent); 101 | PreferenceUtils.setColorPickerActive(context, true); 102 | PreferenceUtils.setColorPickerQsTileEnabled(context, true); 103 | } else { 104 | Intent intent = new Intent(context, ScreenRecordRequestActivity.class); 105 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 106 | context.startActivity(intent); 107 | } 108 | } 109 | 110 | private static void startOverlayActivity(Context context, int overlayType) { 111 | Intent intent = new Intent(context, StartOverlayActivity.class); 112 | intent.putExtra(StartOverlayActivity.EXTRA_OVERLAY_TYPE, overlayType); 113 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 114 | context.startActivity(intent); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/utils/LayoutRenderUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.utils; 17 | 18 | import android.graphics.Bitmap; 19 | import android.graphics.Canvas; 20 | import android.view.View; 21 | import android.widget.FrameLayout; 22 | 23 | public class LayoutRenderUtils { 24 | 25 | public static Bitmap renderViewToBitmap(View view) { 26 | // Provide it with a layout params. It should necessarily be wrapping the 27 | // content as we not really going to have a parent for it. 28 | view.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, 29 | FrameLayout.LayoutParams.WRAP_CONTENT)); 30 | 31 | // Pre-measure the view so that height and width don't remain null. 32 | view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), 33 | View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 34 | 35 | // Assign a size and position to the view and all of its descendants 36 | view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); 37 | 38 | // Create the bitmap 39 | Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), 40 | view.getMeasuredHeight(), 41 | Bitmap.Config.ARGB_8888); 42 | // Create a canvas with the specified bitmap to draw into 43 | Canvas c = new Canvas(bitmap); 44 | 45 | // Render this view to the given Canvas 46 | view.draw(c); 47 | return bitmap; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/utils/MockupUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The CyanogenMod Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.cyanogenmod.designertools.utils; 17 | 18 | import android.content.Context; 19 | import android.graphics.Bitmap; 20 | import android.graphics.BitmapFactory; 21 | 22 | import java.io.File; 23 | import java.io.IOException; 24 | 25 | public class MockupUtils { 26 | private static final String MOCKUP_DIRECTORY = "mockups"; 27 | 28 | public static final String PORTRAIT_MOCKUP_FILENAME = "mockup_portrait"; 29 | public static final String LANDSCAPE_MOCKUP_FILENAME = "mockup_landscape"; 30 | 31 | public static void savePortraitMockup(Context context, Bitmap bmp) throws IOException { 32 | saveMockup(context, bmp, PORTRAIT_MOCKUP_FILENAME); 33 | } 34 | 35 | public static Bitmap getPortraitMockup(Context context) { 36 | return loadMockup(context, PORTRAIT_MOCKUP_FILENAME); 37 | } 38 | 39 | public static void saveLandscapeMockup(Context context, Bitmap bmp) throws IOException { 40 | saveMockup(context, bmp, LANDSCAPE_MOCKUP_FILENAME); 41 | } 42 | 43 | public static Bitmap getLandscapeMockup(Context context) { 44 | return loadMockup(context, LANDSCAPE_MOCKUP_FILENAME); 45 | } 46 | 47 | private static void saveMockup(Context context, Bitmap bmp, String fileName) 48 | throws IOException { 49 | String path = context.getFilesDir().getAbsolutePath() + File.separator + MOCKUP_DIRECTORY; 50 | File dir = new File(path); 51 | if (!dir.exists()) { 52 | if (!dir.mkdirs()) { 53 | throw new IOException("Unable to mkdris"); 54 | } 55 | } 56 | String filePath = path + File.separator + fileName; 57 | if (bmp != null) { 58 | ImageUtils.saveBitmap(bmp, path + File.separator + fileName); 59 | if (PORTRAIT_MOCKUP_FILENAME.equals(fileName)) { 60 | PreferenceUtils.setPortraitMocupkOverlay(context, filePath); 61 | } else if (LANDSCAPE_MOCKUP_FILENAME.equals(fileName)) { 62 | PreferenceUtils.setLandscapeMocupkOverlay(context, filePath); 63 | } 64 | } else { 65 | if (PORTRAIT_MOCKUP_FILENAME.equals(fileName)) { 66 | if (new File(filePath).delete()) { 67 | PreferenceUtils.setPortraitMocupkOverlay(context, ""); 68 | } 69 | } else if (LANDSCAPE_MOCKUP_FILENAME.equals(fileName)) { 70 | if (new File(filePath).delete()) { 71 | PreferenceUtils.setLandscapeMocupkOverlay(context, ""); 72 | } 73 | } 74 | } 75 | } 76 | 77 | private static Bitmap loadMockup(Context context, String fileName) { 78 | File file = new File(context.getFilesDir().getAbsolutePath() + File.separator + 79 | MOCKUP_DIRECTORY + File.separator + fileName); 80 | if (!file.exists()) return null; 81 | 82 | return BitmapFactory.decodeFile(file.getAbsolutePath()); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/widget/DualColorPicker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Cyanogen, Inc. 3 | */ 4 | package org.cyanogenmod.designertools.widget; 5 | 6 | import android.content.Context; 7 | import android.content.res.TypedArray; 8 | import android.graphics.Canvas; 9 | import android.graphics.Color; 10 | import android.graphics.Paint; 11 | import android.graphics.Region; 12 | import android.util.AttributeSet; 13 | import android.view.View; 14 | 15 | import org.cyanogenmod.designertools.R; 16 | import org.cyanogenmod.designertools.utils.PreferenceUtils; 17 | 18 | public class DualColorPicker extends View { 19 | private static final float STROKE_WIDTH = 5f; 20 | private static final float COLOR_DARKEN_FACTOR = 0.8f; 21 | 22 | private Paint mPrimaryFillPaint; 23 | private Paint mSecondaryFillPaint; 24 | private Paint mPrimaryStrokePaint; 25 | private Paint mSecondaryStrokePaint; 26 | 27 | public DualColorPicker(Context context) { 28 | this(context, null); 29 | } 30 | 31 | public DualColorPicker(Context context, AttributeSet attrs) { 32 | this(context, attrs, 0); 33 | } 34 | 35 | public DualColorPicker(Context context, AttributeSet attrs, int defStyleAttr) { 36 | this(context, attrs, defStyleAttr, 0); 37 | } 38 | 39 | public DualColorPicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 40 | super(context, attrs, defStyleAttr, defStyleRes); 41 | TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.DualColorPicker, 0, 0); 42 | int primaryColor = ta.getColor(R.styleable.DualColorPicker_primaryColor, 43 | PreferenceUtils.getGridLineColor(context, getResources() 44 | .getColor(R.color.dualColorPickerDefaultPrimaryColor))); 45 | int secondaryColor = ta.getColor(R.styleable.DualColorPicker_primaryColor, 46 | PreferenceUtils.getKeylineColor(context, getResources() 47 | .getColor(R.color.dualColorPickerDefaultSecondaryColor))); 48 | 49 | mPrimaryFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 50 | mPrimaryFillPaint.setStyle(Paint.Style.FILL); 51 | mPrimaryFillPaint.setColor(primaryColor); 52 | mPrimaryStrokePaint = new Paint(mPrimaryFillPaint); 53 | mPrimaryStrokePaint.setStyle(Paint.Style.STROKE); 54 | mPrimaryStrokePaint.setStrokeWidth(STROKE_WIDTH); 55 | mPrimaryStrokePaint.setColor(getDarkenedColor(primaryColor)); 56 | 57 | mSecondaryFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 58 | mSecondaryFillPaint.setStyle(Paint.Style.FILL_AND_STROKE); 59 | mSecondaryFillPaint.setColor(secondaryColor); 60 | mSecondaryStrokePaint = new Paint(mSecondaryFillPaint); 61 | mSecondaryStrokePaint.setStyle(Paint.Style.STROKE); 62 | mSecondaryStrokePaint.setStrokeWidth(STROKE_WIDTH); 63 | mSecondaryStrokePaint.setColor(getDarkenedColor(secondaryColor)); 64 | } 65 | 66 | @Override 67 | protected void onDraw(Canvas canvas) { 68 | final float width = getWidth(); 69 | final float height = getHeight(); 70 | final float widthDiv2 = width / 2f; 71 | final float heightDiv2 = height / 2f; 72 | final float radius = Math.min(widthDiv2, heightDiv2) * 0.9f; 73 | 74 | // erase everything 75 | canvas.drawColor(0); 76 | 77 | // draw the left half 78 | canvas.clipRect(0, 0, widthDiv2, height, Region.Op.REPLACE); 79 | canvas.drawCircle(widthDiv2, heightDiv2, radius, mPrimaryFillPaint); 80 | canvas.drawCircle(widthDiv2, heightDiv2, radius, mPrimaryStrokePaint); 81 | canvas.drawLine(widthDiv2 - STROKE_WIDTH / 2f, heightDiv2 - radius, 82 | widthDiv2 - STROKE_WIDTH / 2f, heightDiv2 + radius, mPrimaryStrokePaint); 83 | 84 | /// draw the right half 85 | canvas.clipRect(widthDiv2, 0, width, height, Region.Op.REPLACE); 86 | canvas.drawCircle(widthDiv2, heightDiv2, radius, mSecondaryFillPaint); 87 | canvas.drawCircle(widthDiv2, heightDiv2, radius, mSecondaryStrokePaint); 88 | canvas.drawLine(widthDiv2 + STROKE_WIDTH / 2f, heightDiv2 - radius, 89 | widthDiv2 + STROKE_WIDTH / 2f, heightDiv2 + radius, mSecondaryStrokePaint); 90 | } 91 | 92 | private int getDarkenedColor(int color) { 93 | int a = Color.alpha(color); 94 | int r = (int) (Color.red(color) * COLOR_DARKEN_FACTOR); 95 | int g = (int) (Color.green(color) * COLOR_DARKEN_FACTOR); 96 | int b = (int) (Color.blue(color) * COLOR_DARKEN_FACTOR); 97 | 98 | return Color.argb(a, r, g, b); 99 | } 100 | 101 | public void setPrimaryColor(int color) { 102 | mPrimaryFillPaint.setColor(color); 103 | mPrimaryStrokePaint.setColor(getDarkenedColor(color)); 104 | invalidate(); 105 | } 106 | 107 | public int getPrimaryColor() { 108 | return mPrimaryFillPaint.getColor(); 109 | } 110 | 111 | public void setSecondaryColor(int color) { 112 | mSecondaryFillPaint.setColor(color); 113 | mSecondaryStrokePaint.setColor(getDarkenedColor(color)); 114 | invalidate(); 115 | } 116 | 117 | public int getSecondaryColor() { 118 | return mSecondaryFillPaint.getColor(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/widget/GridPreview.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Cyanogen, Inc. 3 | */ 4 | package org.cyanogenmod.designertools.widget; 5 | 6 | import android.content.Context; 7 | import android.graphics.Canvas; 8 | import android.graphics.Paint; 9 | import android.graphics.Rect; 10 | import android.util.AttributeSet; 11 | import android.view.View; 12 | 13 | import org.cyanogenmod.designertools.R; 14 | 15 | public class GridPreview extends View { 16 | // default line width in dp 17 | private static final float DEFAULT_LINE_WIDTH = 1f; 18 | // default column size in dp 19 | private static final int DEFAULT_COLUMN_SIZE = 8; 20 | // default row size in dp 21 | private static final int DEFAULT_ROW_SIZE = 8; 22 | private static final int BACKGROUND_COLOR = 0x1f000000; 23 | 24 | private float mGridLineWidth; 25 | private float mColumnSize; 26 | private float mRowSize; 27 | private float mDensity; 28 | private int mColumnSizeDp; 29 | private int mRowSizeDp; 30 | 31 | private Paint mGridLinePaint; 32 | private Paint mGridSizeTextPaint; 33 | 34 | public GridPreview(Context context) { 35 | this(context, null); 36 | } 37 | 38 | public GridPreview(Context context, AttributeSet attrs) { 39 | this(context, attrs, 0); 40 | } 41 | 42 | public GridPreview(Context context, AttributeSet attrs, int defStyleAttr) { 43 | this(context, attrs, defStyleAttr, 0); 44 | } 45 | 46 | public GridPreview(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 47 | super(context, attrs, defStyleAttr, defStyleRes); 48 | 49 | mDensity = getResources().getDisplayMetrics().density; 50 | 51 | mGridLineWidth = DEFAULT_LINE_WIDTH * mDensity; 52 | mColumnSizeDp = DEFAULT_COLUMN_SIZE; 53 | mColumnSize = mColumnSizeDp * mDensity; 54 | mRowSizeDp = DEFAULT_ROW_SIZE; 55 | mRowSize = mRowSizeDp * mDensity; 56 | 57 | mGridLinePaint = new Paint(); 58 | mGridLinePaint.setColor(context.getColor(R.color.colorGridOverlayCardTint)); 59 | mGridLinePaint.setStrokeWidth(mGridLineWidth); 60 | 61 | mGridSizeTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 62 | mGridSizeTextPaint.setTextSize( 63 | getResources().getDimensionPixelSize(R.dimen.grid_preview_text_size)); 64 | mGridSizeTextPaint.setColor(BACKGROUND_COLOR); 65 | } 66 | 67 | @Override 68 | protected void onDraw(Canvas canvas) { 69 | float width = getWidth(); 70 | float height = getHeight(); 71 | 72 | canvas.drawColor(BACKGROUND_COLOR); 73 | for (float x = mColumnSize; x < width; x += mColumnSize) { 74 | canvas.drawLine(x, 0, x, height, mGridLinePaint); 75 | } 76 | for (float y = mRowSize; y < height; y += mRowSize) { 77 | canvas.drawLine(0, y, width, y, mGridLinePaint); 78 | } 79 | 80 | String text = String.format("%d x %d", mColumnSizeDp, mRowSizeDp); 81 | Rect bounds = new Rect(); 82 | mGridSizeTextPaint.getTextBounds(text, 0, text.length(), bounds); 83 | canvas.drawText(text, (width - bounds.width()) / 2f, (height + bounds.height()) / 2f, mGridSizeTextPaint); 84 | } 85 | 86 | public void setColumnSize(int columnSize) { 87 | mColumnSizeDp = columnSize; 88 | mColumnSize = mColumnSizeDp * mDensity; 89 | invalidate(); 90 | } 91 | 92 | public int getColumnSize() { 93 | return mColumnSizeDp; 94 | } 95 | 96 | public void setRowSize(int rowSize) { 97 | mRowSizeDp = rowSize; 98 | mRowSize = mRowSizeDp * mDensity; 99 | invalidate(); 100 | } 101 | 102 | public int getRowSize() { 103 | return mRowSizeDp; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/widget/MagnifierNodeView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Cyanogen, Inc. 3 | */ 4 | package org.cyanogenmod.designertools.widget; 5 | 6 | import android.content.Context; 7 | import android.graphics.Canvas; 8 | import android.graphics.Paint; 9 | import android.graphics.PorterDuff; 10 | import android.graphics.PorterDuffXfermode; 11 | import android.util.AttributeSet; 12 | import android.util.DisplayMetrics; 13 | import android.view.View; 14 | 15 | import org.cyanogenmod.designertools.R; 16 | 17 | public class MagnifierNodeView extends View { 18 | private Paint mReticlePaint; 19 | private Paint mOutlinePaint; 20 | private Paint mFillPaint; 21 | private Paint mClearPaint; 22 | 23 | private float mCenterX; 24 | private float mCenterY; 25 | private float mRadius; 26 | private float mReticleRadius; 27 | private float mDensity; 28 | 29 | public MagnifierNodeView(Context context) { 30 | this(context, null); 31 | } 32 | 33 | public MagnifierNodeView(Context context, AttributeSet attrs) { 34 | this(context, attrs, 0); 35 | } 36 | 37 | public MagnifierNodeView(Context context, AttributeSet attrs, int defStyleAttr) { 38 | this(context, attrs, defStyleAttr, 0); 39 | } 40 | 41 | public MagnifierNodeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 42 | super(context, attrs, defStyleAttr, defStyleRes); 43 | DisplayMetrics dm = getResources().getDisplayMetrics(); 44 | float twoDp = 2f * dm.density; 45 | mReticlePaint = new Paint(); 46 | mReticlePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 47 | mReticlePaint.setColor(0x50ffffff); 48 | mReticlePaint.setStrokeWidth(twoDp); 49 | mReticlePaint.setStyle(Paint.Style.STROKE); 50 | 51 | mOutlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 52 | mOutlinePaint.setColor(0x80ffffff); 53 | mOutlinePaint.setStrokeWidth(twoDp); 54 | mOutlinePaint.setStyle(Paint.Style.STROKE); 55 | mOutlinePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR)); 56 | 57 | mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 58 | mFillPaint.setColor(0x80000000); 59 | mFillPaint.setStrokeWidth(twoDp); 60 | mFillPaint.setStyle(Paint.Style.FILL_AND_STROKE); 61 | mFillPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN)); 62 | 63 | mClearPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 64 | mClearPaint.setColor(0); 65 | mClearPaint.setStrokeWidth(twoDp); 66 | mClearPaint.setStyle(Paint.Style.FILL); 67 | mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 68 | 69 | mReticleRadius = getResources().getInteger(R.integer.color_picker_sample_width) / 2 + twoDp; 70 | mDensity = dm.density; 71 | } 72 | 73 | @Override 74 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 75 | super.onSizeChanged(w, h, oldw, oldh); 76 | mRadius = Math.min(w, h) / 2.0f - mDensity * 2f; 77 | mCenterX = w / 2.0f; 78 | mCenterY = h / 2.0f; 79 | } 80 | 81 | @Override 82 | protected void onDraw(Canvas canvas) { 83 | canvas.drawCircle(mCenterX, mCenterY, mRadius, mFillPaint); 84 | canvas.drawCircle(mCenterX, mCenterY, mRadius, mOutlinePaint); 85 | canvas.drawCircle(mCenterX, mCenterY, mReticleRadius, mClearPaint); 86 | canvas.drawCircle(mCenterX, mCenterY, mReticleRadius, mReticlePaint); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/org/cyanogenmod/designertools/widget/VerticalSeekBar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Cyanogen, Inc. 3 | */ 4 | package org.cyanogenmod.designertools.widget; 5 | 6 | import android.content.Context; 7 | import android.graphics.Canvas; 8 | import android.util.AttributeSet; 9 | import android.view.MotionEvent; 10 | import android.widget.SeekBar; 11 | 12 | public class VerticalSeekBar extends SeekBar { 13 | 14 | public VerticalSeekBar(Context context) { 15 | super(context); 16 | } 17 | 18 | public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) { 19 | super(context, attrs, defStyle); 20 | } 21 | 22 | public VerticalSeekBar(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 27 | super.onSizeChanged(h, w, oldh, oldw); 28 | } 29 | 30 | @Override 31 | protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 32 | super.onMeasure(heightMeasureSpec, widthMeasureSpec); 33 | setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); 34 | } 35 | 36 | protected void onDraw(Canvas c) { 37 | c.rotate(-90); 38 | c.translate(-getHeight(), 0); 39 | 40 | super.onDraw(c); 41 | } 42 | 43 | @Override 44 | public boolean onTouchEvent(MotionEvent event) { 45 | if (!isEnabled()) { 46 | return false; 47 | } 48 | 49 | switch (event.getAction()) { 50 | case MotionEvent.ACTION_DOWN: 51 | case MotionEvent.ACTION_MOVE: 52 | case MotionEvent.ACTION_UP: 53 | setProgress(getMax() - (int) (getMax() * event.getY() / getHeight())); 54 | onSizeChanged(getWidth(), getHeight(), 0, 0); 55 | break; 56 | 57 | case MotionEvent.ACTION_CANCEL: 58 | break; 59 | } 60 | return true; 61 | } 62 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/color_hex_backer.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-hdpi/color_hex_backer.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/loop_ring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-hdpi/loop_ring.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/color_hex_backer.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-mdpi/color_hex_backer.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loop_ring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-mdpi/loop_ring.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/aaron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-nodpi/aaron.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/asher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-nodpi/asher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/clark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-nodpi/clark.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/img_header_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-nodpi/img_header_bg.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/kover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-nodpi/kover.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/color_hex_backer.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-xhdpi/color_hex_backer.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/loop_ring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-xhdpi/loop_ring.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/color_hex_backer.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-xxhdpi/color_hex_backer.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/loop_ring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-xxhdpi/loop_ring.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/color_hex_backer.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-xxxhdpi/color_hex_backer.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/loop_ring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_apps_DesignerTools/c835a4b3816cd53553d796f6bb39a0d3a397469c/app/src/main/res/drawable-xxxhdpi/loop_ring.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/card_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/half_circle_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 26 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_header_glyph.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 51 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_marker_horiz_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_marker_horiz_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_marker_vert.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_colorpicker_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_colorpicker_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_grid_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_grid_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_layoutbounds_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_layoutbounds_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_overlay_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_overlay_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_screenshotinfo_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_screenshotinfo_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/loop_node.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/pick_mock_overlay_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/pick_mockup_frame.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | 25 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/activity_designer_tools.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 26 | 27 | 28 | 29 | 37 | 38 | 42 | 43 | 50 | 51 | 57 | 58 | 66 | 67 | 75 | 76 | 77 | 78 | 85 | 86 | 92 | 93 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/app_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 21 | 26 | 27 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout-w600dp/activity_designer_tools.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 26 | 27 | 28 | 29 | 37 | 38 | 42 | 43 | 50 | 51 | 57 | 58 | 66 | 67 | 75 | 76 | 77 | 78 | 85 | 86 | 92 | 93 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_credits.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 25 | 26 | 27 | 28 | 35 | 36 | 40 | 46 | 55 | 60 | 64 | 65 | 66 | 67 | 72 | 78 | 87 | 92 | 96 | 97 | 98 | 99 | 104 | 110 | 119 | 124 | 128 | 129 | 130 | 131 | 136 | 142 | 151 | 156 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_designer_tools.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 26 | 27 | 28 | 29 | 36 | 37 | 45 | 46 | 52 | 53 | 60 | 61 | 68 | 69 | 77 | 78 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /app/src/main/res/layout/app_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 27 | 28 | 35 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/layout/card_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 26 | 27 | 32 | 33 | 42 | 43 | 47 | 48 | 49 | 58 | 59 | -------------------------------------------------------------------------------- /app/src/main/res/layout/card_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 30 | 31 | 32 | 33 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/color_picker_magnifier.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/credits_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 27 | 28 | 35 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_color_picker.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 26 | 27 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/grid_overlay_content.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 25 | 26 | 34 | 35 | 39 | 40 | 41 | 42 | 45 | 46 | 54 | 55 | 60 | 61 | 62 | 63 | 66 | 67 | 75 | 76 | 81 | 82 | 83 | 84 | 88 | 89 | 96 | 97 | 102 | 103 | 108 | 109 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /app/src/main/res/layout/lobsterpicker.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | 29 | 30 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/layout/mockup_overlay_content.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 29 | 30 | 34 | 35 | 39 | 40 | 48 | 49 | 55 | 56 | 57 | 58 | 62 | 63 | 73 | 74 | 82 | 83 |