Project

General

Profile

« Previous | Next » 

Revision 58fd2ec0

Added by Leszek Koltunski 3 months ago

Initial support for configuring the stickers.

View differences:

src/main/AndroidManifest.xml
37 37
        <activity android:name="org.distorted.solverui.SolverActivity" android:exported="false" android:screenOrientation="portrait"/>
38 38
        <activity android:name="org.distorted.patternui.PatternActivity" android:exported="false" android:screenOrientation="portrait"/>
39 39
        <activity android:name="org.distorted.playui.PlayActivity" android:exported="false" android:screenOrientation="portrait"/>
40
        <activity android:name="org.distorted.config.ConfigActivity" android:exported="false" android:screenOrientation="portrait"/>
40 41

  
41 42
        <service
42 43
            android:name="org.distorted.messaging.RubikMessagingService"
src/main/java/org/distorted/config/ConfigActivity.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

  
10
package org.distorted.config;
11

  
12
import android.os.Build;
13
import android.os.Bundle;
14
import android.util.DisplayMetrics;
15
import android.view.View;
16
import android.view.ViewGroup;
17
import android.view.WindowManager;
18
import android.widget.LinearLayout;
19

  
20
import androidx.appcompat.app.AppCompatActivity;
21

  
22
import org.distorted.dialogs.RubikDialogError;
23
import org.distorted.library.effect.MatrixEffectQuaternion;
24
import org.distorted.library.main.DistortedLibrary;
25
import org.distorted.main.MainActivity;
26
import org.distorted.main.R;
27
import org.distorted.objectlib.main.InitAssets;
28
import org.distorted.objectlib.main.ObjectControl;
29
import org.distorted.objectlib.main.TwistyObject;
30
import org.distorted.objects.RubikObject;
31
import org.distorted.objects.RubikObjectList;
32

  
33
import java.io.InputStream;
34

  
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

  
37
public class ConfigActivity extends AppCompatActivity
38
{
39
    private static final int ACTIVITY_NUMBER = 7;
40
    private static final float RATIO_BAR  = MainActivity.RATIO_BAR;
41
    public static final int FLAGS = MainActivity.FLAGS;
42

  
43
    private static int mScreenWidth, mScreenHeight;
44
    private int mCurrentApiVersion;
45
    private ConfigScreen mScreen;
46
    private int mObjectOrdinal;
47

  
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

  
50
    @Override
51
    protected void onCreate(Bundle savedState)
52
      {
53
      super.onCreate(savedState);
54
      DistortedLibrary.onCreate(ACTIVITY_NUMBER);
55
      setTheme(R.style.MaterialThemeNoActionBar);
56
      setContentView(R.layout.config);
57

  
58
      Bundle b = getIntent().getExtras();
59

  
60
      if(b != null) mObjectOrdinal = b.getInt("obj");
61

  
62
      DisplayMetrics displaymetrics = new DisplayMetrics();
63
      getWindowManager().getDefaultDisplay().getRealMetrics(displaymetrics);
64
      mScreenWidth =displaymetrics.widthPixels;
65
      mScreenHeight=displaymetrics.heightPixels;
66

  
67
      hideNavigationBar();
68
      cutoutHack();
69
      computeBarHeights();
70
      }
71

  
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73
// this does not include possible insets
74

  
75
    private void computeBarHeights()
76
      {
77
      int barHeight = (int)(mScreenHeight*RATIO_BAR);
78
      LinearLayout layout = findViewById(R.id.lowerBar);
79
      ViewGroup.LayoutParams params = layout.getLayoutParams();
80
      params.height = barHeight;
81
      layout.setLayoutParams(params);
82
      }
83

  
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

  
86
    private void hideNavigationBar()
87
      {
88
      mCurrentApiVersion = Build.VERSION.SDK_INT;
89

  
90
      if(mCurrentApiVersion >= Build.VERSION_CODES.KITKAT)
91
        {
92
        final View decorView = getWindow().getDecorView();
93

  
94
        decorView.setSystemUiVisibility(FLAGS);
95

  
96
        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener()
97
          {
98
          @Override
99
          public void onSystemUiVisibilityChange(int visibility)
100
            {
101
            if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0)
102
              {
103
              decorView.setSystemUiVisibility(FLAGS);
104
              }
105
            }
106
          });
107
        }
108
      }
109

  
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111
// do not avoid cutouts
112

  
113
    private void cutoutHack()
114
      {
115
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
116
        {
117
        getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
118
        }
119
      }
120

  
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

  
123
    @Override
124
    public void onWindowFocusChanged(boolean hasFocus)
125
      {
126
      super.onWindowFocusChanged(hasFocus);
127

  
128
      if(mCurrentApiVersion >= Build.VERSION_CODES.KITKAT && hasFocus)
129
        {
130
        getWindow().getDecorView().setSystemUiVisibility(FLAGS);
131
        }
132
      }
133

  
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135
    
136
    @Override
137
    protected void onPause() 
138
      {
139
      super.onPause();
140
      ConfigSurfaceView view = findViewById(R.id.configSurfaceView);
141
      view.onPause();
142
      DistortedLibrary.onPause(ACTIVITY_NUMBER);
143
      }
144

  
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146
    
147
    @Override
148
    protected void onResume() 
149
      {
150
      super.onResume();
151
      DistortedLibrary.onResume(ACTIVITY_NUMBER);
152
      ConfigSurfaceView view = findViewById(R.id.configSurfaceView);
153
      view.onResume();
154

  
155
      if( mScreen==null ) mScreen = new ConfigScreen();
156
      mScreen.onAttachedToWindow(this,mObjectOrdinal);
157

  
158
      if( mObjectOrdinal>=0 && mObjectOrdinal< RubikObjectList.getNumObjects() )
159
        {
160
        RubikObject object = RubikObjectList.getObject(mObjectOrdinal);
161
        changeIfDifferent(object,mObjectOrdinal,view.getObjectControl());
162
        }
163
      }
164

  
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166
    
167
    @Override
168
    protected void onDestroy() 
169
      {
170
      super.onDestroy();
171
      DistortedLibrary.onDestroy(ACTIVITY_NUMBER);
172
      }
173

  
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

  
176
    void OpenGLError()
177
      {
178
      RubikDialogError errDiag = new RubikDialogError();
179
      errDiag.show(getSupportFragmentManager(), null);
180
      }
181

  
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

  
184
    private void changeIfDifferent(RubikObject object,int ordinal,ObjectControl control)
185
      {
186
      if( object!=null )
187
        {
188
        int iconMode           = TwistyObject.MODE_NORM;
189
        InputStream jsonStream = object.getObjectStream(this);
190
        InputStream meshStream = object.getMeshStream(this);
191
        String name            = object.getUpperName();
192
        InitAssets asset       = new InitAssets(jsonStream,meshStream,null);
193
        control.changeIfDifferent(ordinal,name,iconMode,asset);
194
        }
195
      }
196

  
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198
// PUBLIC API
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

  
201
    public ConfigRenderer getRenderer()
202
      {
203
      ConfigSurfaceView view = findViewById(R.id.configSurfaceView);
204
      return view.getRenderer();
205
      }
206

  
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

  
209
    public int getScreenWidthInPixels()
210
      {
211
      return mScreenWidth;
212
      }
213

  
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

  
216
    public int getScreenHeightInPixels()
217
      {
218
      return mScreenHeight;
219
      }
220

  
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

  
223
    public ObjectControl getControl()
224
      {
225
      ConfigSurfaceView view = findViewById(R.id.configSurfaceView);
226
      return view.getObjectControl();
227
      }
228
}
src/main/java/org/distorted/config/ConfigObjectLibInterface.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

  
10
package org.distorted.config;
11

  
12
import com.google.firebase.crashlytics.FirebaseCrashlytics;
13

  
14
import org.distorted.library.message.EffectMessageSender;
15
import org.distorted.main.BuildConfig;
16
import org.distorted.objectlib.helpers.BlockController;
17
import org.distorted.objectlib.helpers.ObjectLibInterface;
18
import org.distorted.objectlib.main.ObjectControl;
19
import org.distorted.solvers.SolverMain;
20
import org.distorted.solverui.ScreenList;
21
import org.distorted.solverui.ScreenSolver;
22
import org.distorted.solverui.SolverActivity;
23

  
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

  
26
public class ConfigObjectLibInterface implements ObjectLibInterface
27
{
28
  public void onWinEffectFinished(long startTime, long endTime, String debug, int scrambleNum) { }
29
  public void onScrambleEffectFinished() { }
30
  public void onBeginRotation() { }
31
  public void onSolved() { }
32
  public void onObjectCreated(long time) { }
33
  public void onRemoveRotation(int axis, int row, int angle) { }
34
  public void failedToDrag() { }
35
  public void reportJSONError(String error, int ordinal) { }
36

  
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

  
39
  public void reportProblem(String problem, boolean reportException)
40
    {
41
    if( BuildConfig.DEBUG )
42
      {
43
      android.util.Log.e("interface", problem);
44
      }
45
    else
46
      {
47
      if( reportException )
48
        {
49
        Exception ex = new Exception(problem);
50
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
51
        crashlytics.setCustomKey("problem" , problem);
52
        crashlytics.recordException(ex);
53
        }
54
      else
55
        {
56
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
57
        crashlytics.log(problem);
58
        }
59
      }
60
    }
61

  
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

  
64
  private void reportScramblingProblem(int place, long pause, long resume, long time)
65
    {
66
    String error = "SCRAMBLING BLOCK "+place+" blocked for "+time;
67

  
68
    if( BuildConfig.DEBUG )
69
       {
70
       android.util.Log.e("D", error);
71
       }
72
    else
73
      {
74
      Exception ex = new Exception(error);
75
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
76
      crashlytics.setCustomKey("pause" , pause );
77
      crashlytics.setCustomKey("resume", resume );
78
      crashlytics.recordException(ex);
79
      }
80
    }
81

  
82
///////////////////////////////////////////////////////////////////////////////////////////////////
83

  
84
  private void reportRotationProblem(int place, long pause, long resume, long time)
85
    {
86
    String error = "ROTATION BLOCK "+place+" blocked for "+time;
87

  
88
    if( BuildConfig.DEBUG )
89
       {
90
       android.util.Log.e("D", error);
91
       }
92
    else
93
      {
94
      Exception ex = new Exception(error);
95
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
96
      crashlytics.setCustomKey("pause" , pause );
97
      crashlytics.setCustomKey("resume", resume);
98
      crashlytics.recordException(ex);
99
      }
100
    }
101

  
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

  
104
  private void reportThreadProblem(int place, long pause, long resume, long time)
105
    {
106
    String error = EffectMessageSender.reportState();
107

  
108
    if( BuildConfig.DEBUG )
109
       {
110
       android.util.Log.e("D", error);
111
       }
112
    else
113
      {
114
      Exception ex = new Exception(error);
115
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
116
      crashlytics.setCustomKey("pause" , pause  );
117
      crashlytics.setCustomKey("resume", resume );
118
      crashlytics.recordException(ex);
119
      }
120
    }
121

  
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

  
124
  public void reportBlockProblem(int type, int place, long pause, long resume, long time)
125
    {
126
    switch(type)
127
      {
128
      case BlockController.TYPE_SCRAMBLING: reportScramblingProblem(place,pause,resume,time); break;
129
      case BlockController.TYPE_ROTATION  : reportRotationProblem(place,pause,resume,time); break;
130
      case BlockController.TYPE_THREAD    : reportThreadProblem(place,pause,resume,time); break;
131
      }
132
    }
133

  
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135
// TODO
136

  
137
  public void onReplaceModeDown(int cubit, int face)
138
    {
139

  
140
    }
141

  
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

  
144
  public void onReplaceModeUp()
145
    {
146

  
147
    }
148
}
src/main/java/org/distorted/config/ConfigRenderer.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

  
10
package org.distorted.config;
11

  
12
import static org.distorted.library.helpers.QuatHelper.rotateVectorByInvertedQuat;
13

  
14
import android.content.res.Resources;
15
import android.opengl.GLSurfaceView;
16

  
17
import org.distorted.library.effect.EffectType;
18
import org.distorted.library.effect.MatrixEffectRotate;
19
import org.distorted.library.effect.VertexEffectQuaternion;
20
import org.distorted.library.effect.VertexEffectRotate;
21
import org.distorted.library.main.DistortedLibrary;
22
import org.distorted.library.main.DistortedScreen;
23
import org.distorted.library.type.Static1D;
24
import org.distorted.library.type.Static3D;
25
import org.distorted.library.type.Static4D;
26
import org.distorted.objectlib.effects.BaseEffect;
27
import org.distorted.objectlib.main.ObjectControl;
28
import org.distorted.objectlib.main.TwistyObject;
29

  
30
import java.io.InputStream;
31

  
32
import javax.microedition.khronos.egl.EGLConfig;
33
import javax.microedition.khronos.opengles.GL10;
34

  
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

  
37
public class ConfigRenderer implements GLSurfaceView.Renderer, DistortedLibrary.LibraryUser
38
{
39
   private static final int RESET_DURATION = 1000;
40

  
41
   private final ConfigSurfaceView mView;
42
   private final Resources mResources;
43
   private final DistortedScreen mScreen;
44
   private final ObjectControl mControl;
45
   private boolean mResettingObject, mInitialPhase, mEffectApplied;
46
   private long mStartTime;
47
   private final Static1D mAngle;
48

  
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50

  
51
   ConfigRenderer(ConfigSurfaceView v)
52
     {
53
     final float BRIGHTNESS = 0.333f;
54

  
55
     mResettingObject = false;
56
     mEffectApplied   = false;
57
     mAngle = new Static1D(0);
58

  
59
     mView = v;
60
     mControl = mView.getObjectControl();
61

  
62
     mResources = v.getResources();
63
     mScreen = new DistortedScreen();
64
     mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
65
     }
66

  
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

  
69
   @Override
70
   public void onDrawFrame(GL10 glUnused)
71
     {
72
     long time = System.currentTimeMillis();
73
     mControl.preRender();
74
     mScreen.render(time);
75

  
76
     if( mResettingObject )
77
       {
78
       if( !mEffectApplied )
79
         {
80
         mEffectApplied = true;
81
         ObjectControl control = mView.getObjectControl();
82
         TwistyObject object = control.getObject();
83

  
84
         Static4D quaternion = object.getRotationQuat();                       // always rotate around
85
         Static4D tmpAxis    = new Static4D(0,-1,0,0);                         // vert axis no matter
86
         Static4D rotated    = rotateVectorByInvertedQuat(tmpAxis,quaternion); // how cube is rotated
87
         Static3D axis       = new Static3D(rotated.get0(), rotated.get1(), rotated.get2());
88
         Static3D center     = new Static3D(0,0,0);
89

  
90
         MatrixEffectRotate effect = new MatrixEffectRotate(mAngle, axis, center );
91
         object.applyEffect(effect,0);
92
         }
93

  
94
       boolean done = continueResetting(time);
95
       if( done ) mResettingObject = false;
96
       }
97
     }
98

  
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

  
101
   public void setupReset()
102
     {
103
     if( !mResettingObject )
104
       {
105
       mResettingObject = true;
106
       mInitialPhase    = true;
107
       mStartTime       = System.currentTimeMillis();
108
       }
109
     }
110

  
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

  
113
   private boolean continueResetting(long time)
114
     {
115
     long diff = time-mStartTime;
116
     float quotient = ((float)diff)/RESET_DURATION;
117

  
118
     if( mInitialPhase && quotient>0.5f )
119
       {
120
       mInitialPhase=false;
121
       mView.resetObject();
122
       }
123

  
124
     float angle = 720*quotient*quotient*(3-2*quotient);
125
     mAngle.set( angle );
126

  
127
     return quotient>1.0f;
128
     }
129

  
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

  
132
   @Override
133
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
134
      {
135
      mScreen.resize(width,height);
136
      mView.setScreenSize(width,height);
137
      }
138

  
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

  
141
   DistortedScreen getScreen()
142
     {
143
     return mScreen;
144
     }
145

  
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

  
148
   @Override
149
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
150
      {
151
      DistortedLibrary.setMax(EffectType.VERTEX, ObjectControl.MAX_QUATS+1);
152
      VertexEffectRotate.enable();
153
      VertexEffectQuaternion.enable();
154
      BaseEffect.Type.enableEffects();
155

  
156
      DistortedLibrary.onSurfaceCreated(this,1);
157
      DistortedLibrary.setCull(true);
158
      }
159

  
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

  
162
   public void distortedException(Exception ex)
163
     {
164
     android.util.Log.e("Config", "unexpected exception: "+ex.getMessage() );
165
     }
166

  
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

  
169
   public InputStream localFile(int fileID)
170
      {
171
      return mResources.openRawResource(fileID);
172
      }
173

  
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

  
176
   public void logMessage(String message)
177
      {
178
      android.util.Log.e("Config", message );
179
      }
180
}
src/main/java/org/distorted/config/ConfigScreen.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

  
10
package org.distorted.config;
11

  
12
import android.view.View;
13
import android.widget.LinearLayout;
14

  
15
import org.distorted.helpers.TransparentImageButton;
16
import org.distorted.main.R;
17

  
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
public class ConfigScreen
21
{
22
  private TransparentImageButton mBackButton, mResetButton;
23
  private ConfigScreenPane mPane;
24

  
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26

  
27
  private void setupBackButton(final ConfigActivity act)
28
    {
29
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
30
    mBackButton = new TransparentImageButton(act,R.drawable.ui_smallback,params);
31

  
32
    mBackButton.setOnClickListener( new View.OnClickListener()
33
      {
34
      @Override
35
      public void onClick(View v)
36
        {
37
        act.finish();
38
        }
39
      });
40
    }
41

  
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

  
44
  private void setupResetButton(final ConfigActivity act)
45
    {
46
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
47
    mResetButton = new TransparentImageButton(act,R.drawable.ui_reset,params);
48

  
49
    mResetButton.setOnClickListener( new View.OnClickListener()
50
      {
51
      @Override
52
      public void onClick(View v)
53
        {
54
        ConfigRenderer renderer = act.getRenderer();
55
        renderer.setupReset();
56
        }
57
      });
58
    }
59

  
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

  
62
  void onAttachedToWindow(final ConfigActivity act, final int objectOrdinal)
63
    {
64
    int width = act.getScreenWidthInPixels();
65

  
66
    LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
67
    LinearLayout.LayoutParams paramsM = new LinearLayout.LayoutParams(width/2, LinearLayout.LayoutParams.MATCH_PARENT);
68
    LinearLayout.LayoutParams paramsR = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
69

  
70
    LinearLayout layoutLeft = new LinearLayout(act);
71
    layoutLeft.setLayoutParams(paramsL);
72
    LinearLayout layoutMid  = new LinearLayout(act);
73
    layoutMid.setLayoutParams(paramsM);
74
    LinearLayout layoutRight= new LinearLayout(act);
75
    layoutRight.setLayoutParams(paramsR);
76

  
77
    setupBackButton(act);
78
    setupResetButton(act);
79
    layoutLeft.addView(mResetButton);
80
    layoutRight.addView(mBackButton);
81

  
82
    LinearLayout layout = act.findViewById(R.id.lowerBar);
83
    layout.removeAllViews();
84
    layout.addView(layoutLeft);
85
    layout.addView(layoutMid);
86
    layout.addView(layoutRight);
87

  
88
    mPane = new ConfigScreenPane(act,objectOrdinal);
89
    }
90
}
src/main/java/org/distorted/config/ConfigScreenPane.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

  
10
package org.distorted.config;
11

  
12
import static org.distorted.objects.RubikObjectCategories.DIFF_IDS;
13
import static org.distorted.objects.RubikObjectCategories.DIFF_IMAGES;
14

  
15
import android.graphics.PorterDuff;
16
import android.util.TypedValue;
17
import android.widget.ImageView;
18
import android.widget.LinearLayout;
19
import android.widget.TextView;
20

  
21
import org.distorted.main.R;
22
import org.distorted.objectlib.json.JsonReader;
23
import org.distorted.objects.RubikObject;
24
import org.distorted.objects.RubikObjectList;
25

  
26
import java.io.InputStream;
27

  
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29
// TODO
30

  
31
public class ConfigScreenPane
32
{
33
  private static final int NUM_IDS         = DIFF_IDS.length;
34
  private static final float PADDING_RATIO = 0.016f;
35
  private static final float TEXT_RATIO    = 0.025f;
36

  
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

  
39
  void updatePane(ConfigActivity act, int objectOrdinal)
40
    {
41

  
42
    }
43

  
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45

  
46
  ConfigScreenPane(final ConfigActivity act, int objectOrdinal)
47
    {
48
    int height = act.getScreenHeightInPixels();
49
    float textSize = height*TEXT_RATIO;
50
    int padding = (int)(height*PADDING_RATIO);
51

  
52
    LinearLayout configLayout = act.findViewById(R.id.configLayout);
53
    configLayout.setPadding(padding,padding,padding,padding);
54

  
55
    LinearLayout.LayoutParams paramsLayout = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 1.00f);
56
    paramsLayout.bottomMargin = padding;
57
    paramsLayout.topMargin    = 0;
58
    paramsLayout.leftMargin   = padding;
59
    paramsLayout.rightMargin  = padding;
60

  
61
    configLayout.setLayoutParams(paramsLayout);
62

  
63
    TextView textStickers = configLayout.findViewById(R.id.configTextStickers);
64
    textStickers.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
65
    }
66
}
src/main/java/org/distorted/config/ConfigSurfaceView.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

  
10
package org.distorted.config;
11

  
12
import static org.distorted.objectlib.main.ObjectControl.MODE_REPLACE;
13

  
14
import android.annotation.SuppressLint;
15
import android.app.ActivityManager;
16
import android.content.Context;
17
import android.content.pm.ConfigurationInfo;
18
import android.opengl.GLES30;
19
import android.opengl.GLSurfaceView;
20
import android.util.AttributeSet;
21
import android.view.MotionEvent;
22

  
23
import com.google.firebase.crashlytics.FirebaseCrashlytics;
24

  
25
import org.distorted.objectlib.main.ObjectControl;
26
import org.distorted.objectlib.main.TwistyObjectNode;
27
import org.distorted.os.OSInterface;
28

  
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30

  
31
public class ConfigSurfaceView extends GLSurfaceView
32
{
33
    private ObjectControl mObjectController;
34
    private ConfigRenderer mRenderer;
35
    private OSInterface mInterface;
36
    private boolean mCreated;
37

  
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

  
40
    void setScreenSize(int width, int height)
41
      {
42
      mObjectController.setScreenSizeAndScaling(width,height, Math.min(width,height));
43
      mObjectController.setObjectScale(1.00f);
44

  
45
      if( !mCreated )
46
        {
47
        mCreated = true;
48
        mObjectController.createNode(width,height);
49
        TwistyObjectNode objectNode = mObjectController.getNode();
50
        mRenderer.getScreen().attach(objectNode);
51
        }
52
      }
53

  
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

  
56
    ObjectControl getObjectControl()
57
      {
58
      return mObjectController;
59
      }
60

  
61
///////////////////////////////////////////////////////////////////////////////////////////////////
62

  
63
    ConfigRenderer getRenderer()
64
      {
65
      return mRenderer;
66
      }
67

  
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

  
70
    void resetObject()
71
      {
72
      // TODO
73
      }
74

  
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76
// PUBLIC API
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

  
79
    public ConfigSurfaceView(Context context, AttributeSet attrs)
80
      {
81
      super(context,attrs);
82

  
83
      mCreated = false;
84

  
85
      if(!isInEditMode())
86
        {
87
        ConfigActivity act = (ConfigActivity)context;
88
        ConfigObjectLibInterface ref = new ConfigObjectLibInterface();
89
        mInterface = new OSInterface(act,ref);
90
        mObjectController = new ObjectControl(mInterface);
91
        mObjectController.setRotateOnCreation(true);
92
        mRenderer = new ConfigRenderer(this);
93

  
94
        final ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
95

  
96
        try
97
          {
98
          final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
99
          int esVersion = configurationInfo.reqGlEsVersion>>16;
100
          setEGLContextClientVersion(esVersion);
101
          setRenderer(mRenderer);
102
          }
103
        catch(Exception ex)
104
          {
105
          act.OpenGLError();
106

  
107
          String shading = GLES30.glGetString(GLES30.GL_SHADING_LANGUAGE_VERSION);
108
          String version = GLES30.glGetString(GLES30.GL_VERSION);
109
          String vendor  = GLES30.glGetString(GLES30.GL_VENDOR);
110
          String renderer= GLES30.glGetString(GLES30.GL_RENDERER);
111

  
112
          FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
113
          crashlytics.setCustomKey("GLSL Version"  , shading );
114
          crashlytics.setCustomKey("GL version"    , version );
115
          crashlytics.setCustomKey("GL Vendor "    , vendor  );
116
          crashlytics.setCustomKey("GLSL renderer" , renderer);
117
          crashlytics.recordException(ex);
118
          }
119
        }
120
      }
121

  
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

  
124
    @Override
125
    public void onPause()
126
      {
127
      super.onPause();
128
      mObjectController.onPause();
129
      }
130

  
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

  
133
    @Override
134
    public void onResume()
135
      {
136
      super.onResume();
137
      mObjectController.onResume();
138
      }
139

  
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

  
142
    @SuppressLint("ClickableViewAccessibility")
143
    @Override
144
    public boolean onTouchEvent(MotionEvent event)
145
      {
146
      mInterface.setMotionEvent(event);
147
      return mObjectController.onTouchEvent(MODE_REPLACE);
148
      }
149
}
150

  
src/main/java/org/distorted/info/InfoRenderer.java
89 89

  
90 90
   public void distortedException(Exception ex)
91 91
     {
92
     android.util.Log.e("Config", "unexpected exception: "+ex.getMessage() );
92
     android.util.Log.e("Info", "unexpected exception: "+ex.getMessage() );
93 93
     }
94 94

  
95 95
///////////////////////////////////////////////////////////////////////////////////////////////////
......
103 103

  
104 104
   public void logMessage(String message)
105 105
      {
106
      android.util.Log.e("Config", message );
106
      android.util.Log.e("Info", message );
107 107
      }
108 108
}
src/main/java/org/distorted/info/InfoScreen.java
9 9

  
10 10
package org.distorted.info;
11 11

  
12
import android.os.Build;
13
import android.util.TypedValue;
14
import android.view.Gravity;
15 12
import android.view.View;
16
import android.widget.GridLayout;
17
import android.widget.ImageButton;
18 13
import android.widget.LinearLayout;
19
import android.widget.PopupWindow;
20
import android.widget.ScrollView;
21
import android.widget.TextView;
22

  
23
import org.distorted.helpers.ObjectGridCreator;
24 14

  
25 15
import org.distorted.helpers.TransparentImageButton;
26
import org.distorted.main.MainActivity;
27 16
import org.distorted.main.R;
28
import org.distorted.objects.RubikObject;
29
import org.distorted.objects.RubikObjectList;
30

  
31
import static android.view.View.inflate;
32 17

  
33 18
///////////////////////////////////////////////////////////////////////////////////////////////////
34 19

  
35 20
public class InfoScreen
36 21
{
37
  private static final float TEXT_SIZE = 0.0310f;
38
  private static final float PADDING   = 0.0060f;
39
  private static final float MARGIN    = 0.0024f;
40
  private static final int[] mLocation = new int[2];
41
  private static final float POPUP_W  = 0.8f;
42

  
43
  private TransparentImageButton mBackButton, mObjectButton, mPrevButton, mNextButton;
44
  private TextView mMovesText;
45
  private PopupWindow mObjectPopup;
22
  private TransparentImageButton mBackButton;
46 23
  private InfoScreenPane mPane;
47
  private int mObjectOrdinal;
48
  private float mButtonSize;
49

  
50
///////////////////////////////////////////////////////////////////////////////////////////////////
51

  
52
  private void setupObjectWindow(final InfoActivity act, final float width, final float height)
53
    {
54
    int numObjects= RubikObjectList.getNumObjects();
55
    ScrollView view = (ScrollView)inflate( act, R.layout.popup_object_simple, null);
56
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
57

  
58
    int[] objects = new int[numObjects];
59
    for(int i=0; i<numObjects; i++) objects[i] = i;
60

  
61
    ObjectGridCreator creator = new ObjectGridCreator(width);
62
    creator.createObjectGridClassic(objectGrid,act,objects);
63

  
64
    for(int child=0; child<numObjects; child++)
65
      {
66
      final RubikObject obj = RubikObjectList.getObject(child);
67
      View v = objectGrid.getChildAt(child);
68
      ImageButton button = creator.getButton(obj,v);
69
      final int ordinal = child;
70

  
71
      button.setOnClickListener( new View.OnClickListener()
72
        {
73
        @Override
74
        public void onClick(View v)
75
          {
76
          if( mObjectOrdinal!=ordinal )
77
            {
78
            mObjectOrdinal = ordinal;
79
            act.changeObject(mObjectOrdinal);
80
            mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
81
            mPane.updatePane(act,mObjectOrdinal);
82
            }
83

  
84
          mObjectPopup.dismiss();
85
          }
86
        });
87
      }
88

  
89
    mObjectPopup = new PopupWindow(act);
90
    mObjectPopup.setFocusable(true);
91
    mObjectPopup.setContentView(view);
92
    }
93 24

  
94 25
///////////////////////////////////////////////////////////////////////////////////////////////////
95 26

  
......
108 39
      });
109 40
    }
110 41

  
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

  
113
  private void setupObjectButton(final InfoActivity act, final int width, final int height)
114
    {
115
    final int margin= (int)(height*MARGIN);
116
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
117
    mObjectButton = new TransparentImageButton(act,R.drawable.ui_cube_menu,params);
118

  
119
    mObjectButton.setOnClickListener( new View.OnClickListener()
120
      {
121
      @Override
122
      public void onClick(View view)
123
        {
124
        if( mObjectPopup==null ) setupObjectWindow(act,width,height);
125
        View popupView = mObjectPopup.getContentView();
126
        popupView.setSystemUiVisibility(MainActivity.FLAGS);
127
        displayPopup(act,view,mObjectPopup,width,height,margin,margin);
128
        }
129
      });
130
    }
131

  
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
134

  
135
  private void displayPopup(InfoActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
136
    {
137
    View topLayout = act.findViewById(R.id.mainLayout);
138
    boolean isFullScreen;
139

  
140
    if( topLayout!=null )
141
      {
142
      topLayout.getLocationOnScreen(mLocation);
143
      isFullScreen = (mLocation[1]==0);
144
      }
145
    else
146
      {
147
      isFullScreen = true;
148
      }
149

  
150
    try
151
      {
152
      // if on Android 11 or we are fullscreen
153
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
154
        {
155
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
156
        window.update(view, w, h);
157
        }
158
      else  // Android 10 or below in pop-up mode or split-screen mode
159
        {
160
        view.getLocationOnScreen(mLocation);
161
        int width  = view.getWidth();
162
        int height = view.getHeight();
163
        int x = mLocation[0]+(width-w)/2;
164
        int y = mLocation[1]+height+yoff;
165

  
166
        window.showAsDropDown(view);
167
        window.update(x,y,w,h);
168
        }
169
      }
170
    catch( IllegalArgumentException iae )
171
      {
172
      // ignore, this means window is 'not attached to window manager' -
173
      // which most probably is because we are already exiting the app.
174
      }
175
    }
176

  
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

  
179
  private void prevObject(InfoActivity act, int numObjects)
180
    {
181
    mObjectOrdinal--;
182
    if( mObjectOrdinal<0 ) mObjectOrdinal=numObjects-1;
183

  
184
    act.changeObject(mObjectOrdinal);
185
    mPane.updatePane(act,mObjectOrdinal);
186
    }
187

  
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

  
190
  private void nextObject(InfoActivity act, int numObjects)
191
    {
192
    mObjectOrdinal++;
193
    if( mObjectOrdinal>=numObjects ) mObjectOrdinal=0;
194

  
195
    act.changeObject(mObjectOrdinal);
196
    mPane.updatePane(act,mObjectOrdinal);
197
    }
198

  
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

  
201
  private void setupPrevButton(final InfoActivity act)
202
    {
203
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
204
    mPrevButton = new TransparentImageButton(act,R.drawable.ui_left,params);
205

  
206
    mPrevButton.setOnClickListener( new View.OnClickListener()
207
      {
208
      @Override
209
      public void onClick(View v)
210
        {
211
        int numObjects = RubikObjectList.getNumObjects();
212
        prevObject(act,numObjects);
213
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
214
        }
215
      });
216
    }
217

  
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

  
220
  private void setupNextButton(final InfoActivity act)
221
    {
222
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
223
    mNextButton = new TransparentImageButton(act,R.drawable.ui_right,params);
224

  
225
    mNextButton.setOnClickListener( new View.OnClickListener()
226
      {
227
      @Override
228
      public void onClick(View v)
229
        {
230
        int numObjects = RubikObjectList.getNumObjects();
231
        nextObject(act,numObjects);
232
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
233
        }
234
      });
235
    }
236

  
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

  
239
  private void setupTextView(final InfoActivity act, final float height, int numObjects)
240
    {
241
    int padding = (int)(height*PADDING);
242
    int margin  = (int)(height*MARGIN);
243
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,2.0f);
244
    params.topMargin    = margin;
245
    params.bottomMargin = margin;
246
    params.leftMargin   = margin;
247
    params.rightMargin  = margin;
248

  
249
    mMovesText = new TextView(act);
250
    mMovesText.setTextSize(20);
251
    mMovesText.setLayoutParams(params);
252
    mMovesText.setPadding(padding,0,padding,0);
253
    mMovesText.setGravity(Gravity.CENTER);
254
    mMovesText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
255
    mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
256
    }
257

  
258 42
///////////////////////////////////////////////////////////////////////////////////////////////////
259 43

  
260 44
  void onAttachedToWindow(final InfoActivity act, final int objectOrdinal)
261 45
    {
262
    int numObjects = RubikObjectList.getNumObjects();
263 46
    int width = act.getScreenWidthInPixels();
264
    int height= act.getScreenHeightInPixels();
265
    int barHeight = act.getHeightBar();
266
    mButtonSize = height*TEXT_SIZE;
267
    mObjectOrdinal = objectOrdinal;
268 47

  
269 48
    LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
270 49
    LinearLayout.LayoutParams paramsM = new LinearLayout.LayoutParams(width/2, LinearLayout.LayoutParams.MATCH_PARENT);
......
277 56
    LinearLayout layoutRight= new LinearLayout(act);
278 57
    layoutRight.setLayoutParams(paramsR);
279 58

  
280
    int popupW = (int)(POPUP_W*width);
281
    int popupH = (int)(height-barHeight);
282

  
283
    setupObjectButton(act,popupW,popupH);
284
    setupPrevButton(act);
285
    setupNextButton(act);
286
    setupTextView(act,height,numObjects);
287 59
    setupBackButton(act);
288

  
289
    layoutLeft.addView(mObjectButton);
290
    layoutMid.addView(mPrevButton);
291
    layoutMid.addView(mMovesText);
292
    layoutMid.addView(mNextButton);
293 60
    layoutRight.addView(mBackButton);
294 61

  
295 62
    LinearLayout layout = act.findViewById(R.id.lowerBar);
......
298 65
    layout.addView(layoutMid);
299 66
    layout.addView(layoutRight);
300 67

  
301
    mPane = new InfoScreenPane(act,mObjectOrdinal);
68
    mPane = new InfoScreenPane(act,objectOrdinal);
302 69
    }
303 70
}
src/main/java/org/distorted/main/MainActivity.java
34 34
import com.google.firebase.inappmessaging.FirebaseInAppMessaging;
35 35

  
36 36
import org.distorted.bandaged.BandagedActivity;
37
import org.distorted.config.ConfigActivity;
37 38
import org.distorted.info.InfoActivity;
38 39
import org.distorted.dialogs.RubikDialogAbout;
39 40
import org.distorted.dialogs.RubikDialogCreators;
......
402 403
      startActivity(intent);
403 404
      }
404 405

  
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

  
408
    public void switchToConfig(int objectOrdinal)
409
      {
410
      Intent intent = new Intent(this, ConfigActivity.class);
411
      intent.putExtra("obj", objectOrdinal);
412
      startActivity(intent);
413
      }
414

  
405 415
///////////////////////////////////////////////////////////////////////////////////////////////////
406 416

  
407 417
    public void switchToBandagedCreator(int objectOrdinal)
src/main/java/org/distorted/main/MainObjectPopup.java
64 64

  
65 65
    RubikObject object = RubikObjectList.getObject(ordinal);
66 66

  
67
    ///////// SOLVER //////////////////////////////////////////////////
67 68
    Button b1 = layout.findViewById(R.id.objectSolver);
68 69

  
69 70
    if( object!=null && object.hasSolver() )
......
87 88
      }
88 89
    else b1.setVisibility(GONE);
89 90

  
91
    ///////// PATTERN /////////////////////////////////////////////////
90 92
    Button b2 = layout.findViewById(R.id.objectPattern);
91 93

  
92 94
    if( object!=null && object.hasPatterns() )
......
110 112
      }
111 113
    else b2.setVisibility(GONE);
112 114

  
115
    ///////// TUTORIALS ///////////////////////////////////////////////
113 116
    Button b3 = layout.findViewById(R.id.objectTutorial);
114 117

  
115 118
    if( object!=null && object.hasExtras() )
......
133 136
      }
134 137
    else b3.setVisibility(GONE);
135 138

  
139
    ///////// INFO ////////////////////////////////////////////////////
136 140
    Button b4 = layout.findViewById(R.id.objectInfo);
137 141

  
138
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,levelHeight);
139
    params.setMargins(marginH,firstButtonShown ? marginV : marginH,marginH,marginV);
140
    b4.setLayoutParams(params);
142
    LinearLayout.LayoutParams paramsInfo = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,levelHeight);
143
    paramsInfo.setMargins(marginH,firstButtonShown ? marginV : marginH,marginH,marginV);
144
    b4.setLayoutParams(paramsInfo);
141 145
    b4.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
142 146

  
143 147
    b4.setOnClickListener( new View.OnClickListener()
......
150 154
        }
151 155
      });
152 156

  
157
    ///////// CONFIG //////////////////////////////////////////////////
158
    Button b5 = layout.findViewById(R.id.objectConfig);
159

  
160
    LinearLayout.LayoutParams paramsConfig = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,levelHeight);
161
    paramsConfig.setMargins(marginH,marginV,marginH,marginV);
162
    b5.setLayoutParams(paramsConfig);
163
    b5.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
164

  
165
    b5.setOnClickListener( new View.OnClickListener()
166
      {
167
      @Override
168
      public void onClick(View v)
169
        {
170
        mPopup.dismiss();
171
        act.switchToConfig(ordinal);
172
        }
173
      });
174

  
175
    ///////// LEVELS //////////////////////////////////////////////////
153 176
    TextView levels = layout.findViewById(R.id.objectLevels);
154 177
    levels.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
155 178

  
src/main/res/layout/config.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:id="@+id/mainLayout"
4
    android:layout_width="match_parent"
5
    android:layout_height="match_parent"
6
    android:background="@color/light_grey"
7
    android:orientation="vertical">
8

  
9
    <org.distorted.config.ConfigSurfaceView
10
        android:id="@+id/configSurfaceView"
11
        android:layout_width="match_parent"
12
        android:layout_height="0dp"
13
        android:layout_weight="1.3"/>
14

  
15
    <LinearLayout
16
        android:id="@+id/configLayout"
17
        android:layout_width="match_parent"
18
        android:layout_height="0dp"
19
        android:layout_weight="1.0"
20
        android:layout_marginLeft="5dp"
21
        android:layout_marginRight="5dp"
22
        android:layout_marginBottom="5dp"
23
        android:paddingLeft="5dp"
24
        android:paddingRight="5dp"
25
        android:background="@color/grey"
26
        android:orientation="vertical" >
27

  
28
        <TextView
29
            android:id="@+id/configTextStickers"
30
            android:layout_width="fill_parent"
31
            android:layout_height="wrap_content"
32
            android:gravity="center"
33
            android:textSize="26sp"
34
            android:text="@string/config_name"/>
35

  
36
    </LinearLayout>
37

  
38
    <LinearLayout
39
        android:id="@+id/lowerBar"
40
        android:layout_width="match_parent"
41
        android:layout_height="100dp"
42
        android:layout_gravity="end"
43
        android:orientation="horizontal"
44
        android:background="@color/light_grey">
45
    </LinearLayout>
46

  
47
</LinearLayout>
src/main/res/layout/object_popup.xml
50 50
        android:backgroundTint="@color/dark_grey"
51 51
        android:gravity="center"/>
52 52

  
53
    <Button
54
        android:id="@+id/objectConfig"
55
        android:text="@string/object_config"
56
        android:layout_width="match_parent"
57
        android:layout_height="wrap_content"
58
        android:paddingRight="10dp"
59
        android:paddingLeft="10dp"
60
        android:singleLine="true"
61
        android:backgroundTint="@color/dark_grey"
62
        android:gravity="center"/>
63

  
53 64
   <TextView
54 65
       android:id="@+id/objectLevels"
55 66
       android:layout_width="match_parent"
src/main/res/values-de/strings.xml
60 60
    <string name="object_pattern">Muster</string>
61 61
    <string name="object_tutorial">Tutorials</string>
62 62
    <string name="object_info">Info</string>
63
    <string name="object_config">Konfig</string>
63 64

  
64 65
    <string name="stars">Sterne</string>
65 66
    <string name="scores">Highscores</string>
src/main/res/values-es/strings.xml
60 60
    <string name="object_pattern">Patrones</string>
61 61
    <string name="object_tutorial">Tutoriales</string>
62 62
    <string name="object_info">Información</string>
63
    <string name="object_config">Config</string>
63 64

  
64 65
    <string name="stars">Estrellas</string>
65 66
    <string name="scores">Leaderboard</string>
src/main/res/values-fr/strings.xml
60 60
    <string name="object_pattern">Motifs</string>
61 61
    <string name="object_tutorial">Tutoriels</string>
62 62
    <string name="object_info">Info</string>
63
    <string name="object_config">Config</string>
63 64

  
64 65
    <string name="stars">Étoiles</string>
65 66
    <string name="scores">Meilleurs scores</string>
src/main/res/values-ja/strings.xml
60 60
    <string name="object_pattern">パターン</string>
61 61
    <string name="object_tutorial">チュートリアル</string>
62 62
    <string name="object_info">情報</string>
63
    <string name="object_config">構成</string>
63 64

  
64 65
    <string name="stars">星</string>
65 66
    <string name="scores">ハイスコア</string>
src/main/res/values-ko/strings.xml
60 60
    <string name="object_pattern">패턴</string>
61 61
    <string name="object_tutorial">튜토리얼</string>
62 62
    <string name="object_info">정보</string>
63
    <string name="object_config">구성</string>
63 64

  
64 65
    <string name="stars">별</string>
65 66
    <string name="scores">고득점</string>
src/main/res/values-pl/strings.xml
60 60
    <string name="object_pattern">Wzory</string>
61 61
    <string name="object_tutorial">Tutoriale</string>
62 62
    <string name="object_info">Info</string>
63
    <string name="object_config">Konfig</string>
63 64

  
64 65
    <string name="stars">Gwiazdki</string>
65 66
    <string name="scores">Lista najlepszych</string>
src/main/res/values-ru/strings.xml
60 60
    <string name="object_pattern">Узоры</string>
61 61
    <string name="object_tutorial">Учебники</string>
62 62
    <string name="object_info">Инфо</string>
63
    <string name="object_config">Конфиг</string>
63 64

  
64 65
    <string name="stars">Звезды</string>
65 66
    <string name="scores">Высокие баллы</string>
src/main/res/values-zh-rCN/strings.xml
60 60
    <string name="object_pattern">图案</string>
61 61
    <string name="object_tutorial">教程</string>
62 62
    <string name="object_info">信息</string>
63
    <string name="object_config">配置</string>
63 64

  
64 65
    <string name="stars">星星</string>
65 66
    <string name="scores">高分</string>
src/main/res/values-zh-rTW/strings.xml
60 60
    <string name="object_pattern">圖案</string>
61 61
    <string name="object_tutorial">教學</string>
62 62
    <string name="object_info">資訊</string>
63
    <string name="object_config">配置</string>
63 64

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff