commit da768c3534b1957a32b2518c63efce2f4c80ed31
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Sep 29 14:19:28 2020 +0100

    Transparent Buttons.

diff --git a/src/main/java/org/distorted/states/RubikStateAbstract.java b/src/main/java/org/distorted/states/RubikStateAbstract.java
index 4c420246..a0362d90 100644
--- a/src/main/java/org/distorted/states/RubikStateAbstract.java
+++ b/src/main/java/org/distorted/states/RubikStateAbstract.java
@@ -19,13 +19,71 @@
 
 package org.distorted.states;
 
+import android.annotation.SuppressLint;
 import android.content.SharedPreferences;
+import android.util.TypedValue;
+import android.widget.LinearLayout;
+
 import org.distorted.main.RubikActivity;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public abstract class RubikStateAbstract
   {
+  @SuppressLint("ViewConstructor")
+  static class TransparentImageButton extends androidx.appcompat.widget.AppCompatImageButton
+    {
+    public TransparentImageButton(RubikActivity act, int icon, float scrWidth, int butWidth)
+      {
+      super(act);
+
+      final int padding = (int)(scrWidth*RubikActivity.PADDING);
+      final int margin  = (int)(scrWidth*RubikActivity.MARGIN);
+
+      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(butWidth,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
+
+      params.topMargin    = margin;
+      params.bottomMargin = margin;
+      params.leftMargin   = margin;
+      params.rightMargin  = margin;
+
+      setLayoutParams(params);
+      setPadding(padding,0,padding,0);
+      setImageResource(icon);
+
+      TypedValue outValue = new TypedValue();
+      act.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, outValue, true);
+      setBackgroundResource(outValue.resourceId);
+      }
+    }
+
+  @SuppressLint("ViewConstructor")
+  static class TransparentButton extends androidx.appcompat.widget.AppCompatButton
+    {
+    public TransparentButton(RubikActivity act, int resId, float size, float scrWidth)
+      {
+      super(act);
+
+      final int padding = (int)(scrWidth*RubikActivity.PADDING);
+      final int margin  = (int)(scrWidth*RubikActivity.MARGIN);
+
+      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
+      params.topMargin    = margin;
+      params.bottomMargin = margin;
+      params.leftMargin   = margin;
+      params.rightMargin  = margin;
+
+      setLayoutParams(params);
+      setPadding(padding,0,padding,0);
+      setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
+      setText(resId);
+
+      TypedValue outValue = new TypedValue();
+      act.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, outValue, true);
+      setBackgroundResource(outValue.resourceId);
+      }
+    }
+
   abstract void enterState(RubikActivity act);
   abstract void leaveState(RubikActivity act);
   public abstract void savePreferences(SharedPreferences.Editor editor);
diff --git a/src/main/java/org/distorted/states/RubikStateDone.java b/src/main/java/org/distorted/states/RubikStateDone.java
index b9e06ac4..edaf15b2 100644
--- a/src/main/java/org/distorted/states/RubikStateDone.java
+++ b/src/main/java/org/distorted/states/RubikStateDone.java
@@ -38,6 +38,10 @@ import org.distorted.main.RubikActivity;
 
 public class RubikStateDone extends RubikStateAbstract
   {
+  private ImageButton mBackButton;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
   void leaveState(RubikActivity act)
     {
 
@@ -72,35 +76,35 @@ public class RubikStateDone extends RubikStateAbstract
     LinearLayout layoutRight = new LinearLayout(act);
     layoutRight.setLayoutParams(paramsR);
 
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
+    setupBackButton(act,width);
 
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
+    layoutRight.addView(mBackButton);
+    layoutBot.addView(layoutLeft);
+    layoutBot.addView(layoutRight);
+    }
 
-    final int icon = RubikActivity.getDrawable(R.drawable.ui_small_back,R.drawable.ui_medium_back, R.drawable.ui_big_back, R.drawable.ui_huge_back);
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    ImageButton back = new ImageButton(act);
-    back.setLayoutParams(params);
-    back.setPadding(padding,0,padding,0);
-    back.setImageResource(icon);
+  private void setupBackButton(final RubikActivity act, final float width)
+    {
+    int icon = RubikActivity.getDrawable(R.drawable.ui_small_back,R.drawable.ui_medium_back, R.drawable.ui_big_back, R.drawable.ui_huge_back);
+    mBackButton = new TransparentImageButton(act, icon, width, LinearLayout.LayoutParams.MATCH_PARENT);
 
-    back.setOnClickListener( new View.OnClickListener()
+    mBackButton.setOnClickListener( new View.OnClickListener()
       {
       @Override
       public void onClick(View v)
         {
         StateList.goBack(act);
-        dismissDialogs(act);
+
+        FragmentManager mana = act.getSupportFragmentManager();
+        RubikDialogNewRecord diag1 = (RubikDialogNewRecord) mana.findFragmentByTag(RubikDialogNewRecord.getDialogTag());
+        RubikDialogSolved    diag2 = (RubikDialogSolved   ) mana.findFragmentByTag(RubikDialogSolved.getDialogTag());
+
+        if( diag1 !=null ) diag1.dismiss();
+        if( diag2 !=null ) diag2.dismiss();
         }
       });
-
-    layoutRight.addView(back);
-    layoutBot.addView(layoutLeft);
-    layoutBot.addView(layoutRight);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -116,16 +120,4 @@ public class RubikStateDone extends RubikStateAbstract
     {
 
     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void dismissDialogs(RubikActivity act)
-    {
-    FragmentManager mana = act.getSupportFragmentManager();
-    RubikDialogNewRecord diag1 = (RubikDialogNewRecord) mana.findFragmentByTag(RubikDialogNewRecord.getDialogTag());
-    RubikDialogSolved    diag2 = (RubikDialogSolved   ) mana.findFragmentByTag(RubikDialogSolved.getDialogTag());
-
-    if( diag1 !=null ) diag1.dismiss();
-    if( diag2 !=null ) diag2.dismiss();
-    }
   }
diff --git a/src/main/java/org/distorted/states/RubikStatePattern.java b/src/main/java/org/distorted/states/RubikStatePattern.java
index 5abbd2b6..d115adcc 100644
--- a/src/main/java/org/distorted/states/RubikStatePattern.java
+++ b/src/main/java/org/distorted/states/RubikStatePattern.java
@@ -47,7 +47,7 @@ public class RubikStatePattern extends RubikStateAbstract
   private TextView mMovesText;
   private int mNumMoves;
   private int mPatternOrdinal, mCategory, mPattern;
-  private float mButtonSize, mTitleSize;
+  private float mButtonSize;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -80,7 +80,7 @@ public class RubikStatePattern extends RubikStateAbstract
     {
     float width = act.getScreenWidthInPixels();
     mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
-    mTitleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
+    float titleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
 
     RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
     int obj  = play.getObject();
@@ -104,7 +104,7 @@ public class RubikStatePattern extends RubikStateAbstract
     LinearLayout layoutTop = act.findViewById(R.id.upperBar);
     layoutTop.removeAllViews();
     mText = (TextView)inflater.inflate(R.layout.upper_pattern_text, null);
-    mText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTitleSize);
+    mText.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize);
     mText.setText(R.string.patterns);
     layoutTop.addView(mText);
 
@@ -168,21 +168,8 @@ public class RubikStatePattern extends RubikStateAbstract
 
   private void setupBackButton(final RubikActivity act, final float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
     final int icon = RubikActivity.getDrawable(R.drawable.ui_small_back,R.drawable.ui_medium_back, R.drawable.ui_big_back, R.drawable.ui_huge_back);
-
-    mBackButton = new ImageButton(act);
-    mBackButton.setLayoutParams(params);
-    mBackButton.setPadding(padding,0,padding,0);
-    mBackButton.setImageResource(icon);
+    mBackButton = new TransparentImageButton(act, icon, width, LinearLayout.LayoutParams.MATCH_PARENT);
 
     mBackButton.setOnClickListener( new View.OnClickListener()
       {
@@ -211,20 +198,8 @@ public class RubikStatePattern extends RubikStateAbstract
 
   private void setupPrevButton(final RubikActivity act, final float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
     int icon = RubikActivity.getDrawable(R.drawable.ui_small_left,R.drawable.ui_medium_left, R.drawable.ui_big_left, R.drawable.ui_huge_left);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mPrevButton = new ImageButton(act);
-    mPrevButton.setLayoutParams(params);
-    mPrevButton.setPadding(padding,0,padding,0);
-    mPrevButton.setImageResource(icon);
+    mPrevButton = new TransparentImageButton(act,icon,width,0);
 
     mPrevButton.setOnClickListener( new View.OnClickListener()
       {
@@ -244,20 +219,8 @@ public class RubikStatePattern extends RubikStateAbstract
 
   private void setupNextButton(final RubikActivity act, final float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
     int icon = RubikActivity.getDrawable(R.drawable.ui_small_right,R.drawable.ui_medium_right, R.drawable.ui_big_right, R.drawable.ui_huge_right);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mNextButton = new ImageButton(act);
-    mNextButton.setLayoutParams(params);
-    mNextButton.setPadding(padding,0,padding,0);
-    mNextButton.setImageResource(icon);
+    mNextButton = new TransparentImageButton(act,icon,width,0);
 
     mNextButton.setOnClickListener( new View.OnClickListener()
       {
diff --git a/src/main/java/org/distorted/states/RubikStatePlay.java b/src/main/java/org/distorted/states/RubikStatePlay.java
index a7d1f7f3..5df4fa7a 100644
--- a/src/main/java/org/distorted/states/RubikStatePlay.java
+++ b/src/main/java/org/distorted/states/RubikStatePlay.java
@@ -151,20 +151,9 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
 
   private void setupObjectButton(final RubikActivity act, final float width)
     {
-    final int padding = (int)(width*RubikActivity.PADDING);
     final int margin  = (int)(width*RubikActivity.MARGIN);
     final int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_menu,R.drawable.ui_medium_cube_menu, R.drawable.ui_big_cube_menu, R.drawable.ui_huge_cube_menu);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mObjButton = new ImageButton(act);
-    mObjButton.setLayoutParams(params);
-    mObjButton.setPadding(padding,0,padding,0);
-    mObjButton.setImageResource(icon);
+    mObjButton = new TransparentImageButton(act, icon, width,LinearLayout.LayoutParams.MATCH_PARENT);
 
     mObjButton.setOnClickListener( new View.OnClickListener()
       {
@@ -184,7 +173,6 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
 
           mObjectPopup.setFocusable(true);
           mObjectPopup.update();
-
           }
         }
       });
@@ -194,19 +182,8 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
 
   private void setupPlayButton(final RubikActivity act, final float width)
     {
-    final int padding = (int)(width*RubikActivity.PADDING);
     final int margin  = (int)(width*RubikActivity.MARGIN);
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mPlayButton = new Button(act);
-    mPlayButton.setLayoutParams(params);
-    mPlayButton.setPadding(padding,0,padding,0);
-    mPlayButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
-    mPlayButton.setText(R.string.play);
+    mPlayButton = new TransparentButton(act, R.string.play, mButtonSize, width);
 
     mPlayButton.setOnClickListener( new View.OnClickListener()
       {
@@ -236,20 +213,9 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
 
   private void setupMenuButton(final RubikActivity act, final float width)
     {
-    final int padding = (int)(width*RubikActivity.PADDING);
     final int margin  = (int)(width*RubikActivity.MARGIN);
     final int icon = RubikActivity.getDrawable(R.drawable.ui_small_menu,R.drawable.ui_medium_menu, R.drawable.ui_big_menu, R.drawable.ui_huge_menu);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mMenuButton = new ImageButton(act);
-    mMenuButton.setLayoutParams(params);
-    mMenuButton.setPadding(padding,0,padding,0);
-    mMenuButton.setImageResource(icon);
+    mMenuButton = new TransparentImageButton(act, icon, width,LinearLayout.LayoutParams.MATCH_PARENT);
 
     mMenuButton.setOnClickListener( new View.OnClickListener()
       {
@@ -278,20 +244,8 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
 
   private void setupSolveButton(final RubikActivity act, final float width)
     {
-    int padding  = (int)(width*RubikActivity.PADDING);
-    int margin   = (int)(width*RubikActivity.MARGIN);
     int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_solve,R.drawable.ui_medium_cube_solve, R.drawable.ui_big_cube_solve, R.drawable.ui_huge_cube_solve);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mSolveButton = new ImageButton(act);
-    mSolveButton.setLayoutParams(params);
-    mSolveButton.setPadding(padding,0,padding,0);
-    mSolveButton.setImageResource(icon);
+    mSolveButton = new TransparentImageButton(act, icon, width,LinearLayout.LayoutParams.MATCH_PARENT);
 
     mSolveButton.setOnClickListener( new View.OnClickListener()
       {
@@ -308,19 +262,8 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
 
   private void setupLockButton(final RubikActivity act, final float width)
     {
-    int padding  = (int)(width*RubikActivity.PADDING);
-    int margin   = (int)(width*RubikActivity.MARGIN);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mLockButton = new ImageButton(act);
-    mLockButton.setLayoutParams(params);
-    mLockButton.setPadding(padding,0,padding,0);
-    mLockButton.setImageResource(getLockIcon(act));
+    final int icon = getLockIcon(act);
+    mLockButton = new TransparentImageButton(act, icon, width,LinearLayout.LayoutParams.MATCH_PARENT);
 
     mLockButton.setOnClickListener( new View.OnClickListener()
       {
@@ -336,20 +279,8 @@ public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender
 
   private void setupPrevButton(final RubikActivity act, final float width)
     {
-    int padding  = (int)(width*RubikActivity.PADDING);
-    int margin   = (int)(width*RubikActivity.MARGIN);
     int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_back,R.drawable.ui_medium_cube_back, R.drawable.ui_big_cube_back, R.drawable.ui_huge_cube_back);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mPrevButton = new ImageButton(act);
-    mPrevButton.setLayoutParams(params);
-    mPrevButton.setPadding(padding,0,padding,0);
-    mPrevButton.setImageResource(icon);
+    mPrevButton = new TransparentImageButton(act, icon, width,LinearLayout.LayoutParams.MATCH_PARENT);
 
     mPrevButton.setOnClickListener( new View.OnClickListener()
       {
diff --git a/src/main/java/org/distorted/states/RubikStateReady.java b/src/main/java/org/distorted/states/RubikStateReady.java
index bdf64cb2..63d2fef7 100644
--- a/src/main/java/org/distorted/states/RubikStateReady.java
+++ b/src/main/java/org/distorted/states/RubikStateReady.java
@@ -89,20 +89,8 @@ public class RubikStateReady extends RubikStateAbstract
 
   private void setupBackButton(final RubikActivity act, float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
     final int icon = RubikActivity.getDrawable(R.drawable.ui_small_back,R.drawable.ui_medium_back, R.drawable.ui_big_back, R.drawable.ui_huge_back);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mBackButton = new ImageButton(act);
-    mBackButton.setLayoutParams(params);
-    mBackButton.setPadding(padding,0,padding,0);
-    mBackButton.setImageResource(icon);
+    mBackButton = new TransparentImageButton(act, icon, width, LinearLayout.LayoutParams.MATCH_PARENT);
 
     mBackButton.setOnClickListener( new View.OnClickListener()
       {
@@ -118,19 +106,8 @@ public class RubikStateReady extends RubikStateAbstract
 
   private void setupLockButton(final RubikActivity act, final float width)
     {
-    int padding  = (int)(width*RubikActivity.PADDING);
-    int margin   = (int)(width*RubikActivity.MARGIN);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mLockButton = new ImageButton(act);
-    mLockButton.setLayoutParams(params);
-    mLockButton.setPadding(padding,0,padding,0);
-    mLockButton.setImageResource(getLockIcon(act));
+    final int icon = getLockIcon(act);
+    mLockButton = new TransparentImageButton(act, icon, width,LinearLayout.LayoutParams.MATCH_PARENT);
 
     mLockButton.setOnClickListener( new View.OnClickListener()
       {
@@ -146,20 +123,8 @@ public class RubikStateReady extends RubikStateAbstract
 
   private void setupPrevButtom(final RubikActivity act, float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
     int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_back,R.drawable.ui_medium_cube_back, R.drawable.ui_big_cube_back, R.drawable.ui_huge_cube_back);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mPrevButton = new ImageButton(act);
-    mPrevButton.setLayoutParams(params);
-    mPrevButton.setPadding(padding,0,padding,0);
-    mPrevButton.setImageResource(icon);
+    mPrevButton = new TransparentImageButton(act, icon, width, LinearLayout.LayoutParams.MATCH_PARENT);
 
     mPrevButton.setOnClickListener( new View.OnClickListener()
       {
diff --git a/src/main/java/org/distorted/states/RubikStateSolution.java b/src/main/java/org/distorted/states/RubikStateSolution.java
index 0d96d8c5..bde960b2 100644
--- a/src/main/java/org/distorted/states/RubikStateSolution.java
+++ b/src/main/java/org/distorted/states/RubikStateSolution.java
@@ -45,7 +45,7 @@ public class RubikStateSolution extends RubikStateAbstract implements RubikPreRe
   private int[][] mMoves;
   private int mCurrMove, mNumMoves;
   private boolean mCanRotate;
-  private float mButtonSize, mTitleSize;
+  private float mButtonSize;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -61,7 +61,7 @@ public class RubikStateSolution extends RubikStateAbstract implements RubikPreRe
     {
     float width = act.getScreenWidthInPixels();
     mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
-    mTitleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
+    float titleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
 
     LayoutInflater inflater = act.getLayoutInflater();
 
@@ -70,7 +70,7 @@ public class RubikStateSolution extends RubikStateAbstract implements RubikPreRe
     layoutTop.removeAllViews();
 
     final TextView text = (TextView)inflater.inflate(R.layout.upper_text, null);
-    text.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTitleSize);
+    text.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize);
     text.setText(R.string.solution);
     layoutTop.addView(text);
 
@@ -110,20 +110,8 @@ public class RubikStateSolution extends RubikStateAbstract implements RubikPreRe
 
   private void setupPrevButton(final RubikActivity act, final float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
     int icon = RubikActivity.getDrawable(R.drawable.ui_small_left,R.drawable.ui_medium_left, R.drawable.ui_big_left, R.drawable.ui_huge_left);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mPrevButton = new ImageButton(act);
-    mPrevButton.setLayoutParams(params);
-    mPrevButton.setPadding(padding,0,padding,0);
-    mPrevButton.setImageResource(icon);
+    mPrevButton = new TransparentImageButton(act,icon,width,0);
 
     mPrevButton.setOnClickListener( new View.OnClickListener()
       {
@@ -141,20 +129,8 @@ public class RubikStateSolution extends RubikStateAbstract implements RubikPreRe
 
   private void setupNextButton(final RubikActivity act, final float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
     int icon = RubikActivity.getDrawable(R.drawable.ui_small_right,R.drawable.ui_medium_right, R.drawable.ui_big_right, R.drawable.ui_huge_right);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mNextButton = new ImageButton(act);
-    mNextButton.setLayoutParams(params);
-    mNextButton.setPadding(padding,0,padding,0);
-    mNextButton.setImageResource(icon);
+    mNextButton = new TransparentImageButton(act,icon,width,0);
 
     mNextButton.setOnClickListener( new View.OnClickListener()
       {
@@ -193,20 +169,8 @@ public class RubikStateSolution extends RubikStateAbstract implements RubikPreRe
 
   private void setupBackButton(final RubikActivity act, final float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
     final int icon = RubikActivity.getDrawable(R.drawable.ui_small_back,R.drawable.ui_medium_back, R.drawable.ui_big_back, R.drawable.ui_huge_back);
-
-    mBackButton = new ImageButton(act);
-    mBackButton.setLayoutParams(params);
-    mBackButton.setPadding(padding,0,padding,0);
-    mBackButton.setImageResource(icon);
+    mBackButton = new TransparentImageButton(act, icon, width, LinearLayout.LayoutParams.MATCH_PARENT);
 
     mBackButton.setOnClickListener( new View.OnClickListener()
       {
diff --git a/src/main/java/org/distorted/states/RubikStateSolver.java b/src/main/java/org/distorted/states/RubikStateSolver.java
index 847cdcc8..978b9c64 100644
--- a/src/main/java/org/distorted/states/RubikStateSolver.java
+++ b/src/main/java/org/distorted/states/RubikStateSolver.java
@@ -199,20 +199,8 @@ public class RubikStateSolver extends RubikStateAbstract
 
   private void setupSolveButton(final RubikActivity act, final float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin   = (int)(width*RubikActivity.MARGIN);
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
     final int icon = RubikActivity.getDrawable(R.drawable.ui_small_solve,R.drawable.ui_medium_solve, R.drawable.ui_big_solve, R.drawable.ui_huge_solve);
-
-    mSolveButton = new ImageButton(act);
-    mSolveButton.setLayoutParams(params);
-    mSolveButton.setPadding(padding,0,padding,0);
-    mSolveButton.setImageResource(icon);
+    mSolveButton = new TransparentImageButton(act,icon,width, LinearLayout.LayoutParams.MATCH_PARENT);
 
     mSolveButton.setOnClickListener( new View.OnClickListener()
       {
@@ -235,20 +223,8 @@ public class RubikStateSolver extends RubikStateAbstract
 
   private void setupBackButton(final RubikActivity act, final float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
     final int icon = RubikActivity.getDrawable(R.drawable.ui_small_back,R.drawable.ui_medium_back, R.drawable.ui_big_back, R.drawable.ui_huge_back);
-
-    mBackButton = new ImageButton(act);
-    mBackButton.setLayoutParams(params);
-    mBackButton.setPadding(padding,0,padding,0);
-    mBackButton.setImageResource(icon);
+    mBackButton = new TransparentImageButton(act, icon, width, LinearLayout.LayoutParams.MATCH_PARENT);
 
     mBackButton.setOnClickListener( new View.OnClickListener()
       {
diff --git a/src/main/java/org/distorted/states/RubikStateSolving.java b/src/main/java/org/distorted/states/RubikStateSolving.java
index 793253ab..af3baa6c 100644
--- a/src/main/java/org/distorted/states/RubikStateSolving.java
+++ b/src/main/java/org/distorted/states/RubikStateSolving.java
@@ -135,20 +135,8 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPreRen
 
   private void setupBackButtom(final RubikActivity act, float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
     final int icon = RubikActivity.getDrawable(R.drawable.ui_small_back,R.drawable.ui_medium_back, R.drawable.ui_big_back, R.drawable.ui_huge_back);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mBackButton = new ImageButton(act);
-    mBackButton.setLayoutParams(params);
-    mBackButton.setPadding(padding,0,padding,0);
-    mBackButton.setImageResource(icon);
+    mBackButton = new TransparentImageButton(act, icon, width, LinearLayout.LayoutParams.MATCH_PARENT);
 
     mBackButton.setOnClickListener( new View.OnClickListener()
       {
@@ -164,19 +152,8 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPreRen
 
   private void setupLockButton(final RubikActivity act, final float width)
     {
-    int padding  = (int)(width*RubikActivity.PADDING);
-    int margin   = (int)(width*RubikActivity.MARGIN);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mLockButton = new ImageButton(act);
-    mLockButton.setLayoutParams(params);
-    mLockButton.setPadding(padding,0,padding,0);
-    mLockButton.setImageResource(getLockIcon(act));
+    final int icon = getLockIcon(act);
+    mLockButton = new TransparentImageButton(act, icon, width, LinearLayout.LayoutParams.MATCH_PARENT);
 
     mLockButton.setOnClickListener( new View.OnClickListener()
       {
@@ -192,20 +169,8 @@ public class RubikStateSolving extends RubikStateAbstract implements RubikPreRen
 
   private void setupPrevButtom(final RubikActivity act, float width)
     {
-    int padding = (int)(width*RubikActivity.PADDING);
-    int margin  = (int)(width*RubikActivity.MARGIN);
     int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_back,R.drawable.ui_medium_cube_back, R.drawable.ui_big_cube_back, R.drawable.ui_huge_cube_back);
-
-    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
-    params.topMargin    = margin;
-    params.bottomMargin = margin;
-    params.leftMargin   = margin;
-    params.rightMargin  = margin;
-
-    mPrevButton = new ImageButton(act);
-    mPrevButton.setLayoutParams(params);
-    mPrevButton.setPadding(padding,0,padding,0);
-    mPrevButton.setImageResource(icon);
+    mPrevButton = new TransparentImageButton(act, icon, width, LinearLayout.LayoutParams.MATCH_PARENT);
 
     mPrevButton.setOnClickListener( new View.OnClickListener()
       {
