├── .classpath ├── .gitignore ├── .project ├── AndroidManifest.xml ├── README.textile ├── app ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── manichord │ │ └── sketchnotes │ │ ├── BetterPopupWindow.java │ │ ├── FileUtils.java │ │ ├── PageImageAdapter.java │ │ ├── PagesList.java │ │ ├── PenModel.java │ │ ├── PenSelectionSpinnerModel.java │ │ ├── PensCustomAdapter.java │ │ ├── PreferenceHelper.java │ │ ├── SKNPrefs.java │ │ ├── SKNotesActivity.java │ │ └── SketchView.java │ └── res │ ├── anim │ ├── grow_from_bottom.xml │ ├── grow_from_top.xml │ ├── grow_from_topleft_to_bottomright.xml │ ├── shrink_from_bottom.xml │ ├── shrink_from_bottomright_to_topleft.xml │ └── shrink_from_top.xml │ ├── drawable-hdpi │ ├── black_pen_button.xml │ ├── blue_pen_button.xml │ ├── default_thumb.png │ ├── h4_pencil_button.xml │ ├── hb_pencil_button.xml │ ├── icon.png │ ├── notebook_icon.png │ ├── red_pen_button.xml │ └── yellow_hl_button.xml │ ├── drawable-ldpi │ ├── icon.png │ └── notebook_icon.png │ ├── drawable-mdpi │ ├── icon.png │ └── notebook_icon.png │ ├── drawable │ ├── ic_eraser_variant.xml │ └── ic_mode_edit_black_24dp.xml │ ├── layout-land │ └── pages.xml │ ├── layout │ ├── pages.xml │ └── sknotes_activity.xml │ ├── menu │ └── main_menu.xml │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ ├── styles.xml │ └── values.xml │ └── xml │ ├── filepaths.xml │ ├── preferences.xml │ └── settings.xml ├── build.gradle ├── docs ├── app-icon-512.png ├── app-icon.svg ├── draw-icon.svg ├── draw_icon.png ├── erase-icon.svg ├── erase_icon.png ├── eraser-pen-icons.svg ├── notebook_black.svg ├── notebook_icon.png ├── pen.svg ├── research.textile ├── screenshot1.png └── screenshot2.png ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── import-summary.txt ├── project.properties ├── res ├── anim │ ├── grow_from_bottom.xml │ ├── grow_from_top.xml │ ├── grow_from_topleft_to_bottomright.xml │ ├── shrink_from_bottom.xml │ ├── shrink_from_bottomright_to_topleft.xml │ └── shrink_from_top.xml ├── drawable-hdpi │ ├── black_pen_button.xml │ ├── blue_pen_button.xml │ ├── default_thumb.png │ ├── h4_pencil_button.xml │ ├── hb_pencil_button.xml │ ├── icon.png │ ├── notebook_icon.png │ ├── red_pen_button.xml │ └── yellow_hl_button.xml ├── drawable-ldpi │ ├── icon.png │ └── notebook_icon.png ├── drawable-mdpi │ ├── draw_button.png │ ├── eraser_button.png │ ├── icon.png │ ├── notebook_icon.png │ └── pen_button.png ├── layout-land │ └── pages.xml ├── layout │ ├── colours_popup.xml │ ├── main.xml │ └── pages.xml ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ ├── styles.xml │ └── values.xml └── xml │ ├── preferences.xml │ └── settings.xml ├── settings.gradle └── src └── com └── manichord └── sketchnotes ├── BetterPopupWindow.java ├── PageImageAdapter.java ├── PagesList.java ├── SKNPrefs.java ├── SKNotes.java └── SketchView.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | /.idea/ 7 | .DS_Store 8 | /build 9 | /captures 10 | /**/build 11 | /**/*.iml 12 | 13 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sketch Notes 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. Sketch Notes An sketching notepad Android App 2 | 3 | h2. Author: Maksim Lin 4 | 5 | h2. License 6 | 7 | Copyright 2011 Maksim Lin 8 | 9 | This file is part of Sketch Notes App. 10 | 11 | Sketch Notes is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | Sketch Notes is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with Sketch Notes. If not, see . -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | android { 3 | compileSdk 34 4 | 5 | defaultConfig { 6 | applicationId "com.manichord.sketchnotes" 7 | minSdk 23 8 | targetSdk 34 9 | 10 | versionCode 7 11 | versionName "1.0." + versionCode 12 | } 13 | 14 | dataBinding { 15 | enabled = true 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 22 | } 23 | } 24 | namespace 'com.manichord.sketchnotes' 25 | } 26 | 27 | dependencies { 28 | implementation 'com.android.support:support-v4:28.0.0' 29 | implementation 'com.android.support:appcompat-v7:28.0.0' 30 | implementation 'com.jakewharton.timber:timber:4.5.1' 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 30 | 31 | 36 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/BetterPopupWindow.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import android.content.Context; 4 | import android.graphics.Rect; 5 | import android.graphics.drawable.BitmapDrawable; 6 | import android.graphics.drawable.Drawable; 7 | import android.view.Gravity; 8 | import android.view.LayoutInflater; 9 | import android.view.MotionEvent; 10 | import android.view.View; 11 | import android.view.View.OnTouchListener; 12 | import android.view.ViewGroup.LayoutParams; 13 | import android.view.WindowManager; 14 | import android.widget.PopupWindow; 15 | 16 | /** 17 | * This class does most of the work of wrapping the {@link PopupWindow} so it's simpler to use. 18 | * (sourced from: http://code.google.com/p/simple-quickactions) 19 | * 20 | * Code license: New BSD License 21 | * 22 | * @author qberticus 23 | * 24 | */ 25 | public class BetterPopupWindow { 26 | protected final View anchor; 27 | private final PopupWindow window; 28 | private View root; 29 | private Drawable background = null; 30 | private final WindowManager windowManager; 31 | 32 | /** 33 | * Create a BetterPopupWindow 34 | * 35 | * @param anchor 36 | * the view that the BetterPopupWindow will be displaying 'from' 37 | */ 38 | public BetterPopupWindow(View anchor) { 39 | this.anchor = anchor; 40 | this.window = new PopupWindow(anchor.getContext()); 41 | 42 | // when a touch even happens outside of the window 43 | // make the window go away 44 | this.window.setTouchInterceptor(new OnTouchListener() { 45 | 46 | public boolean onTouch(View v, MotionEvent event) { 47 | if(event.getAction() == MotionEvent.ACTION_OUTSIDE) { 48 | BetterPopupWindow.this.window.dismiss(); 49 | return true; 50 | } 51 | return false; 52 | } 53 | }); 54 | 55 | this.windowManager = (WindowManager) this.anchor.getContext().getSystemService(Context.WINDOW_SERVICE); 56 | onCreate(); 57 | } 58 | 59 | /** 60 | * Anything you want to have happen when created. Probably should create a view and setup the event listeners on 61 | * child views. 62 | */ 63 | protected void onCreate() {} 64 | 65 | /** 66 | * In case there is stuff to do right before displaying. 67 | */ 68 | protected void onShow() {} 69 | 70 | private void preShow() { 71 | if(this.root == null) { 72 | throw new IllegalStateException("setContentView was not called with a view to display."); 73 | } 74 | onShow(); 75 | 76 | if(this.background == null) { 77 | this.window.setBackgroundDrawable(new BitmapDrawable()); 78 | } else { 79 | this.window.setBackgroundDrawable(this.background); 80 | } 81 | 82 | // if using PopupWindow#setBackgroundDrawable this is the only values of the width and hight that make it work 83 | // otherwise you need to set the background of the root viewgroup 84 | // and set the popupwindow background to an empty BitmapDrawable 85 | this.window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT); 86 | this.window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); 87 | this.window.setTouchable(true); 88 | this.window.setFocusable(true); 89 | this.window.setOutsideTouchable(true); 90 | 91 | this.window.setContentView(this.root); 92 | } 93 | 94 | public void setBackgroundDrawable(Drawable background) { 95 | this.background = background; 96 | } 97 | 98 | /** 99 | * Sets the content view. Probably should be called from {@link onCreate} 100 | * 101 | * @param root 102 | * the view the popup will display 103 | */ 104 | public void setContentView(View root) { 105 | this.root = root; 106 | this.window.setContentView(root); 107 | } 108 | 109 | /** 110 | * Will inflate and set the view from a resource id 111 | * 112 | * @param layoutResID 113 | */ 114 | public void setContentView(int layoutResID) { 115 | LayoutInflater inflator = 116 | (LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 117 | this.setContentView(inflator.inflate(layoutResID, null)); 118 | } 119 | 120 | /** 121 | * If you want to do anything when {@link dismiss} is called 122 | * 123 | * @param listener 124 | */ 125 | public void setOnDismissListener(PopupWindow.OnDismissListener listener) { 126 | this.window.setOnDismissListener(listener); 127 | } 128 | 129 | /** 130 | * Displays like a popdown menu from the anchor view 131 | */ 132 | public void showLikePopDownMenu() { 133 | this.showLikePopDownMenu(0, 0); 134 | } 135 | 136 | /** 137 | * Displays like a popdown menu from the anchor view. 138 | * 139 | * @param xOffset 140 | * offset in X direction 141 | * @param yOffset 142 | * offset in Y direction 143 | */ 144 | public void showLikePopDownMenu(int xOffset, int yOffset) { 145 | this.preShow(); 146 | 147 | this.window.setAnimationStyle(R.style.Animations_PopDownMenu); 148 | 149 | this.window.showAsDropDown(this.anchor, xOffset, yOffset); 150 | } 151 | 152 | /** 153 | * Displays like a QuickAction from the anchor view. 154 | */ 155 | public void showLikeQuickAction() { 156 | this.showLikeQuickAction(0, 0); 157 | } 158 | 159 | /** 160 | * Displays like a QuickAction from the anchor view. 161 | * 162 | * @param xOffset 163 | * offset in the X direction 164 | * @param yOffset 165 | * offset in the Y direction 166 | */ 167 | public void showLikeQuickAction(int xOffset, int yOffset) { 168 | this.preShow(); 169 | 170 | this.window.setAnimationStyle(R.style.Animations_GrowFromBottom); 171 | 172 | int[] location = new int[2]; 173 | this.anchor.getLocationOnScreen(location); 174 | 175 | Rect anchorRect = 176 | new Rect(location[0], location[1], location[0] + this.anchor.getWidth(), location[1] 177 | + this.anchor.getHeight()); 178 | 179 | this.root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 180 | 181 | int rootWidth = this.root.getMeasuredWidth(); 182 | int rootHeight = this.root.getMeasuredHeight(); 183 | 184 | int screenWidth = this.windowManager.getDefaultDisplay().getWidth(); 185 | int screenHeight = this.windowManager.getDefaultDisplay().getHeight(); 186 | 187 | int xPos = ((screenWidth - rootWidth) / 2) + xOffset; 188 | int yPos = anchorRect.top - rootHeight + yOffset; 189 | 190 | // display on bottom 191 | if(rootHeight > anchorRect.top) { 192 | yPos = anchorRect.bottom + yOffset; 193 | this.window.setAnimationStyle(R.style.Animations_GrowFromTop); 194 | } 195 | 196 | this.window.showAtLocation(this.anchor, Gravity.NO_GRAVITY, xPos, yPos); 197 | } 198 | 199 | public void dismiss() { 200 | this.window.dismiss(); 201 | } 202 | } -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.OutputStream; 8 | 9 | /** 10 | * Misc fiel related util methods. 11 | */ 12 | public class FileUtils { 13 | 14 | /** 15 | * Copies src file to dst file. If the dst file does not exist, it will be 16 | * created. 17 | * 18 | * @param src 19 | * @param dst 20 | * @throws IOException 21 | */ 22 | public static void copyToFile(InputStream src, File dst) 23 | throws IOException { 24 | OutputStream out = null; 25 | try { 26 | out = new FileOutputStream(dst); 27 | 28 | // Transfer bytes from in to out 29 | byte[] buf = new byte[1024]; 30 | int len; 31 | while ((len = src.read(buf)) > 0) { 32 | out.write(buf, 0, len); 33 | } 34 | } finally { 35 | try { 36 | if (out != null) { 37 | out.close(); 38 | } 39 | } catch (IOException e) { 40 | // can't do anything about this 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/PageImageAdapter.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import java.io.File; 4 | import java.lang.ref.WeakReference; 5 | 6 | import android.content.Context; 7 | import android.graphics.Bitmap; 8 | import android.graphics.BitmapFactory; 9 | import android.graphics.Canvas; 10 | import android.graphics.Paint; 11 | import android.graphics.drawable.BitmapDrawable; 12 | import android.os.AsyncTask; 13 | import android.util.Log; 14 | import android.view.View; 15 | import android.view.ViewGroup; 16 | import android.widget.BaseAdapter; 17 | import android.widget.ImageView; 18 | 19 | public class PageImageAdapter extends BaseAdapter { 20 | 21 | private final String TAG = "PageImageAdapter"; 22 | 23 | private final static int THUMB_SCALE_FACTOR = 4; 24 | 25 | private Context mContext; 26 | private File[] mFileList; 27 | private int mBackgroundColor; 28 | private Paint mPainter; 29 | private int currentPageCount; 30 | 31 | private Bitmap mDefaultBitMap; 32 | private static BitmapFactory.Options mBitmapFactoryOpts; 33 | 34 | static { 35 | mBitmapFactoryOpts = new BitmapFactory.Options(); 36 | mBitmapFactoryOpts.inSampleSize = THUMB_SCALE_FACTOR; 37 | } 38 | 39 | public PageImageAdapter(Context c) { 40 | mContext = c; 41 | 42 | mBackgroundColor = mContext.getResources().getColor(R.color.page_colour); 43 | 44 | getFilesList(); 45 | mDefaultBitMap = ((BitmapDrawable)mContext.getResources().getDrawable(R.drawable.default_thumb)).getBitmap(); 46 | } 47 | 48 | public int getCount() { 49 | return currentPageCount; 50 | } 51 | 52 | public Object getItem(int position) { 53 | return null; 54 | } 55 | 56 | public long getItemId(int position) { 57 | return mFileList[position].hashCode(); 58 | } 59 | 60 | @Override 61 | public boolean hasStableIds() { 62 | return true; 63 | } 64 | 65 | // create a new ImageView for each item referenced by the Adapter 66 | public View getView(int position, View convertView, ViewGroup parent) { 67 | Log.d(TAG,"Page Adapter - "+ SKNotesActivity.getMemUsageString()); 68 | 69 | if (convertView == null) { // if it's not recycled, initialize some attributes 70 | Log.d(TAG, "NEW IMG VIEW"); 71 | convertView = new ImageView(mContext); 72 | } 73 | 74 | Object currThumbTask = convertView.getTag(); 75 | if (currThumbTask != null) { 76 | ((MkThumbsAsync)currThumbTask).cancel(true); 77 | } 78 | 79 | MkThumbsAsync thumbLoader = new MkThumbsAsync((ImageView)convertView); 80 | convertView.setTag(thumbLoader); 81 | thumbLoader.execute(position); 82 | 83 | ((ImageView)convertView).setImageBitmap(mDefaultBitMap); 84 | 85 | return convertView; 86 | } 87 | 88 | private void getFilesList() { 89 | File storeDir = mContext.getFilesDir(); 90 | 91 | Log.d(TAG, "getting page files list..."); 92 | 93 | if (storeDir != null) { 94 | mFileList = storeDir.listFiles(); 95 | } else { 96 | Log.e(TAG, "invalid store dir:"+storeDir); 97 | } 98 | currentPageCount = mFileList.length; 99 | } 100 | 101 | void deletePage(int index) { 102 | Log.i(TAG, "Deleted Page:" + mFileList[index].getName()); 103 | mFileList[index].delete(); 104 | getFilesList(); 105 | } 106 | 107 | void renamePage(int index, String nuName) { 108 | //TODO the actual rename 109 | getFilesList(); 110 | Log.i(TAG, "ReNamed Page:" + mFileList[index].getName()); 111 | } 112 | 113 | public String getFileName(int position) { 114 | return mFileList[position].getName(); 115 | } 116 | 117 | class MkThumbsAsync extends AsyncTask 118 | { 119 | private final String TAG = "MkThumbsAsync"; 120 | 121 | int mPosition; 122 | 123 | WeakReference mImgView; 124 | 125 | public MkThumbsAsync(ImageView imgView) { 126 | mImgView = new WeakReference(imgView); 127 | } 128 | 129 | @Override 130 | protected Bitmap doInBackground(Integer... params) { 131 | mPosition = params[0]; 132 | File currentfile = mFileList[mPosition]; 133 | Log.d(TAG, "img file:"+currentfile); 134 | //for explanation of why to use BMFactory options see 135 | //http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue/823966#823966 136 | 137 | String filePath = currentfile.getAbsolutePath(); 138 | 139 | //Decode with inSampleSize 140 | Bitmap loadedBM = BitmapFactory.decodeFile(filePath, mBitmapFactoryOpts); 141 | 142 | if (loadedBM != null) { 143 | Bitmap thumbBitMap = Bitmap.createBitmap(loadedBM.getWidth(), loadedBM.getHeight(), 144 | Bitmap.Config.RGB_565); 145 | 146 | Canvas newCanvas = new Canvas(); 147 | newCanvas.setBitmap(thumbBitMap); 148 | thumbBitMap.eraseColor(mBackgroundColor); 149 | newCanvas.drawBitmap(loadedBM, 0, 0, mPainter); 150 | 151 | loadedBM.recycle(); 152 | 153 | Log.d(TAG, "MkThumb Aft Recycle " + SKNotesActivity.getMemUsageString()); 154 | return thumbBitMap; 155 | } else { 156 | return null; 157 | } 158 | } 159 | 160 | @Override 161 | protected void onPostExecute(Bitmap thumb) { 162 | if (mImgView != null) { 163 | ImageView iView = mImgView.get(); 164 | if (iView != null) { 165 | iView.setImageBitmap(thumb); 166 | } 167 | } 168 | } 169 | } 170 | } 171 | 172 | 173 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/PagesList.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.util.Log; 7 | import android.view.ContextMenu; 8 | import android.view.Menu; 9 | import android.view.MenuItem; 10 | import android.view.View; 11 | import android.widget.AdapterView; 12 | import android.widget.AdapterView.AdapterContextMenuInfo; 13 | import android.widget.AdapterView.OnItemClickListener; 14 | import android.widget.GridView; 15 | 16 | public class PagesList extends Activity implements OnItemClickListener { 17 | 18 | private static final String TAG = "PagesList"; 19 | 20 | //==Pop up menu == 21 | /** Menu ID for the command to clear the window. */ 22 | private static final int RENAME_ID = Menu.FIRST; 23 | 24 | /** Menu ID for the command to clear the window. */ 25 | private static final int DELETE_ID = Menu.FIRST + 1; 26 | 27 | /** Menu ID for the command to clear the window. */ 28 | private static final int TAG_ID = Menu.FIRST + 2; 29 | //===== 30 | 31 | /** Menu ID for the command to create new sketch page. */ 32 | private static final int NEW_ID = Menu.FIRST + 3; 33 | 34 | private PageImageAdapter mAdapter; 35 | 36 | private GridView mView; 37 | 38 | @Override 39 | public void onCreate(Bundle savedInstanceState) { 40 | super.onCreate(savedInstanceState); 41 | 42 | Log.d(TAG, "Create PAGESLIST - "+ SKNotesActivity.getMemUsageString()); 43 | 44 | setContentView(R.layout.pages); 45 | 46 | mView = (GridView) findViewById(R.id.gridview); 47 | if (mView == null) { 48 | Log.e(TAG, "NO GRIDVIEW!!"); 49 | } else { 50 | mAdapter = new PageImageAdapter(this); 51 | mView.setAdapter(mAdapter); 52 | mView.setOnItemClickListener(this); 53 | registerForContextMenu(mView); 54 | } 55 | } 56 | 57 | @Override 58 | public boolean onCreateOptionsMenu(Menu menu) { 59 | menu.add(0, NEW_ID, 0, "New"); 60 | 61 | return super.onCreateOptionsMenu(menu); 62 | } 63 | 64 | @Override 65 | public boolean onOptionsItemSelected(MenuItem item) { 66 | switch (item.getItemId()) { 67 | case NEW_ID: 68 | Intent intent = new Intent(this, SKNotesActivity.class); 69 | startActivity(intent); 70 | return true; 71 | default: 72 | return super.onOptionsItemSelected(item); 73 | } 74 | } 75 | 76 | @Override 77 | protected void onPause() { 78 | super.onPause(); 79 | Log.d(TAG, "Paused PAGESLIST"+ SKNotesActivity.getMemUsageString()); 80 | } 81 | 82 | 83 | @Override 84 | public void onCreateContextMenu(ContextMenu menu, View v, 85 | ContextMenu.ContextMenuInfo menuInfo) { 86 | populateMenu(menu); 87 | } 88 | 89 | @Override 90 | public boolean onContextItemSelected(MenuItem item) { 91 | AdapterContextMenuInfo info = (AdapterContextMenuInfo) item 92 | .getMenuInfo(); 93 | int index = info.position; 94 | 95 | switch (item.getItemId()) { 96 | case RENAME_ID: 97 | Log.i(TAG, "reName Page" + index); 98 | // TODO 99 | return true; 100 | case TAG_ID: 101 | Log.i(TAG, "Tag Page" + index); 102 | // TODO 103 | return true; 104 | case DELETE_ID: 105 | //TODO: add confirmation dialog 106 | mAdapter.deletePage(index); 107 | mView.invalidateViews(); 108 | return true; 109 | default: 110 | return super.onContextItemSelected(item); 111 | } 112 | } 113 | 114 | private void populateMenu(Menu menu) { 115 | //TODO: implement rename function 116 | //menu.add(Menu.NONE, RENAME_ID, Menu.NONE, "Rename"); 117 | menu.add(Menu.NONE, DELETE_ID, Menu.NONE, "Delete"); 118 | //TODO: implement tagging function 119 | //menu.add(Menu.NONE, TAG_ID, Menu.NONE, "Tag"); 120 | 121 | } 122 | 123 | 124 | public void onItemClick(AdapterView parent, View v, 125 | int position, long id) { 126 | Log.e(TAG, "pos:" + position); 127 | Intent intent = new Intent(this, SKNotesActivity.class); 128 | intent.putExtra(SKNotesActivity.LOAD_FILENAME, mAdapter.getFileName(position)); 129 | startActivity(intent); 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/PenModel.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import android.content.Context; 4 | 5 | import java.util.ArrayList; 6 | 7 | /** 8 | * Created by maks on 14/09/17. 9 | */ 10 | 11 | class PenModel { 12 | 13 | private int colour; 14 | private String name; 15 | 16 | PenModel(int colour, String name) { 17 | this.colour = colour; 18 | this.name = name; 19 | } 20 | 21 | public int getPenColour() { 22 | return colour; 23 | } 24 | 25 | public String getPenName() { 26 | return name; 27 | } 28 | 29 | public static ArrayList getPens(Context context) { 30 | int[] penColours = context.getResources().getIntArray(R.array.penColourList); 31 | String[] penNames = context.getResources().getStringArray(R.array.penNameList); 32 | ArrayList pensList = new ArrayList<>(penColours.length); 33 | for (int i=0; i < penColours.length; i++) { 34 | pensList.add(new PenModel(penColours[i], penNames[i])); 35 | } 36 | return pensList; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/PenSelectionSpinnerModel.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import androidx.databinding.BaseObservable; 4 | import androidx.databinding.Bindable; 5 | 6 | /** 7 | * View Model for the currently selected pen type 8 | */ 9 | public class PenSelectionSpinnerModel extends BaseObservable { 10 | 11 | private final SketchView mView; 12 | 13 | public PenSelectionSpinnerModel(SketchView view) { 14 | mView = view; 15 | } 16 | 17 | public void setPenPos(int pos) { 18 | mView.setCurrentPenIndex(pos); 19 | notifyPropertyChanged(BR.spinModel); 20 | } 21 | 22 | @Bindable 23 | public int getPenPos() { 24 | return mView.getCurrentPenIndex(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/PensCustomAdapter.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import androidx.annotation.NonNull; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ArrayAdapter; 9 | import android.widget.TextView; 10 | 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * Custom adapter for Coloured Pens in Sketchnotes 15 | */ 16 | 17 | public class PensCustomAdapter extends ArrayAdapter { 18 | 19 | public PensCustomAdapter(@NonNull Context context, ArrayList pens) { 20 | super(context, R.layout.support_simple_spinner_dropdown_item, pens); 21 | } 22 | 23 | @Override 24 | public View getDropDownView(int position, View convertView,ViewGroup parent) { 25 | return getView(position, convertView, parent); 26 | } 27 | 28 | @Override 29 | public View getView(int position, View convertView, ViewGroup parent) { 30 | View row = super.getView(position, convertView, parent); 31 | PenModel pen = getItem(position); 32 | row.setBackgroundColor(pen.getPenColour()); 33 | ((TextView)row.findViewById(android.R.id.text1)).setText(pen.getPenName()); 34 | ((TextView)row.findViewById(android.R.id.text1)).setTextColor(getContrastColor(pen.getPenColour())); 35 | return row; 36 | } 37 | 38 | // https://stackoverflow.com/a/41335343/85472 39 | private static int getContrastColor(int color) { 40 | // Counting the perceptive luminance - human eye favors green color... 41 | double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255; 42 | return a < 0.5 ? Color.BLACK : Color.WHITE; 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/PreferenceHelper.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.preference.PreferenceManager; 6 | 7 | /** 8 | * Clean, central access to getting/setting user preferences 9 | */ 10 | 11 | public class PreferenceHelper { 12 | 13 | private static final int DEFAULT_INT = 0; 14 | private static final boolean DEFAULT_BOOLEAN = false; 15 | 16 | private static final String PREF_KEY_PEN_SIZE = "penSizePref"; 17 | private static final String PREF_KEY_PEN_COLOUR_IDX = "penColourIndex"; 18 | 19 | private final Context mContext; 20 | 21 | public PreferenceHelper(Context context) { 22 | mContext = context.getApplicationContext(); 23 | } 24 | 25 | 26 | protected SharedPreferences getSharedPrefs() { 27 | return PreferenceManager.getDefaultSharedPreferences(mContext); 28 | } 29 | 30 | public String getPenSizePref() { 31 | return getString(PREF_KEY_PEN_SIZE, "medium"); 32 | } 33 | 34 | public int getPenIndex() { 35 | return getInt(PREF_KEY_PEN_COLOUR_IDX); 36 | } 37 | 38 | public void setPenIndex(int penIndex) { 39 | edit(PREF_KEY_PEN_COLOUR_IDX, penIndex); 40 | } 41 | 42 | private void edit(String name, String value) { 43 | SharedPreferences.Editor editor = getSharedPrefs().edit(); 44 | editor.putString(name, value); 45 | editor.apply(); 46 | } 47 | 48 | private void edit(String name, int value) { 49 | SharedPreferences.Editor editor = getSharedPrefs().edit(); 50 | editor.putInt(name, value); 51 | editor.apply(); 52 | } 53 | 54 | private void edit(String name, boolean value) { 55 | SharedPreferences.Editor editor = getSharedPrefs().edit(); 56 | editor.putBoolean(name, value); 57 | editor.apply(); 58 | } 59 | 60 | private String getString(String name, String def) { 61 | return getSharedPrefs().getString(name, def); 62 | } 63 | 64 | private int getInt(String name) { 65 | return getSharedPrefs().getInt(name, DEFAULT_INT); 66 | } 67 | 68 | private boolean getBoolean(String name) { 69 | return getSharedPrefs().getBoolean(name, DEFAULT_BOOLEAN); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/SKNPrefs.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import android.os.Bundle; 4 | import android.preference.PreferenceActivity; 5 | 6 | public class SKNPrefs extends PreferenceActivity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | addPreferencesFromResource(R.xml.preferences); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/SKNotesActivity.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import android.content.Intent; 4 | import androidx.databinding.DataBindingUtil; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import android.os.Debug; 8 | import androidx.core.content.FileProvider; 9 | import androidx.appcompat.app.AppCompatActivity; 10 | import androidx.appcompat.widget.Toolbar; 11 | import android.util.Log; 12 | import android.view.Menu; 13 | import android.view.MenuInflater; 14 | import android.view.MenuItem; 15 | 16 | import com.manichord.sketchnotes.databinding.SknotesActivityBinding; 17 | 18 | import java.io.File; 19 | import java.util.Date; 20 | 21 | import timber.log.Timber; 22 | 23 | public class SKNotesActivity extends AppCompatActivity { 24 | 25 | private static final String TAG = "SKNotesActivity"; 26 | 27 | protected static final String LOAD_FILENAME = "com.manichord.sketchnotes.load_filename"; 28 | 29 | private String mCurrentFileName; 30 | private SknotesActivityBinding mBinding; 31 | 32 | /** Called when the activity is first created. */ 33 | @Override 34 | public void onCreate(Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | 37 | Timber.plant(new Timber.DebugTree()); 38 | Timber.d("TIMBER ready"); 39 | 40 | setupViews(); 41 | } 42 | 43 | @Override 44 | public boolean onCreateOptionsMenu(Menu menu) { 45 | MenuInflater inflater = getMenuInflater(); 46 | inflater.inflate(R.menu.main_menu, menu); 47 | return true; 48 | } 49 | 50 | @Override 51 | public boolean onOptionsItemSelected(MenuItem item) { 52 | switch (item.getItemId()) { 53 | case R.id.menu_draw: 54 | mBinding.skview.setEraserMode(false); 55 | return true; 56 | case R.id.menu_eraser: 57 | mBinding.skview.setEraserMode(true); 58 | return true; 59 | case R.id.menu_new_page: 60 | if (mBinding.skview != null) { 61 | mBinding.skview.saveCurrentBitMap(mCurrentFileName); 62 | 63 | Date now = new Date(); 64 | mCurrentFileName = "skpage" + now.getTime() + ".png"; 65 | mBinding.skview.clear(); 66 | } else { 67 | Log.e(TAG, "NO Sketch VIEW!!!"); 68 | } 69 | return true; 70 | case R.id.menu_pages: 71 | Intent intent = new Intent(this, PagesList.class); 72 | mBinding.skview.saveCurrentBitMap(mCurrentFileName); 73 | startActivity(intent); 74 | return true; 75 | case R.id.menu_settings: 76 | startActivity(new Intent(this, SKNPrefs.class)); 77 | return true; 78 | case R.id.menu_share: 79 | shareSketch(); 80 | return true; 81 | default: 82 | return super.onOptionsItemSelected(item); 83 | } 84 | } 85 | 86 | private void shareSketch() { 87 | // make sure current version is saved 88 | mBinding.skview.saveCurrentBitMap(mCurrentFileName); 89 | Intent sharingIntent = new Intent(Intent.ACTION_SEND); 90 | 91 | Uri sketchUri = FileProvider.getUriForFile(getApplicationContext(), 92 | "com.manichord.sketchnotes.fileprovider", 93 | new File(getApplicationContext().getFilesDir(),mCurrentFileName)); 94 | sharingIntent.setType("image/png"); 95 | sharingIntent.putExtra(Intent.EXTRA_STREAM, sketchUri); 96 | startActivity(Intent.createChooser(sharingIntent, 97 | "Share Sketch Using...")); 98 | } 99 | 100 | @Override 101 | protected void onPause() { 102 | super.onPause(); 103 | mBinding.skview.saveCurrentBitMap(mCurrentFileName); 104 | mBinding.skview.nullBitmaps(); 105 | System.gc(); 106 | Log.d(TAG, "SKNotesActivity onPause:"+mCurrentFileName+" mem:" + getMemUsageString()); 107 | } 108 | 109 | @Override 110 | protected void onResume() { 111 | super.onResume(); 112 | Log.d(TAG, "SKNotesActivity onResume:"+mCurrentFileName+" mem:" + getMemUsageString()); 113 | setupViews(); 114 | } 115 | 116 | public String getCurrentFileName() { 117 | return mCurrentFileName; 118 | } 119 | 120 | public static String getMemUsageString() { 121 | int usedNativeKbs = (int) (Debug.getNativeHeapAllocatedSize() / 1024L); 122 | 123 | return String.format(" SKNotesActivity Memory Used: %d KB", usedNativeKbs); 124 | } 125 | 126 | private void setupViews() { 127 | 128 | mBinding = DataBindingUtil.setContentView(this, R.layout.sknotes_activity); 129 | 130 | mBinding.penColourSpinner.setAdapter(new PensCustomAdapter(this, PenModel.getPens(this.getApplicationContext()))); 131 | 132 | mBinding.setSpinModel(new PenSelectionSpinnerModel(mBinding.skview)); 133 | 134 | Date now = new Date(); 135 | 136 | String fileToLoad = getIntent().getStringExtra(LOAD_FILENAME); 137 | getIntent().removeExtra(LOAD_FILENAME);//clear intent 138 | if (fileToLoad != null && !"".equals(fileToLoad)) { 139 | Log.d(TAG, "file from Intent filename:"+fileToLoad); 140 | mCurrentFileName = fileToLoad; 141 | } else { 142 | if (mCurrentFileName != null) { 143 | Log.d(TAG, "have current filename:"+mCurrentFileName); 144 | } else { 145 | mCurrentFileName = "skpage" + now.getTime() + ".png"; 146 | Log.d(TAG, "NEW filename:"+mCurrentFileName); 147 | } 148 | } 149 | 150 | Toolbar toolbar = ((Toolbar) findViewById(R.id.toolbar)); 151 | setSupportActionBar(toolbar); 152 | 153 | Log.d(TAG, " SKNotesActivity - " + SKNotesActivity.getMemUsageString()); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /app/src/main/java/com/manichord/sketchnotes/SketchView.java: -------------------------------------------------------------------------------- 1 | package com.manichord.sketchnotes; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.SharedPreferences; 6 | import android.content.SharedPreferences.Editor; 7 | import android.content.res.Resources; 8 | import android.graphics.Bitmap; 9 | import android.graphics.BitmapFactory; 10 | import android.graphics.Canvas; 11 | import android.graphics.Color; 12 | import android.graphics.Paint; 13 | import android.graphics.Paint.Style; 14 | import android.graphics.Path; 15 | import android.graphics.Point; 16 | import android.graphics.PorterDuff; 17 | import android.graphics.PorterDuffXfermode; 18 | import android.preference.PreferenceManager; 19 | import android.util.AttributeSet; 20 | import android.util.Log; 21 | import android.view.Display; 22 | import android.view.MotionEvent; 23 | import android.view.View; 24 | import android.view.View.OnTouchListener; 25 | 26 | import java.io.File; 27 | import java.io.FileOutputStream; 28 | import java.util.ArrayList; 29 | import java.util.Date; 30 | 31 | import timber.log.Timber; 32 | 33 | public class SketchView extends View implements OnTouchListener { 34 | 35 | private static final String TAG = "SketchView"; 36 | private final PreferenceHelper mPrefHelper; 37 | 38 | private long mLastSaveTime; 39 | 40 | private int SAVE_DELAY = 30 * 1000; //30sec 41 | 42 | private Bitmap mBitmap; 43 | private Canvas mCanvas; 44 | 45 | private Bitmap mBackgroundBitmap; 46 | private Canvas mBackgroundCanvas; 47 | 48 | Path mCurrentPath; 49 | 50 | private final Paint mPagePainter; 51 | private final Paint mGridPainter; 52 | private final Paint mPenPainter; 53 | private final Paint mEraserPainter; 54 | 55 | int width = 0; 56 | int height = 0; 57 | 58 | private boolean mUnsaved = false; 59 | 60 | public void setEraserMode(boolean eraserMode) { 61 | mEraserMode = eraserMode; 62 | } 63 | 64 | private boolean mEraserMode = false; 65 | 66 | public SketchView(Context context) { 67 | this(context, null); 68 | } 69 | 70 | public SketchView(Context context, AttributeSet attrs) { 71 | super(context, attrs); 72 | 73 | setFocusable(true); 74 | 75 | mPrefHelper = new PreferenceHelper(context); 76 | 77 | String penSizePref = mPrefHelper.getPenSizePref(); 78 | 79 | Integer penColour = mPrefHelper.getPenIndex(); 80 | 81 | mPagePainter = new Paint(); 82 | mPagePainter.setAntiAlias(true); 83 | mPagePainter.setColor(getResources().getColor(R.color.page_colour)); 84 | 85 | mGridPainter = new Paint(); 86 | mGridPainter.setColor(getResources().getColor(R.color.grid_colour)); 87 | mGridPainter.setStyle(Style.STROKE); 88 | 89 | mPenPainter = new Paint(); 90 | mPenPainter.setColor(penColour); 91 | 92 | int penSizeIdentifier = getResources().getIdentifier(penSizePref, 93 | "dimen", 94 | getContext().getPackageName()); 95 | 96 | Log.d(TAG, penSizePref + "-> got IDENT:" + penSizeIdentifier); 97 | 98 | float penSize = getResources().getDimension(R.dimen.pen_medium); 99 | if (penSizeIdentifier != 0) { 100 | penSize = getResources().getDimension(penSizeIdentifier); 101 | } 102 | 103 | mPenPainter.setStrokeWidth(penSize); 104 | mPenPainter.setStyle(Style.STROKE); 105 | 106 | float mEraserWidth = getResources().getDimension(R.dimen.eraser_size); 107 | 108 | mEraserPainter = new Paint(); 109 | mEraserPainter.setColor(Color.TRANSPARENT); 110 | mEraserPainter.setStrokeWidth(mEraserWidth); 111 | mEraserPainter.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 112 | 113 | mLastSaveTime = (new Date()).getTime(); 114 | } 115 | 116 | /** 117 | * Set and persist the current pen used for drawing 118 | * 119 | * @param penIndex 120 | */ 121 | public void setCurrentPenIndex(int penIndex) { 122 | int penColour = getResources().getIntArray(R.array.penColourList)[penIndex]; 123 | Timber.d("Set pen colour %d", penColour); 124 | mPrefHelper.setPenIndex(penIndex); 125 | mPenPainter.setColor(penColour); 126 | } 127 | 128 | /** 129 | * @return 130 | */ 131 | public int getCurrentPenIndex() { 132 | return mPrefHelper.getPenIndex(); 133 | } 134 | 135 | @Override 136 | protected void onDraw(Canvas canvas) { 137 | if (mBackgroundCanvas != null) { 138 | canvas.drawBitmap(mBackgroundBitmap, 0, 0, null); 139 | } else { 140 | Log.e(TAG, "NO BACKGROUND BITMAP!"); 141 | } 142 | if (mBitmap != null) { 143 | canvas.drawBitmap(mBitmap, 0, 0, null); 144 | } else { 145 | Log.e(TAG, "NO BITMAP!"); 146 | } 147 | Date now = new Date(); 148 | if (now.getTime() > (mLastSaveTime + SAVE_DELAY)) { 149 | saveCurrentBitMap(((SKNotesActivity) getContext()).getCurrentFileName()); 150 | mLastSaveTime = now.getTime(); 151 | } 152 | } 153 | 154 | @Override 155 | public boolean onTouchEvent(MotionEvent event) { 156 | 157 | float mCurX; 158 | float mCurY; 159 | 160 | ArrayList eraserpoints = new ArrayList(); 161 | 162 | int action = event.getAction(); 163 | if (action != MotionEvent.ACTION_UP 164 | && action != MotionEvent.ACTION_CANCEL) { 165 | //Log.d(TAG, "PEN UP"); 166 | } 167 | if (action == MotionEvent.ACTION_DOWN) { 168 | //start recording points 169 | mCurrentPath = new Path(); 170 | mCurrentPath.moveTo(event.getX(), event.getY()); 171 | } 172 | if (action == MotionEvent.ACTION_MOVE) { 173 | //start recording points 174 | int N = event.getHistorySize(); 175 | int P = event.getPointerCount(); 176 | for (int i = 0; i < N; i++) { 177 | for (int j = 0; j < P; j++) { 178 | mCurX = event.getHistoricalX(j, i); 179 | mCurY = event.getHistoricalY(j, i); 180 | 181 | if (mEraserMode == true) { 182 | if (eraserpoints != null) { 183 | eraserpoints.add(new Point(Math.round(mCurX), Math.round(mCurY))); 184 | } else { 185 | Log.e(TAG, "no eraserpoints array defined, skipping adding erase point"); 186 | } 187 | } else { 188 | if (mCurrentPath != null) { 189 | mCurrentPath.lineTo(mCurX, mCurY); 190 | } else { 191 | Log.e(TAG, "NO PATH TO ADD POINT" + mCurX + "," + mCurY); 192 | } 193 | } 194 | } 195 | } 196 | 197 | if (mCurrentPath != null) { 198 | mCurrentPath.lineTo(event.getX(), event.getY()); 199 | mCanvas.drawPath(mCurrentPath, (mEraserMode == true ? mEraserPainter : mPenPainter)); 200 | invalidate(); 201 | } else { 202 | Log.e(TAG, "Missing CurrentPath object"); 203 | } 204 | } 205 | mUnsaved = true; 206 | return true; 207 | } 208 | 209 | 210 | public boolean onTouch(View v, MotionEvent event) { 211 | return false; 212 | } 213 | 214 | @Override 215 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 216 | 217 | Log.i(TAG, "Size changed w:" + w + " h:" + h); 218 | 219 | createNewDrawingCanvasAndBitMap(w, h); 220 | 221 | drawPageGridOrLines(w, h); 222 | loadBitMap(((SKNotesActivity) getContext()).getCurrentFileName()); 223 | } 224 | 225 | public void clear() { 226 | int curW = mBitmap != null ? mBitmap.getWidth() : 0; 227 | int curH = mBitmap != null ? mBitmap.getHeight() : 0; 228 | 229 | createNewDrawingCanvasAndBitMap(curW, curH); 230 | drawPageGridOrLines(curW, curH); 231 | invalidate(); 232 | } 233 | 234 | private void createNewDrawingCanvasAndBitMap(int w, int h) { 235 | Bitmap newBitmap = Bitmap.createBitmap(w, h, 236 | Bitmap.Config.ARGB_8888); 237 | Canvas newCanvas = new Canvas(); 238 | newCanvas.setBitmap(newBitmap); 239 | 240 | if (mBitmap != null) { 241 | mBitmap.recycle(); //tell android to clear up prev bitmap 242 | } 243 | 244 | mBitmap = newBitmap; 245 | mCanvas = newCanvas; 246 | } 247 | 248 | private void drawPageGridOrLines(int w, int h) { 249 | 250 | Resources res = getResources(); 251 | int xpos = Math.round(res.getDimension(R.dimen.grid_size)); 252 | int ypos = Math.round(res.getDimension(R.dimen.grid_size)); 253 | 254 | Bitmap newBackgroundBitmap = Bitmap.createBitmap(w, h, 255 | Bitmap.Config.RGB_565); 256 | Canvas newBackgroundCanvas = new Canvas(); 257 | newBackgroundCanvas.setBitmap(newBackgroundBitmap); 258 | 259 | 260 | if (mBackgroundBitmap != null) { 261 | newBackgroundCanvas.drawBitmap(mBackgroundBitmap, 0, 0, null); 262 | } 263 | mBackgroundBitmap = newBackgroundBitmap; 264 | mBackgroundCanvas = newBackgroundCanvas; 265 | 266 | // make the entire canvas page colour 267 | mBackgroundCanvas.drawPaint(mPagePainter); 268 | 269 | // Draw Background Grid 270 | Display display = ((Activity) getContext()).getWindowManager().getDefaultDisplay(); 271 | width = display.getWidth();// start 272 | height = display.getHeight();// end 273 | 274 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getContext()); 275 | String pageBackgroundPref = prefs.getString("pageBackgroundPref", "Grid"); 276 | 277 | //lines only 278 | if (!pageBackgroundPref.equals("None")) { 279 | for (int i = 0; i < height; i += ypos) { 280 | mBackgroundCanvas.drawLine(0, i, width, i, mGridPainter); 281 | } 282 | } 283 | 284 | if (pageBackgroundPref.equals("Grid")) { 285 | // add for square graph paper: 286 | for (int i = 0; i < width; i += xpos) { 287 | mBackgroundCanvas.drawLine(i, 0, i, height, mGridPainter); 288 | } 289 | } 290 | } 291 | 292 | 293 | public void saveCurrentBitMap(String filename) { 294 | if (!mUnsaved) { 295 | return; //do nothing if no unsaved changes pending 296 | } 297 | try { 298 | FileOutputStream out = (getContext()).openFileOutput(filename, 299 | Context.MODE_PRIVATE); 300 | mBitmap.compress(Bitmap.CompressFormat.PNG, 99, out); //note PNG lossless 301 | mUnsaved = false; 302 | Log.i(TAG, "saved page:" + filename); 303 | } catch (Exception e) { 304 | e.printStackTrace(); 305 | } 306 | } 307 | 308 | public void loadBitMap(String filename) { 309 | Bitmap loadedBM = BitmapFactory.decodeFile(((Activity) getContext()).getFilesDir() + File.separator + filename); 310 | if (loadedBM != null) { 311 | Log.i(TAG, "decoded:" 312 | + loadedBM.getHeight()); 313 | mCanvas.drawBitmap(loadedBM, 0, 0, null); 314 | mUnsaved = false; 315 | invalidate(); 316 | } else { 317 | Log.e(TAG, "bitmap file not found!"); 318 | } 319 | } 320 | 321 | public void nullBitmaps() { 322 | mCanvas = null; 323 | if (mBitmap != null) { 324 | mBitmap.recycle(); 325 | } 326 | mBitmap = null; 327 | mBackgroundCanvas = null; 328 | if (mBackgroundBitmap != null) { 329 | mBackgroundBitmap.recycle(); 330 | } 331 | mBackgroundBitmap = null; 332 | } 333 | 334 | } 335 | -------------------------------------------------------------------------------- /app/src/main/res/anim/grow_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/anim/grow_from_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/anim/grow_from_topleft_to_bottomright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/anim/shrink_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/anim/shrink_from_bottomright_to_topleft.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/anim/shrink_from_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/black_pen_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/blue_pen_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/default_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/app/src/main/res/drawable-hdpi/default_thumb.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/h4_pencil_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/hb_pencil_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/app/src/main/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/notebook_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/app/src/main/res/drawable-hdpi/notebook_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/red_pen_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/yellow_hl_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/app/src/main/res/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/notebook_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/app/src/main/res/drawable-ldpi/notebook_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/app/src/main/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/notebook_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/app/src/main/res/drawable-mdpi/notebook_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_eraser_variant.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_mode_edit_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/pages.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/pages.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/sknotes_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 15 | 16 | 26 | 27 | 35 | 36 | 37 | 38 | 39 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 18 | 19 | 23 | 27 | 31 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #F5F5DC 4 | #A4DDED 5 | #555 6 | #AAA 7 | #005db4 8 | #ff0000 9 | #ffff00 10 | #111111 11 | #FF2222 12 | #777777 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 0.5mm 3 | 0.7mm 4 | 0.9mm 5 | 2.0mm 6 | 1.0mm 7 | 4.5mm 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello World, main! 4 | Sketch Notes 5 | 6 | Pages 7 | Preferences 8 | 9 | New 10 | Pages 11 | Settings 12 | Share 13 | 14 | HB Pencil 15 | H4 Pencil 16 | Black Pen 17 | Blue Pen 18 | Red Pen 19 | Yellow HL 20 | Draw 21 | Erase 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 16 | 17 | 21 | 22 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/values/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Grid 5 | Lines 6 | None 7 | 8 | 9 | 10 | Small (0.5mm) 11 | Medium (0.7mm) 12 | Large (0.9mm) 13 | 14 | 15 | 16 | pen_small 17 | pen_medium 18 | pen_large 19 | 20 | 21 | 22 | @string/pen_hb_pencil 23 | @string/pen_h4_pencil 24 | @string/pen_black 25 | @string/pen_blue 26 | @string/pen_red 27 | @string/pen_yellow_hl 28 | 29 | 30 | 31 | @color/hb_pencil 32 | @color/h4_pencil 33 | @color/black_pen 34 | @color/blue_pen 35 | @color/red_pen 36 | @color/yellow_hl 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/xml/filepaths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/xml/preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/xml/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:8.3.2' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | mavenCentral() 16 | maven { 17 | url "https://maven.google.com" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/app-icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/docs/app-icon-512.png -------------------------------------------------------------------------------- /docs/app-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 31 | 34 | 38 | 42 | 43 | 54 | 61 | 68 | 75 | 82 | 83 | 102 | 105 | 106 | 108 | 109 | 111 | image/svg+xml 112 | 114 | 115 | 116 | 117 | 118 | 123 | 126 | 133 | 136 | 142 | 148 | 154 | 160 | 166 | 172 | 178 | 184 | 190 | 196 | 202 | 208 | 214 | 220 | 226 | 232 | 238 | 244 | 250 | 256 | 262 | 268 | 274 | 280 | 286 | 292 | 298 | 304 | 310 | 316 | 322 | 328 | 334 | 340 | 341 | 342 | 343 | 344 | -------------------------------------------------------------------------------- /docs/draw_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/docs/draw_icon.png -------------------------------------------------------------------------------- /docs/erase-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 28 | 35 | 44 | 47 | 51 | 55 | 56 | 59 | 63 | 64 | 73 | 75 | 79 | 83 | 87 | 88 | 97 | 99 | 103 | 107 | 111 | 112 | 122 | 124 | 128 | 132 | 136 | 137 | 147 | 149 | 153 | 157 | 161 | 162 | 172 | 174 | 178 | 182 | 183 | 190 | 194 | 195 | 204 | 206 | 210 | 214 | 215 | 224 | 226 | 230 | 234 | 235 | 236 | 254 | 256 | 257 | 259 | image/svg+xml 260 | 262 | 263 | 264 | 265 | 266 | 270 | 273 | 277 | 280 | 283 | 287 | 291 | 296 | 301 | 302 | 306 | 311 | 312 | 317 | 321 | 325 | 330 | 334 | 338 | 339 | 343 | 348 | 349 | 353 | 357 | 361 | 366 | 370 | 374 | 378 | 379 | 387 | 395 | 396 | 397 | 398 | 399 | -------------------------------------------------------------------------------- /docs/erase_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/docs/erase_icon.png -------------------------------------------------------------------------------- /docs/notebook_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/docs/notebook_icon.png -------------------------------------------------------------------------------- /docs/pen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 28 | 35 | 39 | 43 | 44 | 54 | 57 | 61 | 65 | 69 | 73 | 77 | 81 | 85 | 86 | 96 | 99 | 103 | 107 | 111 | 112 | 122 | 125 | 129 | 133 | 137 | 138 | 148 | 151 | 155 | 159 | 163 | 167 | 171 | 172 | 173 | 191 | 193 | 194 | 196 | image/svg+xml 197 | 199 | 200 | 201 | 202 | 203 | 207 | 210 | 215 | 218 | 223 | 229 | 234 | 240 | 241 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /docs/research.textile: -------------------------------------------------------------------------------- 1 | h1. Research 2 | 3 | h2. Gfx 4 | 5 | * "how to draw simple grid using android 2d api":http://www.ceveni.com/2009/07/sample-program-to-draw-grid-using.html 6 | * "simple drawing program using android 2d api":http://marakana.com/tutorials/android/2d-graphics-example.html 7 | * "simple drawing app from android samples":http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.html 8 | * "working with bitmaps article":http://www.higherpass.com/Android/Tutorials/Working-With-Images-In-Android/2/ 9 | * "posting on howto set transparency when drawing":http://groups.google.com/group/android-developers/browse_thread/thread/5b0a498664b17aa0/e2548672a8294677?lnk=gst&q=How+to+paint+transparency#e2548672a8294677 10 | * "...and the example app for PortDuff XferModes":http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.html 11 | * "yet more info on the dreaded OOM for bitmaps":http://code.google.com/p/android/issues/detail?id=8488 12 | * "asyncd-ing listview":http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html 13 | 14 | h2. Design 15 | 16 | * "non photo blue colour used for gridline":http://en.wikipedia.org/wiki/Non-photo_blue 17 | * "handy list of colours and RGB values":http://en.wikipedia.org/wiki/List_of_colours 18 | * "open clipart library":http://www.openclipart.org/tags/paper?page=1 19 | * "notebook icon":http://www.openclipart.org/detail/100339 20 | * "wikipedia pencil rgb":http://en.wikipedia.org/wiki/Pencil#Grading_and_classification 21 | 22 | h2. Existing Apps as examples 23 | 24 | * "the article that inspired this app":http://www.alistapart.com/articles/sketching-the-visual-thinking-power-tool/ 25 | * "draft":http://37signals.com/draft 26 | * "penultimate":http://www.cocoabox.com/penultimate 27 | * "review showing limitations of capacitve screen+stylus":http://www.youtube.com/watch?v=9gjruoxBrpA 28 | 29 | h2. Andriod UI 30 | 31 | * "context menus":http://stackoverflow.com/questions/2453620/android-how-to-find-the-position-clicked-from-the-context-menu 32 | * "rotate emualtor":http://www.androidpeople.com/android-rotate-emulator/ 33 | 34 | h3. Quick Actions 35 | 36 | * http://stackoverflow.com/questions/3451889/android-popup-menu 37 | * http://www.londatiga.net/it/how-to-create-quickaction-dialog-in-android/ 38 | * http://code.google.com/p/simple-quickactions/ 39 | 40 | 41 | h2. Devices 42 | 43 | h3. ZTE v9 44 | 45 | Screen size: 153 X 92mm (6.0236 x 3.622in) 46 | Screen res: 800 x 480 47 | -------------------------------------------------------------------------------- /docs/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/docs/screenshot1.png -------------------------------------------------------------------------------- /docs/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/docs/screenshot2.png -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ## For more details on how to configure your build environment visit 2 | # http://www.gradle.org/docs/current/userguide/build_environment.html 3 | # 4 | # Specifies the JVM arguments used for the daemon process. 5 | # The setting is particularly useful for tweaking memory settings. 6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m 7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 8 | # 9 | # When configured, Gradle will run in incubating parallel mode. 10 | # This option should only be used with decoupled projects. For more details, visit 11 | # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects 12 | # org.gradle.parallel=true 13 | #Fri May 24 20:31:08 AEST 2024 14 | android.defaults.buildfeatures.buildconfig=true 15 | android.enableJetifier=true 16 | android.nonFinalResIds=false 17 | android.nonTransitiveRClass=false 18 | android.useAndroidX=true 19 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /import-summary.txt: -------------------------------------------------------------------------------- 1 | ECLIPSE ANDROID PROJECT IMPORT SUMMARY 2 | ====================================== 3 | 4 | Ignored Files: 5 | -------------- 6 | The following files were *not* copied into the new Gradle project; you 7 | should evaluate whether these are still needed in your project and if 8 | so manually move them: 9 | 10 | * .gitignore 11 | * .idea/ 12 | * .idea/.name 13 | * .idea/compiler.xml 14 | * .idea/copyright/ 15 | * .idea/copyright/profiles_settings.xml 16 | * .idea/encodings.xml 17 | * .idea/misc.xml 18 | * .idea/workspace.xml 19 | * README.textile 20 | * app/ 21 | * app/build.gradle 22 | * app/src/ 23 | * app/src/main/ 24 | * app/src/main/AndroidManifest.xml 25 | * app/src/main/java/ 26 | * app/src/main/java/com/ 27 | * app/src/main/java/com/manichord/ 28 | * app/src/main/java/com/manichord/sketchnotes/ 29 | * app/src/main/java/com/manichord/sketchnotes/BetterPopupWindow.java 30 | * app/src/main/java/com/manichord/sketchnotes/PageImageAdapter.java 31 | * app/src/main/java/com/manichord/sketchnotes/PagesList.java 32 | * app/src/main/java/com/manichord/sketchnotes/SKNPrefs.java 33 | * app/src/main/java/com/manichord/sketchnotes/SKNotes.java 34 | * app/src/main/java/com/manichord/sketchnotes/SketchView.java 35 | * app/src/main/res/ 36 | * app/src/main/res/anim/ 37 | * app/src/main/res/anim/grow_from_bottom.xml 38 | * app/src/main/res/anim/grow_from_top.xml 39 | * app/src/main/res/anim/grow_from_topleft_to_bottomright.xml 40 | * app/src/main/res/anim/shrink_from_bottom.xml 41 | * app/src/main/res/anim/shrink_from_bottomright_to_topleft.xml 42 | * app/src/main/res/anim/shrink_from_top.xml 43 | * app/src/main/res/drawable-hdpi/ 44 | * app/src/main/res/drawable-hdpi/black_pen_button.xml 45 | * app/src/main/res/drawable-hdpi/blue_pen_button.xml 46 | * app/src/main/res/drawable-hdpi/default_thumb.png 47 | * app/src/main/res/drawable-hdpi/h4_pencil_button.xml 48 | * app/src/main/res/drawable-hdpi/hb_pencil_button.xml 49 | * app/src/main/res/drawable-hdpi/icon.png 50 | * app/src/main/res/drawable-hdpi/notebook_icon.png 51 | * app/src/main/res/drawable-hdpi/red_pen_button.xml 52 | * app/src/main/res/drawable-hdpi/yellow_hl_button.xml 53 | * app/src/main/res/drawable-ldpi/ 54 | * app/src/main/res/drawable-ldpi/icon.png 55 | * app/src/main/res/drawable-ldpi/notebook_icon.png 56 | * app/src/main/res/drawable-mdpi/ 57 | * app/src/main/res/drawable-mdpi/draw_button.png 58 | * app/src/main/res/drawable-mdpi/eraser_button.png 59 | * app/src/main/res/drawable-mdpi/icon.png 60 | * app/src/main/res/drawable-mdpi/notebook_icon.png 61 | * app/src/main/res/drawable-mdpi/pen_button.png 62 | * app/src/main/res/layout-land/ 63 | * app/src/main/res/layout-land/pages.xml 64 | * app/src/main/res/layout/ 65 | * app/src/main/res/layout/colours_popup.xml 66 | * app/src/main/res/layout/main.xml 67 | * app/src/main/res/layout/pages.xml 68 | * app/src/main/res/values/ 69 | * app/src/main/res/values/colors.xml 70 | * app/src/main/res/values/dimens.xml 71 | * app/src/main/res/values/strings.xml 72 | * app/src/main/res/values/styles.xml 73 | * app/src/main/res/values/values.xml 74 | * app/src/main/res/xml/ 75 | * app/src/main/res/xml/preferences.xml 76 | * app/src/main/res/xml/settings.xml 77 | * build.gradle 78 | * docs/ 79 | * docs/app-icon-512.png 80 | * docs/app-icon.svg 81 | * docs/draw-icon.svg 82 | * docs/draw_icon.png 83 | * docs/erase-icon.svg 84 | * docs/erase_icon.png 85 | * docs/eraser-pen-icons.svg 86 | * docs/notebook_black.svg 87 | * docs/notebook_icon.png 88 | * docs/pen.svg 89 | * docs/research.textile 90 | * docs/screenshot1.png 91 | * docs/screenshot2.png 92 | * gradle/ 93 | * gradle/wrapper/ 94 | * gradle/wrapper/gradle-wrapper.jar 95 | * gradle/wrapper/gradle-wrapper.properties 96 | * gradlew 97 | * gradlew.bat 98 | * settings.gradle 99 | 100 | Moved Files: 101 | ------------ 102 | Android Gradle projects use a different directory structure than ADT 103 | Eclipse projects. Here's how the projects were restructured: 104 | 105 | * AndroidManifest.xml => app/src/main/AndroidManifest.xml 106 | * res/ => app/src/main/res/ 107 | * src/ => app/src/main/java/ 108 | 109 | Next Steps: 110 | ----------- 111 | You can now build the project. The Gradle project needs network 112 | connectivity to download dependencies. 113 | 114 | Bugs: 115 | ----- 116 | If for some reason your project does not build, and you determine that 117 | it is due to a bug or limitation of the Eclipse to Gradle importer, 118 | please file a bug at http://b.android.com with category 119 | Component-Tools. 120 | 121 | (This import summary is for your information only, and can be deleted 122 | after import once you are satisfied with the results.) 123 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system use, 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | 10 | # Project target. 11 | target=android-19 12 | -------------------------------------------------------------------------------- /res/anim/grow_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /res/anim/grow_from_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /res/anim/grow_from_topleft_to_bottomright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /res/anim/shrink_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /res/anim/shrink_from_bottomright_to_topleft.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /res/anim/shrink_from_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /res/drawable-hdpi/black_pen_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/drawable-hdpi/blue_pen_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/drawable-hdpi/default_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-hdpi/default_thumb.png -------------------------------------------------------------------------------- /res/drawable-hdpi/h4_pencil_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/drawable-hdpi/hb_pencil_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /res/drawable-hdpi/notebook_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-hdpi/notebook_icon.png -------------------------------------------------------------------------------- /res/drawable-hdpi/red_pen_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/drawable-hdpi/yellow_hl_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /res/drawable-ldpi/notebook_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-ldpi/notebook_icon.png -------------------------------------------------------------------------------- /res/drawable-mdpi/draw_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-mdpi/draw_button.png -------------------------------------------------------------------------------- /res/drawable-mdpi/eraser_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-mdpi/eraser_button.png -------------------------------------------------------------------------------- /res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /res/drawable-mdpi/notebook_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-mdpi/notebook_icon.png -------------------------------------------------------------------------------- /res/drawable-mdpi/pen_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maks/Sketch-Notes/a48c48c0aceb4f8d5edbe34cd8a9eab205fe16d7/res/drawable-mdpi/pen_button.png -------------------------------------------------------------------------------- /res/layout-land/pages.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /res/layout/colours_popup.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 |