====== Differences ====== This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
script_app_drawer [2014/09/24 16:09] lm13 [About the script] |
script_app_drawer [2015/04/23 14:49] (current) lm13 |
||
---|---|---|---|
Line 2: | Line 2: | ||
* Purpose : This script will fill any container with all of your apps, like an App Drawer | * Purpose : This script will fill any container with all of your apps, like an App Drawer | ||
* Author : [[https://plus.google.com/+LukasMorawietz|LM13]] | * Author : [[https://plus.google.com/+LukasMorawietz|LM13]] | ||
- | * Current Version : 2.1 | + | * Current Version : 3.2 |
* Link: https://plus.google.com/115366157037831519359/posts/4F9TpMfz2fv | * Link: https://plus.google.com/115366157037831519359/posts/4F9TpMfz2fv | ||
- | * Download avialable! (Check repository) | + | * Video: https://plus.google.com/+LukasMorawietz/posts/L8r6qKajirq |
+ | * Download available! (Check repository) | ||
====== Changelog ====== | ====== Changelog ====== | ||
Line 11: | Line 12: | ||
* Version 2.0 (23/7/2014): Removed autovalues, due to an unfixable bug, added item remove and add again | * Version 2.0 (23/7/2014): Removed autovalues, due to an unfixable bug, added item remove and add again | ||
* Version 2.1 (28/8/2014): Sorting ignores Case | * Version 2.1 (28/8/2014): Sorting ignores Case | ||
+ | * Version 3.0 (21/3/2015): Doesn't rely on LLs drawer anymore, hiding items improved | ||
+ | * Version 3.1 (21/3/2015): Fix crash on pre-lollipop devices, added reload | ||
+ | * Version 3.2 (23/4/2015): Fix compatibility with latest Lightning Versions | ||
====== How to use the script ====== | ====== How to use the script ====== | ||
- | * Set the script in the resumed event of the container | + | * load the apk |
- | * configure what you want at the beginning of the script | + | |
- | * enable the script for Lightning and item menu | + | |
- | * if you don't want to see an app in the new app drawer, run this script from the item menu | + | |
- | * to re-add items, run this script from lightning menu | + | |
====== Issues and Hints ====== | ====== Issues and Hints ====== | ||
- | * As the script is based on the original app drawer, you may have to load the original app drawer once to detect installed or uninstalled apps | + | * first load may take some time |
- | * first load may take some time | + | |
- | * don't hide the icons in the original app drawer. | + | |
* if you delete items in the normal way, it will cause an error | * if you delete items in the normal way, it will cause an error | ||
+ | * Note: The setup script won't work outside of the APK | ||
//please report all bugs in the g+ community!// | //please report all bugs in the g+ community!// | ||
- | ====== Script ====== | + | ====== Scripts ====== |
- | <sxh javascript;>//config | + | <spoiler|Setup> |
- | var columns=5;//has to be an Integer >0 | + | <sxh javascript;>var MY_PKG="net.pierrox.lightning_launcher.llscript.appdrawer"; |
- | var rows=0;//has to be an Integer >=0, 0 for infinite | + | var TAG = "appdrawer_lukas"; |
- | //endconfig | + | |
+ | // install (or update) a script given its id in the package, and its clear name in the launcher data | ||
+ | function installScript(id,name){ | ||
+ | // load the script (if any) among the existing ones | ||
+ | var script=LL.getScriptByName(name); | ||
- | var e=LL.getEvent(); | + | var script_text=LL.loadRawResource(MY_PKG,id); |
- | var c=e.getContainer(); | + | |
- | var d=LL.getContainerById(99); | + | |
- | var db=JSON.parse(c.getTag())||[]; | + | |
- | if(e.getSource()=="MENU_ITEM") | + | if(script==null){ |
- | { | + | // script not found: install it |
- | if(db[0]==null) | + | script=LL.createScript(name,script_text,0); |
- | { | + | }else{ |
- | alert("Error: database for this container not yet created!"); | + | // the script already exists: update its text |
- | return; | + | script.setText(script_text); |
} | } | ||
- | var i=e.getItem(); | ||
- | var a=0; | ||
- | while(db[a][1]!=i.getId()||a==db.length)a++; | ||
- | if(a==db.length) | ||
- | { | ||
- | if(confirm("Item not in database.\n Delete anyway?"))c.removeItem(i); | ||
- | return; | ||
- | } | ||
- | db[a][1]=-1; | ||
- | c.removeItem(i); | ||
- | } | ||
- | if(e.getSource()=="MENU_APP") | + | return script; |
- | { | + | |
- | if(db[0]==null) | + | |
- | { | + | |
- | alert("Error: database for this container not yet created!"); | + | |
- | return; | + | |
- | } | + | |
- | var found=false; | + | |
- | for(a=0;a<db.length;a++) | + | |
- | { | + | |
- | if(db[a][1]==-1) | + | |
- | { | + | |
- | var found=true; | + | |
- | var item=LL.getItemById(db[a][0]); | + | |
- | if(confirm("Recreate "+item.getLabel()+"?")) | + | |
- | { | + | |
- | var newItem=c.addShortcut(item.getLabel(),item.getIntent(),0,0); | + | |
- | newItem.setDefaultIcon(item.getDefaultIcon()); | + | |
- | db[a][1]=newItem.getId(); | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | if(!found)Android.makeNewToast("No deleted items found",true).show(); | + | |
} | } | ||
- | var ditems=d.getItems(); | + | |
- | for(a0=0;a0<ditems.length;a0++) | + | var script=installScript("appdrawer","AppDrawer_main"); |
- | resetTag(ditems.getAt(a0)); | + | var menu= installScript("menu","AppDrawer_menu"); |
- | for(a1=0;a1<db.length;a1++) | + | if(!confirm("Do you want to use this container as App Drawer?"))return; |
- | { | + | var data={}; |
- | if(LL.getItemById(db[a1][0])==null) | + | data.columns=prompt("How many columns do you want?","5"); |
- | { | + | if(data.columns == null) return; |
- | if(LL.getItemById(db[a1][1])!=null) | + | data.rows=prompt("How many rows do you want? (0 for infinite)","0"); |
- | c.removeItem(LL.getItemById(db[a1][1])); | + | if(data.rows == null) return; |
- | if(a1==db.length-1)db.pop(); | + | var c=LL.getEvent().getContainer(); |
- | else | + | c.setTag(TAG,JSON.stringify(data)); |
- | { | + | c.getProperties().edit().setEventHandler("resumed",EventHandler.RUN_SCRIPT,script.getId()).setEventHandler("bgLongTap",EventHandler.RUN_SCRIPT,menu.getId()).commit(); |
- | db[a1]=db.pop(); | + | Android.makeNewToast("Enjoy your new Appdrawer!",true).show(); |
- | a1--; | + | </sxh> |
- | } | + | </spoiler> |
- | } | + | <spoiler|Menu> |
- | else{ | + | <sxh javascript;>LL.bindClass("android.R"); |
- | LL.getItemById(db[a1][0]).setTag("saved"); | + | LL.bindClass("java.util.ArrayList"); |
- | } | + | LL.bindClass("android.view.ViewTreeObserver"); |
+ | LL.bindClass("android.widget.Button"); | ||
+ | LL.bindClass("android.view.View"); | ||
+ | LL.bindClass("android.os.Build"); | ||
+ | |||
+ | var sourceItem = LL.getEvent().getItem(); | ||
+ | var context = LL.getContext(); | ||
+ | var pkg = context.getPackageName(); | ||
+ | var rsrc = context.getResources(); | ||
+ | var id = rsrc.getIdentifier("bubble_content", "id", pkg); | ||
+ | var menu =context.getWindow().getDecorView().findViewById(id); | ||
+ | var menuRoot = menu.getParent(); | ||
+ | var version = Build.VERSION.SDK_INT; | ||
+ | |||
+ | var obs=menuRoot.getViewTreeObserver(); | ||
+ | var l=new ViewTreeObserver.OnGlobalLayoutListener(){ | ||
+ | onGlobalLayout:function(){ | ||
+ | var list=menu; | ||
+ | var first=list.getChildAt(0); | ||
+ | list.removeAllViews(); | ||
+ | var v = !(typeof invisible === 'undefined' || invisible); | ||
+ | add(v?"Hide Hidden":"Show Hidden",function(){ | ||
+ | LL.runAction(EventHandler.LAUNCHER_MENU); | ||
+ | invisible = v; | ||
+ | LL.runScript("AppDrawer_main",v?"":"showHidden"); | ||
+ | },first,list); | ||
+ | if(sourceItem!=null){ | ||
+ | v = !JSON.parse(sourceItem.getTag("hide")); | ||
+ | add(v?"Hide":"Unhide",function(){ | ||
+ | LL.runAction(EventHandler.LAUNCHER_MENU); | ||
+ | if(v)LL.getEvent().getContainer().setItemZIndex(sourceItem.getId(),0); | ||
+ | sourceItem.setVisibility(!v); | ||
+ | sourceItem.setTag("hide",v); | ||
+ | LL.runScript("AppDrawer_main",""); | ||
+ | },first,list); | ||
+ | } | ||
+ | add("Reload",function(){ | ||
+ | LL.runAction(EventHandler.LAUNCHER_MENU); | ||
+ | LL.runScript("AppDrawer_main","reload"); | ||
+ | },first,list); | ||
+ | add("Lightning Menu",function(){ | ||
+ | LL.runAction(EventHandler.LAUNCHER_MENU); | ||
+ | if(sourceItem==null) LL.runAction(EventHandler.LAUNCHER_MENU) | ||
+ | else LL.runAction(EventHandler.ITEM_MENU,sourceItem,null); | ||
+ | },first,list); | ||
+ | obs.removeOnGlobalLayoutListener(l); | ||
+ | return true; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | obs.addOnGlobalLayoutListener(l); | ||
+ | LL.runAction(EventHandler.LAUNCHER_MENU); | ||
+ | |||
+ | function add(text,onClickFunction,first,list){ | ||
+ | var t=new Button(LL.getContext()); | ||
+ | if(version >= 16) t.setBackground(first.getBackground().mutate().getConstantState().newDrawable()); | ||
+ | else t.setBackgroundDrawable(first.getBackground().mutate().newDrawable()); | ||
+ | t.setTypeface(first.getTypeface()); | ||
+ | if(version >= 14) t.setAllCaps(false); | ||
+ | t.setTextSize(0,first.getTextSize()); | ||
+ | if(version >= 21) t.setFontFeatureSettings(first.getFontFeatureSettings()); | ||
+ | t.setGravity(first.getGravity()); | ||
+ | t.setText(text); | ||
+ | t.setOnClickListener(new View.OnClickListener(){ | ||
+ | onClick:onClickFunction | ||
+ | }); | ||
+ | list.addView(t); | ||
} | } | ||
- | for(a2=0;a2<ditems.length;a2++) | + | </sxh> |
- | check(ditems.getAt(a2)); | + | </spoiler> |
- | c.setTag(JSON.stringify(db)); | + | <spoiler|Main> |
- | var labels=[]; | + | <sxh javascript;>var TAG = "appdrawer_lukas"; |
- | for(a4=0;a4<db.length;a4++)if(db[a4][1]!=-1)labels.push(LL.getItemById(db[a4][1]).getLabel()); | + | |
- | labels.sort(noCaseSort); | + | |
- | if(rows==0) | + | |
- | for(a5=0;a5<labels.length;a5++) | + | |
- | c.getItemByLabel(labels[a5]).setCell(a5%columns,Math.floor(a5/columns),a5%columns+1,Math.floor(a5/columns)+1); | + | |
- | else | + | |
- | for(a5=0;a5<labels.length;a5++) | + | |
- | c.getItemByLabel(labels[a5]).setCell(a5%columns+columns*Math.floor(a5/(rows*columns)),Math.floor(a5/columns)-rows*Math.floor(a5/(rows*columns)),a5%columns+columns*Math.floor(a5/(rows*columns))+1,Math.floor(a5/columns)-rows*Math.floor(a5/(rows*columns))+1); | + | |
- | LL.save(); | + | |
- | function check(item) | + | var e=LL.getEvent(); |
- | { | + | var c=e.getContainer(); |
- | if(item.getType()=="Folder") | + | var data=JSON.parse(c.getTag(TAG)); |
- | { | + | if(data == null)return; |
- | var fitems=item.getContainer().getItems(); | + | var db=data.db || []; |
- | for(a3=0;a3<fitems.length;a3++) | + | var columns=data.columns; |
- | check(fitems.getAt(a3)); | + | var rows=data.rows; |
- | } | + | var showHidden = (e.getData() == "showHidden"); |
- | else if(item.getTag()!="saved") | + | |
- | { | + | sort(); |
- | var newItem=c.addShortcut(item.getLabel(),item.getIntent(),0,0); | + | |
- | newItem.setDefaultIcon(item.getDefaultIcon()); | + | var initialize = (db.length == 0 || e.getData() == "reload"); |
- | db.push([item.getId(),newItem.getId()]); | + | if(initialize){ |
- | } | + | db = []; |
+ | LL.bindClass("android.app.ProgressDialog"); | ||
+ | var progress = new ProgressDialog(LL.getContext()); | ||
+ | progress.setTitle("Initializing App Drawer") | ||
+ | progress.setMessage("Please wait..."); | ||
+ | progress.setProgressStyle(ProgressDialog.STYLE_SPINNER); | ||
+ | progress.show(); | ||
} | } | ||
+ | setTimeout(function(){ | ||
+ | if(initialize){ | ||
+ | var i=c.getItems(); | ||
+ | for(var a = 0; a < i.length; a++) c.removeItem(i.getAt(a)); | ||
+ | } | ||
+ | for(var a = 0; a < db.length; a++) db[a][2] = false; | ||
- | function resetTag(item) | + | var intent = new Intent(Intent.ACTION_MAIN); |
- | { | + | intent.addCategory(Intent.CATEGORY_LAUNCHER); |
- | if(item.getType()=="Folder") | + | var pm = LL.getContext().getPackageManager(); |
- | { | + | var apps = pm.queryIntentActivities(intent,0); |
- | var fitems=item.getContainer().getItems(); | + | var x = 0; |
- | for(a5=0;a5<fitems.length;a5++) | + | var f = function(){ |
- | resetTag(fitems.getAt(a5)); | + | var app = apps.get(x); |
- | } | + | var name = app.activityInfo.name; |
- | else | + | var pkg = app.activityInfo.packageName; |
- | { | + | for(var b = 0; b < db.length && db[b][1] != name; b++); |
- | item.setTag(null); | + | if(b == db.length) { |
- | } | + | var i = new Intent(intent); |
+ | i.setClassName(pkg, name); | ||
+ | var item = c.addShortcut(app.loadLabel(pm),i,0,0); | ||
+ | item.setName(item.getLabel()); | ||
+ | item.setTag("hide",false); | ||
+ | var bmp = pm.getActivityIcon(i).getBitmap(); | ||
+ | var img = LL.createImage(bmp.getWidth(),bmp.getHeight()); | ||
+ | img.draw().drawBitmap(bmp,0,0,null); | ||
+ | item.setDefaultIcon(img); | ||
+ | item.getProperties().edit().setEventHandler("i.longTap",EventHandler.RUN_SCRIPT,LL.getScriptByName("AppDrawer_menu").getId()).commit(); | ||
+ | db[b] = []; | ||
+ | db[b][0] = item.getId(); | ||
+ | db[b][1] = name; | ||
+ | } | ||
+ | db[b][2] = true; | ||
+ | x++; | ||
+ | if(x<apps.size()) setTimeout(f,0); | ||
+ | else{ | ||
+ | sort(); | ||
+ | if(typeof progress !== 'undefined')progress.dismiss(); | ||
+ | } | ||
+ | }; | ||
+ | setTimeout(f,0); | ||
+ | },100); | ||
+ | |||
+ | function sort(){ | ||
+ | var labels=[]; | ||
+ | for(var a = 0; a < db.length; a++){ | ||
+ | var item=LL.getItemById(db[a][0]); | ||
+ | if(db[a][2]){ | ||
+ | if(showHidden||!JSON.parse(item.getTag("hide")))labels.push(item.getName()); | ||
+ | else item.setVisibility(false); | ||
+ | } | ||
+ | else{ | ||
+ | c.removeItem(item); | ||
+ | db.splice(a,1); | ||
+ | a--; | ||
+ | } | ||
+ | } | ||
+ | data.db = db; | ||
+ | c.setTag(TAG,JSON.stringify(data)); | ||
+ | labels.sort(noCaseSort); | ||
+ | for(var a = 0; a < labels.length; a++){ | ||
+ | var item = c.getItemByName(labels[a]); | ||
+ | item.setVisibility(true); | ||
+ | if(rows==0)item.setCell(a%columns,Math.floor(a/columns),a%columns+1,Math.floor(a/columns)+1); | ||
+ | else item.setCell(a%columns+columns*Math.floor(a/(rows*columns)),Math.floor(a/columns)-rows*Math.floor(a/(rows*columns)),a%columns+columns*Math.floor(a/(rows*columns))+1,Math.floor(a/columns)-rows*Math.floor(a/(rows*columns))+1); | ||
+ | } | ||
+ | c.getItemByName(labels[a]) | ||
+ | LL.save(); | ||
} | } | ||
Line 156: | Line 240: | ||
} | } | ||
</sxh> | </sxh> | ||
+ | </spoiler> |