User Tools

Site Tools


script_8wheel

====== About the script ====== * Purpose : Make all items in a container animate on a figure 8 when scrolling left and right * Author : TBog * Link: www.google.com/+BogdanTautuTBog ====== How to use the script ====== Still in development, but the main feature will be that everything will be customizable with an internal GUI - Set the script in the category "Lightning menu" then long-press on any container (panel was tested) and run the script. - A dialog will appear that will guide you further. Known issue: while the script is running if user enters edit mode an error will appear. ====== Script code ====== <sxh javascript> // v0.1 function empty( mixedVar ) { /*discuss at: http://locutus.io/php/empty/ */ var undef, key, i, len; var emptyValues = [undef, null, false, 0, '', '0']; for ( i = 0, len = emptyValues.length; i < len; i++ ) { if ( mixedVar === emptyValues[i] ) { return true; } } if ( typeof mixedVar === 'object' ) { for ( key in mixedVar ) { if ( Object.hasOwnProperty.call(mixedVar, key) ) { return false; } } return true; } return false; } function getWheelItems( container ) { var items = container.getAllItems(); var a = []; var na = 0; for ( var i = items.length - 1; i >= 0; i -= 1 ) { var item = items[i]; var type = item.getType(); // we are only interested in shortcuts and folders if ( type != 'Shortcut' && type != 'Folder' ) { continue; } a[na++] = item; } return a; } function isConfigItemName( name ) { if ( empty(name) ) return false; if ( name.indexOf( '8w_config' ) != -1 ) return true; if ( name.indexOf( '8w_setup' ) != -1 ) return true; return false; } function getConfigItems( container ) { var items = container.getAllItems(); var arrConfigItems = []; for ( var i = 0; i < items.length; i += 1 ) { var name = items[i].getName(); if ( isConfigItemName(name) ) { arrConfigItems.push( items[i] ); } } return arrConfigItems; } function filterConfigItems( items ) { for ( var i = 0; i < items.length; i += 1 ) { var name = items[i].getName(); if ( isConfigItemName(name) ) { // remove from list items.splice( i--, 1 ); } } return items; } function cubicBezier( p0, p1, p2, p3, t ) { return ( 1 - t ) * ( 1 - t ) * ( 1 - t ) * p0 + 3 * ( 1 - t ) * ( 1 - t ) * t * p1 + 3 * ( 1 - t ) * t * t * p2 + t * t * t * p3; } function scaleAnim( t ) { return cubicBezier( 1, 0, 1, 0, t ); } function showConfigMenu( container ) { bindClass( 'android.app.AlertDialog' ); bindClass( 'net.pierrox.lightning_launcher.prefs.LLPreferenceListView' ); bindClass( 'net.pierrox.lightning_launcher.prefs.LLPreferenceCheckBox' ); var ctx = getActiveScreen().getContext(); var prefColorize = new LLPreferenceCheckBox( 0, 'Colorize', 'desaturate items', true, null ); var listView = new LLPreferenceListView( ctx, null ); listView.setPreferences( [prefColorize] ); var builder = new AlertDialog.Builder( ctx ); builder.setView( listView ); builder.setTitle( '8wheel settings' ); builder.setPositiveButton( 'Save', { onClick: function( dialog, id ) { dialog.dismiss(); } } ); builder.setNegativeButton( 'Cancel', null ); builder.show(); } function createScriptShortcut( container ) { var scriptId = getCurrentScript().getId(); var intent = Intent.parseUri("#Intent;component=net.pierrox.lightning_launcher_extreme/net.pierrox.lightning_launcher.activities.Dashboard;i.a=35;S.d="+scriptId+";end",0); if ( empty(intent) ) return false; return container.addShortcut('8wheel', intent, 0, 0); } function showSetupMenu( container ) { bindClass( 'android.app.AlertDialog' ); bindClass( 'android.content.DialogInterface' ); bindClass( 'android.text.Html' ); bindClass( 'android.view.View' ); bindClass( 'android.view.ContextThemeWrapper' ); bindClass( 'android.widget.ListView' ); bindClass( 'android.widget.LinearLayout' ); bindClass( 'android.widget.ScrollView' ); bindClass( 'android.widget.TextView' ); bindClass( 'android.widget.Button' ); bindClass( 'android.R' ); var ctx = getActiveScreen().getContext(); var builder = new AlertDialog.Builder( ctx, R.style.Theme_Material_Dialog ); var ctxTheme = new ContextThemeWrapper( ctx, R.style.Theme_Material_Dialog ); var rootView = new ScrollView( ctxTheme ); var linearView = new LinearLayout( ctxTheme ); linearView.setOrientation( LinearLayout.VERTICAL ); linearView.setShowDividers( LinearLayout.SHOW_DIVIDER_MIDDLE ); linearView.setDividerDrawable( ctx.getResources().getDrawable(R.drawable.divider_horizontal_textfield) ); var textView = new TextView( ctxTheme ); textView.setText( "Do not edit the container after the 8wheel is setup; use this dialog to stop the script first" ); linearView.addView( textView ); var btn = new Button( ctxTheme ); btn.setAllCaps( false ); var hex = Number(container.getId()).toString(16); hex = "000000".substr(0, 6 - hex.length) + hex; btn.setText( 'Setup 8wheel in container #' + hex ); btn.setOnClickListener( new View.OnClickListener() { onClick: function( view ) { var html = []; var a = getWheelItems( container ); var na = a.length; html.push( 'Found <b>', na, '</b> items' ); a = filterConfigItems( a ); var nConfigItems = 0; if ( a.length != na ) { nConfigItems = na - a.length; html.push( '<br>', 'Found <b>', nConfigItems, '</b> config items' ); na = a.length; } if ( na < 5 ) { alert('Only found ' + na + ' item(s).\nAdd more shortcuts and/or folders and try again.'); return; } var nPinned = 0; var nDetached = 0; for ( var i = 0; i < na; i+= 1 ) { var prop = a[i].getProperties(); var pinMode = prop.getString( 'i.pinMode' ); /*NONE|XY|X|Y*/ if ( pinMode.indexOf( 'X' ) == -1 ) { prop.edit().setString( 'i.pinMode', 'X' ).commit(); nPinned+= 1; } var onGrid = prop.getBoolean( 'i.onGrid' ); if ( onGrid ) { prop.edit().setBoolean( 'i.onGrid', false ).commit(); nDetached+= 1; } } html.push( '<br>', 'Pinned <b>', nPinned, '</b> items', '<br>', 'Detached from grid <b>', nDetached, '</b> items' ); var itemConfig, itemSetup; var aCfgBtns = getConfigItems( container ); for ( var i = 0; i < aCfgBtns.length; i+= 1 ) { switch( aCfgBtns[i].getName() ) { case '8w_config': itemConfig = aCfgBtns[i]; break; case '8w_setup': itemSetup = aCfgBtns[i]; break; } } // the lists become invalid after we create new items aCfgBtns = []; a = []; na = 0; if ( empty(itemConfig) ) { var item = createScriptShortcut( container ); if ( empty(item) ) { html.push( '<br>', '<b>8wheel config</b> button not found and can\'t be created' ); } else { item.setName('8w_config'); item.getProperties().edit() .setString('s.label', '<b>8wheel</b> config') .setString( 'i.pinMode', 'X' ) .setBoolean( 'i.onGrid', false ) .commit(); item.setPosition(0, container.getHeight() - item.getHeight()); html.push( '<br>', '<b>8wheel config</b> button created' ); } } else { html.push( '<br>', '<b>8wheel config</b> button found' ); } if ( empty(itemSetup) ) { var item = createScriptShortcut( container ); if ( empty(item) ) { html.push( '<br>', '<b>8wheel setup</b> button not found and can\'t be created' ); } else { item.setName('8w_setup'); item.getProperties().edit() .setString('s.label', '<b>8wheel</b> setup') .setString( 'i.pinMode', 'X' ) .setBoolean( 'i.onGrid', false ) .commit(); item.setPosition(container.getWidth() - item.getWidth(), container.getHeight() - item.getHeight()); html.push( '<br>', '<b>8wheel setup</b> button created' ); } } else { html.push( '<br>', '<b>8wheel setup</b> button found' ); } var containerPropEditor = container.getProperties().edit(); containerPropEditor.setEventHandler('posChanged', EventHandler.RUN_SCRIPT, getCurrentScript().getId()); containerPropEditor.commit(); save(); var label = new TextView( ctxTheme ); label.setText( Html.fromHtml(html.join('')) ); view.getParent().addView(label, view.getParent().indexOfChild(view) + 1); } } ); linearView.addView( btn ); btn = new Button( ctxTheme ); btn.setAllCaps( false ); btn.setText( 'Stop 8wheel in container #' + hex ); btn.setOnClickListener( new View.OnClickListener() { onClick: function( view ) { var aCfgBtns = getConfigItems( container ); for ( var i = 0; i < aCfgBtns.length; i+= 1 ) { container.removeItem( aCfgBtns[i] ); } container.getProperties().edit() .setEventHandler('posChanged', EventHandler.NOTHING, '') .setBoolean( 'rearrangeItems', false ) .commit(); var a = getWheelItems( container ); for ( var i = 0; i < a.length; i+= 1 ) { try { a[i].setScale( 1, 1 ); } catch (Exception) { // ignore } a[i].setVisibility( true ); a[i].getProperties().edit() .setInteger( 'i.alpha', 0xff ) .setInteger( 's.iconColorFilter', 0xFFffffff ) .setInteger( 's.labelFontColor', 0xFFffffff ) .setString( 'i.pinMode', 'NONE' ) .setBoolean( 'i.onGrid', true ) .commit(); a[i].setCell(i, 0, i + 1, 1); } save(); } } ); linearView.addView( btn ); var linearViewShowHideShortcuts = new LinearLayout( ctxTheme ); linearViewShowHideShortcuts.setOrientation( LinearLayout.VERTICAL ); var linearViewHorizontal = new LinearLayout( ctxTheme ); linearViewHorizontal.setOrientation( LinearLayout.HORIZONTAL ); textView = new TextView( ctxTheme ); textView.setText( Html.fromHtml('Configure <b>Setup</b> and <b>Config</b> shortcuts') ); linearViewShowHideShortcuts.addView( textView ); btn = new Button( ctxTheme ); btn.setAllCaps( false ); btn.setText( 'Show' ); btn.setOnClickListener( new View.OnClickListener() { onClick: function( view ) { var txt = view.getText().toString().split("\n", 1); var items = getConfigItems( container ); for ( var i = 0; i < items.length; i+= 1 ) { var item = items[i]; item.setVisibility( true ); } Android.makeNewToast( Html.fromHtml('<b>Setup</b> and <b>Config</b> shortcuts are now visible'), true ).show(); } } ); linearViewHorizontal.addView( btn ); btn = new Button( ctxTheme ); btn.setAllCaps( false ); btn.setText( 'Hide' ); btn.setOnClickListener( new View.OnClickListener() { onClick: function( view ) { var txt = view.getText().toString().split("\n", 1); var items = getConfigItems( container ); for ( var i = 0; i < items.length; i+= 1 ) { var item = items[i]; item.setVisibility( false ); } Android.makeNewToast( Html.fromHtml('<b>Setup</b> and <b>Config</b> shortcuts are now hidden'), true ).show(); } } ); linearViewHorizontal.addView( btn ); linearViewShowHideShortcuts.addView( linearViewHorizontal ); linearView.addView( linearViewShowHideShortcuts ); rootView.addView( linearView ); builder.setView( rootView ); builder.setCancelable( true ); builder.setTitle( '8wheel setup' ); builder.setNeutralButton( 'Close', { onClick: function( dialog, id ) { dialog.dismiss(); } } ); var dialog = builder.create(); dialog.setOnShowListener( new DialogInterface.OnShowListener() { onShow:function() { rootView.scrollTo(0,0); } } ); dialog.show(); } function updatePosition(container, offsetScroll) { var a = getWheelItems( container ); a = filterConfigItems( a ); var na = a.length; var x, y, pos, scale; var w2 = container.getWidth() / 2; var h2 = container.getHeight() / 2; var radius = Math.min( w2, h2 ) * 0.5; var sizeRef = radius; for ( var i = 0; i < na; i += 1 ) { pos = i / na + offsetScroll; /* compute modulo 1 */ pos = pos - Math.floor( pos ); scale = 0; if ( pos <= 0.5 ) { scale += pos * 2; /*make scale 0..1*/ var p = pos * 2; x = Math.cos( Math.PI * 2 * p - Math.PI / 2 ) * radius; y = Math.sin( Math.PI * 2 * p - Math.PI / 2 ) * radius + radius; } else { scale += ( 1 - pos ) * 2; /*make scale 1..0*/ var p = ( pos - 0.5 ) * -2; x = Math.cos( Math.PI * 2 * p + Math.PI / 2 ) * radius; y = Math.sin( Math.PI * 2 * p + Math.PI / 2 ) * radius - radius; } scale = scaleAnim( scale ); var alpha = scale < fadeEnd ? 0 : ( scale < fadeStart ? ( ( scale - fadeEnd ) / ( fadeStart - fadeEnd ) ) : 1 ); var colorize = scale < colorizeEnd ? colorizeEndValue : ( scale < colorizeStart ? ( ( scale - colorizeEnd ) / ( colorizeStart - colorizeEnd ) * ( colorizeStartValue - colorizeEndValue ) + colorizeEndValue ) : colorizeStartValue ); colorize = Math.round( colorize * 255 ) << 24; var labelColor = colorize | 0xffffff; /*var shadowColor = colorize|0xff000000;*/ colorize = colorize | 0xffffff; alpha = Math.round( alpha * 255 ); a[i].setVisibility( alpha > 0 ); a[i].getProperties().edit().setInteger( 'i.alpha', alpha ).setInteger( 's.iconColorFilter', colorize ).setInteger( 's.labelFontColor', labelColor ) /*.setInteger('s.labelShadowColor',shadowColor)*/ .commit(); scale *= 1.5; x += w2; y += h2; try { a[i].setScale( scale, scale ); } catch (Exception) { // probably edit mode return; } x -= a[i].getWidth() / 2 * scale; y -= a[i].getHeight() / 2 * scale; a[i].setPosition( x, y ); } } /*Start of config area (Default values)*/ var fadeStart = 0.47; var fadeEnd = 0.35; var colorizeStart = 0.9; var colorizeStartValue = 1; var colorizeEnd = 0.7; var colorizeEndValue = 0.1; /*End of config area*/ var event = getEvent(); switch ( event.getSource() ) { case 'MENU_APP': showSetupMenu( event.getContainer() ); return; case 'I_CLICK': case 'SHORTCUT': { var btn = event.getItem(); switch ( btn.getName() ) { case '8w_config': showConfigMenu( btn.getParent() ); return; case '8w_setup': showSetupMenu( btn.getParent() ); } return; } case 'C_POSITION_CHANGED': { var container = event.getContainer(); var offsetScroll = container.getPositionX() / container.getWidth() * 0.5; updatePosition(container, offsetScroll); return; } default: alert( 'unknown event source ' + event.getSource() ); return; } </sxh>

script_8wheel.txt · Last modified: 2017/05/18 12:27 by tbog