====== Differences ====== This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
script_shape_background [2017/06/08 08:38] tbog LLPreferenceCheckBox binding missing |
script_shape_background [2017/06/20 18:26] (current) tbog [How to use the script] |
||
|---|---|---|---|
| Line 11: | Line 11: | ||
| - Remember to scroll (if the preview image is too big) for the buttons | - Remember to scroll (if the preview image is too big) for the buttons | ||
| - | Known issue: for arcs you can't define the start and sweep angles | + | Known issue: can't import an exported string |
| ====== Script code ====== | ====== Script code ====== | ||
| <sxh javascript> | <sxh javascript> | ||
| - | // v1.0 | + | // v1.1.test6 |
| function DrawData() | function DrawData() | ||
| { | { | ||
| Line 26: | Line 26: | ||
| OVAL: 2, | OVAL: 2, | ||
| ARC: 3, | ARC: 3, | ||
| + | ROUND_RECT: 4, | ||
| properties: { | properties: { | ||
| 1: {name: 'Rectangle'}, | 1: {name: 'Rectangle'}, | ||
| 2: {name: 'Oval'}, | 2: {name: 'Oval'}, | ||
| 3: {name: 'Arc'}, | 3: {name: 'Arc'}, | ||
| + | 4: {name: 'Round rectangle'}, | ||
| }, | }, | ||
| findByName: function( name ) | findByName: function( name ) | ||
| Line 36: | Line 38: | ||
| { | { | ||
| if ( enumShapeType.properties[key].name == name ) | if ( enumShapeType.properties[key].name == name ) | ||
| - | return key; | + | return parseInt(key); |
| } | } | ||
| - | return enumShapeType.RECTANGLE; | + | return enumShapeType.RECTANGLE; // should never happen |
| }, | }, | ||
| getNameArr: function() | getNameArr: function() | ||
| Line 44: | Line 46: | ||
| return [ | return [ | ||
| enumShapeType.properties[enumShapeType.RECTANGLE].name, | enumShapeType.properties[enumShapeType.RECTANGLE].name, | ||
| + | enumShapeType.properties[enumShapeType.ROUND_RECT].name, | ||
| enumShapeType.properties[enumShapeType.OVAL].name, | enumShapeType.properties[enumShapeType.OVAL].name, | ||
| enumShapeType.properties[enumShapeType.ARC].name | enumShapeType.properties[enumShapeType.ARC].name | ||
| Line 50: | Line 53: | ||
| getIdx: function( shapeType ) | getIdx: function( shapeType ) | ||
| { | { | ||
| - | return shapeType - 1; // TODO: search in getNameArr | + | var arr = this.getNameArr(); |
| + | for ( var i = 0; i < arr.length; i+= 1 ) | ||
| + | if ( shapeType == this.findByName(arr[i]) ) | ||
| + | return i; | ||
| + | return 0; // should never happen | ||
| } | } | ||
| }; | }; | ||
| Line 63: | Line 70: | ||
| this.offsetY = 0; | this.offsetY = 0; | ||
| this.fill = true; | this.fill = true; | ||
| + | // for arc | ||
| + | this.startAngle = 270; | ||
| + | this.sweepAngle = 45; | ||
| + | // for round corners | ||
| + | this.cornerX = 10; | ||
| + | this.cornerY = 20; | ||
| + | |||
| + | this.validate = function( c ) | ||
| + | { | ||
| + | // if not all properties found, copy them to "c" | ||
| + | for( var prop in this ) | ||
| + | { | ||
| + | if ( (typeof this[prop] == 'boolean') || (typeof this[prop] == 'number') || (typeof this[prop] == 'string') ) | ||
| + | { | ||
| + | if ( (typeof c[prop] == 'undefined') || (typeof c[prop] == 'object') ) | ||
| + | c[prop] = this[prop]; | ||
| + | } | ||
| + | } | ||
| + | if ( c.width < 0 ) | ||
| + | c.width = this.width; | ||
| + | if ( c.height < 0 ) | ||
| + | c.height = this.height; | ||
| + | }; | ||
| } | } | ||
| function empty( mixedVar ) | function empty( mixedVar ) | ||
| Line 111: | Line 141: | ||
| case enumShapeType.RECTANGLE: | case enumShapeType.RECTANGLE: | ||
| canvas.drawRect( shapeInfo.offsetX, shapeInfo.offsetY, shapeInfo.offsetX + shapeWidth, shapeInfo.offsetY + shapeHeight, paint ); | canvas.drawRect( shapeInfo.offsetX, shapeInfo.offsetY, shapeInfo.offsetX + shapeWidth, shapeInfo.offsetY + shapeHeight, paint ); | ||
| - | break; | + | break; |
| case enumShapeType.OVAL: | case enumShapeType.OVAL: | ||
| canvas.drawOval( shapeInfo.offsetX, shapeInfo.offsetY, shapeInfo.offsetX + shapeWidth, shapeInfo.offsetY + shapeHeight, paint ); | canvas.drawOval( shapeInfo.offsetX, shapeInfo.offsetY, shapeInfo.offsetX + shapeWidth, shapeInfo.offsetY + shapeHeight, paint ); | ||
| - | break; | + | break; |
| case enumShapeType.ARC: | case enumShapeType.ARC: | ||
| - | canvas.drawArc( shapeInfo.offsetX, shapeInfo.offsetY, shapeInfo.offsetX + shapeWidth, shapeInfo.offsetY + shapeHeight, -90, 45, true, paint ); | + | canvas.drawArc( shapeInfo.offsetX, shapeInfo.offsetY, shapeInfo.offsetX + shapeWidth, shapeInfo.offsetY + shapeHeight, shapeInfo.startAngle, shapeInfo.sweepAngle, true, paint ); |
| - | break; | + | break; |
| + | case enumShapeType.ROUND_RECT: | ||
| + | canvas.drawRoundRect( shapeInfo.offsetX, shapeInfo.offsetY, shapeInfo.offsetX + shapeWidth, shapeInfo.offsetY + shapeHeight, shapeInfo.cornerX, shapeInfo.cornerY, paint ); | ||
| + | break; | ||
| default: | default: | ||
| - | alert('Unknown shape type "' + shapeInfo.type + '"'); | + | Android.makeNewToast( 'Unknown shape type "' + shapeInfo.type + '"', true ).show(); |
| } | } | ||
| } | } | ||
| Line 147: | Line 180: | ||
| } | } | ||
| g_cache.itemId = item.getId(); | g_cache.itemId = item.getId(); | ||
| + | |||
| + | // hack to initialize with item size | ||
| if ( g_cache.data.width <= 0 ) | if ( g_cache.data.width <= 0 ) | ||
| g_cache.data.width = item.getWidth(); | g_cache.data.width = item.getWidth(); | ||
| if ( g_cache.data.height <= 0 ) | if ( g_cache.data.height <= 0 ) | ||
| g_cache.data.height = item.getHeight(); | g_cache.data.height = item.getHeight(); | ||
| + | |||
| + | // validate shapes | ||
| + | var defaultShape = new ShapeInfo(); | ||
| + | defaultShape.width = g_cache.data.width; | ||
| + | defaultShape.height = g_cache.data.height; | ||
| + | for ( var i = 0; i < g_cache.data.shapeArr.length; i+= 1 ) | ||
| + | { | ||
| + | defaultShape.validate( g_cache.data.shapeArr[i] ); | ||
| + | } | ||
| return g_cache.data; | return g_cache.data; | ||
| } | } | ||
| Line 188: | Line 232: | ||
| var prefOffX = new LLPreferenceSlider(0, 'Offset X', 'pixel', shapeInfo.offsetX, 0, 'INT', 0, 512, 1, 'px'); | var prefOffX = new LLPreferenceSlider(0, 'Offset X', 'pixel', shapeInfo.offsetX, 0, 'INT', 0, 512, 1, 'px'); | ||
| var prefOffY = new LLPreferenceSlider(0, 'Offset Y', 'pixel', shapeInfo.offsetY, 0, 'INT', 0, 512, 1, 'px'); | var prefOffY = new LLPreferenceSlider(0, 'Offset Y', 'pixel', shapeInfo.offsetY, 0, 'INT', 0, 512, 1, 'px'); | ||
| + | var prefCornerRadX = new LLPreferenceSlider(0, 'Corner radius X', 'pixel', shapeInfo.cornerX, 0, 'INT', 0, 512, 1, 'px'); | ||
| + | var prefCornerRadY = new LLPreferenceSlider(0, 'Corner radius Y', 'pixel', shapeInfo.cornerY, 0, 'INT', 0, 512, 1, 'px'); | ||
| + | var prefStartAng = new LLPreferenceSlider(0, 'Start angle', 'degree', shapeInfo.startAngle, 0, 'INT', 0, 360, 1, 'deg'); | ||
| + | var prefSweepAng = new LLPreferenceSlider(0, 'Sweep angle', 'degree', shapeInfo.sweepAngle, 0, 'INT', 0, 360, 1, 'deg'); | ||
| var prefFill = new LLPreferenceCheckBox( 0, 'Fill', null, shapeInfo.fill, null ); | var prefFill = new LLPreferenceCheckBox( 0, 'Fill', null, shapeInfo.fill, null ); | ||
| - | + | ||
| var prefList = new LLPreferenceListView( ctxTheme, null ); | var prefList = new LLPreferenceListView( ctxTheme, null ); | ||
| prefList.setCompactMode(true); | prefList.setCompactMode(true); | ||
| + | var prefListener = | ||
| + | { | ||
| + | onLLPreferenceChanged: function( pref ) | ||
| + | { | ||
| + | if ( pref == prefType ) | ||
| + | { | ||
| + | var type = enumShapeType.findByName( prefType.getLabels()[prefType.getValueIndex()] ); | ||
| + | switch ( type ) | ||
| + | { | ||
| + | case enumShapeType.RECTANGLE: | ||
| + | case enumShapeType.OVAL: | ||
| + | prefStartAng.setVisible(false); | ||
| + | prefSweepAng.setVisible(false); | ||
| + | |||
| + | prefCornerRadX.setVisible(false); | ||
| + | prefCornerRadY.setVisible(false); | ||
| + | break; | ||
| + | case enumShapeType.ARC: | ||
| + | prefStartAng.setVisible(true); | ||
| + | prefSweepAng.setVisible(true); | ||
| + | |||
| + | prefCornerRadX.setVisible(false); | ||
| + | prefCornerRadY.setVisible(false); | ||
| + | break; | ||
| + | case enumShapeType.ROUND_RECT: | ||
| + | prefStartAng.setVisible(false); | ||
| + | prefSweepAng.setVisible(false); | ||
| + | |||
| + | prefCornerRadX.setVisible(true); | ||
| + | prefCornerRadY.setVisible(true); | ||
| + | break; | ||
| + | } | ||
| + | prefList.refresh(); | ||
| + | } | ||
| + | }, | ||
| + | onLLPreferenceClicked: function( pref ) | ||
| + | { | ||
| + | }, | ||
| + | onLLPreferenceLongClicked: function( pref ) | ||
| + | { | ||
| + | } | ||
| + | }; | ||
| + | prefList.setListener( prefListener ); | ||
| + | |||
| prefList.setPreferences( [ | prefList.setPreferences( [ | ||
| prefName, | prefName, | ||
| Line 200: | Line 292: | ||
| prefOffX, | prefOffX, | ||
| prefOffY, | prefOffY, | ||
| + | prefCornerRadX, | ||
| + | prefCornerRadY, | ||
| + | prefStartAng, | ||
| + | prefSweepAng, | ||
| prefFill | prefFill | ||
| ] ); | ] ); | ||
| + | prefListener.onLLPreferenceChanged( prefType ); | ||
| builder.setView( prefList ); | builder.setView( prefList ); | ||
| Line 231: | Line 328: | ||
| shapeInfo.offsetY = prefOffY.getValue(); | shapeInfo.offsetY = prefOffY.getValue(); | ||
| shapeInfo.fill = prefFill.isChecked(); | shapeInfo.fill = prefFill.isChecked(); | ||
| + | shapeInfo.startAngle = prefStartAng.getValue(); | ||
| + | shapeInfo.sweepAngle = prefSweepAng.getValue(); | ||
| + | shapeInfo.cornerX = prefCornerRadX.getValue(); | ||
| + | shapeInfo.cornerY = prefCornerRadY.getValue(); | ||
| setDrawData( item, drawData ); | setDrawData( item, drawData ); | ||
| Line 249: | Line 350: | ||
| bindClass( 'android.view.View' ); | bindClass( 'android.view.View' ); | ||
| bindClass( 'android.view.ViewGroup' ); | bindClass( 'android.view.ViewGroup' ); | ||
| - | bindClass( 'android.view.ContextThemeWrapper' ); | ||
| bindClass( 'android.view.ViewGroup.LayoutParams' ); | bindClass( 'android.view.ViewGroup.LayoutParams' ); | ||
| + | bindClass( 'android.view.ContextThemeWrapper' ); | ||
| bindClass( 'android.widget.ListView' ); | bindClass( 'android.widget.ListView' ); | ||
| bindClass( 'android.widget.LinearLayout' ); | bindClass( 'android.widget.LinearLayout' ); | ||
| Line 383: | Line 484: | ||
| editHeight.setInputType( InputType.TYPE_CLASS_NUMBER ); | editHeight.setInputType( InputType.TYPE_CLASS_NUMBER ); | ||
| + | linearView.addView( shapeInfoLayout = new LinearLayout( ctxTheme ) ); | ||
| var btn; | var btn; | ||
| - | linearView.addView( btn = new Button( ctxTheme ) ); | + | shapeInfoLayout.addView( btn = new Button( ctxTheme ) ); |
| btn.setAllCaps( false ); | btn.setAllCaps( false ); | ||
| - | btn.setText( 'Save size' ); | + | btn.setText( 'Set size' ); |
| btn.setOnClickListener( new View.OnClickListener() | btn.setOnClickListener( new View.OnClickListener() | ||
| { | { | ||
| Line 397: | Line 499: | ||
| setDrawData( item, drawData ); | setDrawData( item, drawData ); | ||
| + | dialog.dismiss(); | ||
| + | var time = setTimeout(function(){clearTimeout(time); showShapeMenu(item);}, 0); | ||
| + | } | ||
| + | }); | ||
| + | shapeInfoLayout.addView( btn = new Button( ctxTheme ) ); | ||
| + | btn.setAllCaps( false ); | ||
| + | btn.setText( 'Reset size' ); | ||
| + | btn.setOnClickListener( new View.OnClickListener() | ||
| + | { | ||
| + | onClick: function( view ) | ||
| + | { | ||
| + | var drawData = getDrawData( item ); | ||
| + | |||
| + | drawData.width = item.getWidth(); | ||
| + | drawData.height = item.getHeight(); | ||
| + | |||
| + | setDrawData( item, drawData ); | ||
| + | dialog.dismiss(); | ||
| var time = setTimeout(function(){clearTimeout(time); showShapeMenu(item);}, 0); | var time = setTimeout(function(){clearTimeout(time); showShapeMenu(item);}, 0); | ||
| } | } | ||
| Line 471: | Line 591: | ||
| img.update(); | img.update(); | ||
| item.setBoxBackground( img, 'nsf', true ); | item.setBoxBackground( img, 'nsf', true ); | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | linearView.addView( btn = new Button( ctxTheme ) ); | ||
| + | btn.setAllCaps( false ); | ||
| + | btn.setText( 'Export to string' ); | ||
| + | btn.setOnClickListener( new View.OnClickListener() | ||
| + | { | ||
| + | onClick: function( view ) | ||
| + | { | ||
| + | var drawData = getDrawData( item ); | ||
| + | var text = JSON.stringify(drawData); | ||
| + | var ctx = getActiveScreen().getContext(); | ||
| + | //bindClass( 'android.content.Context' ); | ||
| + | bindClass( 'android.content.ClipboardManager' ); | ||
| + | bindClass( 'android.content.ClipData' ); | ||
| + | var clipboard = ctx.getSystemService(Context.CLIPBOARD_SERVICE); | ||
| + | var clip = ClipData.newPlainText('shape export', text); | ||
| + | clipboard.setPrimaryClip(clip); | ||
| + | Android.makeNewToast('Shape data exported to clipboard.', true).show(); | ||
| } | } | ||
| }); | }); | ||