Project

General

Profile

« Previous | Next » 

Revision c7238c67

Added by Leszek Koltunski over 2 years ago

IAP part 5: new 'Purchase' activity.

View differences:

src/main/AndroidManifest.xml
32 32
        <activity android:name="org.distorted.config.ConfigActivity" android:exported="false" android:screenOrientation="portrait"/>
33 33
        <activity android:name="org.distorted.bandaged.BandagedCreatorActivity" android:exported="false" android:screenOrientation="portrait"/>
34 34
        <activity android:name="org.distorted.bandaged.BandagedPlayActivity" android:exported="false" android:screenOrientation="portrait"/>
35
        <activity android:name="org.distorted.purchase.PurchaseActivity" android:exported="false" android:screenOrientation="portrait"/>
35 36

  
36 37
        <service
37 38
            android:name="org.distorted.messaging.RubikMessagingService"
src/main/java/org/distorted/bandaged/BandagedCreatorActivity.java
25 25

  
26 26
import androidx.appcompat.app.AppCompatActivity;
27 27

  
28
import com.google.firebase.analytics.FirebaseAnalytics;
29

  
30 28
import org.distorted.dialogs.RubikDialogError;
31 29
import org.distorted.external.RubikFiles;
32 30
import org.distorted.library.main.DistortedLibrary;
......
54 52
                                   | View.SYSTEM_UI_FLAG_FULLSCREEN
55 53
                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
56 54

  
57
    private FirebaseAnalytics mFirebaseAnalytics;
58 55
    private static int mScreenWidth, mScreenHeight;
59 56
    private int mCurrentApiVersion;
60 57
    private BandagedCreatorScreen mScreen;
......
69 66
      setTheme(R.style.MaterialThemeNoActionBar);
70 67
      setContentView(R.layout.bandaged);
71 68

  
72
      mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
73

  
74 69
      DisplayMetrics displaymetrics = new DisplayMetrics();
75 70
      getWindowManager().getDefaultDisplay().getRealMetrics(displaymetrics);
76 71
      mScreenWidth =displaymetrics.widthPixels;
......
231 226

  
232 227
///////////////////////////////////////////////////////////////////////////////////////////////////
233 228
// PUBLIC API
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

  
236
    public FirebaseAnalytics getAnalytics()
237
      {
238
      return mFirebaseAnalytics;
239
      }
240

  
241 229
///////////////////////////////////////////////////////////////////////////////////////////////////
242 230

  
243 231
    public void changeObject(int x, int y, int z)
src/main/java/org/distorted/bandaged/BandagedPlayActivity.java
22 22

  
23 23
import androidx.appcompat.app.AppCompatActivity;
24 24

  
25
import com.google.firebase.analytics.FirebaseAnalytics;
26

  
27 25
import org.distorted.dialogs.RubikDialogError;
28 26
import org.distorted.external.RubikFiles;
29 27
import org.distorted.library.main.DistortedLibrary;
......
50 48
                                   | View.SYSTEM_UI_FLAG_FULLSCREEN
51 49
                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
52 50

  
53
    private FirebaseAnalytics mFirebaseAnalytics;
54 51
    private static int mScreenWidth, mScreenHeight;
55 52
    private int mCurrentApiVersion;
56 53
    private BandagedPlayScreen mScreen;
......
70 67
      Bundle b = getIntent().getExtras();
71 68
      mObjectName = b!=null ? b.getString("name") : "";
72 69

  
73
      mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
74

  
75 70
      DisplayMetrics displaymetrics = new DisplayMetrics();
76 71
      getWindowManager().getDefaultDisplay().getRealMetrics(displaymetrics);
77 72
      mScreenWidth =displaymetrics.widthPixels;
......
267 262
      changeIfDifferent(name,control);
268 263
      }
269 264

  
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

  
272
    public FirebaseAnalytics getAnalytics()
273
      {
274
      return mFirebaseAnalytics;
275
      }
276

  
277 265
///////////////////////////////////////////////////////////////////////////////////////////////////
278 266

  
279 267
    public int getHeightBar()
src/main/java/org/distorted/config/ConfigActivity.java
19 19
import android.view.WindowManager;
20 20
import android.widget.LinearLayout;
21 21
import androidx.appcompat.app.AppCompatActivity;
22
import com.google.firebase.analytics.FirebaseAnalytics;
23 22

  
24 23
import org.distorted.library.main.DistortedLibrary;
25 24
import org.distorted.objectlib.main.ObjectControl;
......
45 44
                                   | View.SYSTEM_UI_FLAG_FULLSCREEN
46 45
                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
47 46

  
48
    private FirebaseAnalytics mFirebaseAnalytics;
49 47
    private static int mScreenWidth, mScreenHeight;
50 48
    private int mCurrentApiVersion;
51 49
    private ConfigScreen mScreen;
......
66 64

  
67 65
      if(b != null) mObjectOrdinal = b.getInt("obj");
68 66

  
69
      mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
70

  
71 67
      DisplayMetrics displaymetrics = new DisplayMetrics();
72 68
      getWindowManager().getDefaultDisplay().getRealMetrics(displaymetrics);
73 69
      mScreenWidth =displaymetrics.widthPixels;
......
237 233
        }
238 234
      }
239 235

  
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

  
242
    public FirebaseAnalytics getAnalytics()
243
      {
244
      return mFirebaseAnalytics;
245
      }
246

  
247 236
///////////////////////////////////////////////////////////////////////////////////////////////////
248 237

  
249 238
    public int getHeightBar()
src/main/java/org/distorted/main/RubikActivity.java
48 48
import org.distorted.external.RubikNetwork;
49 49
import org.distorted.objects.RubikObject;
50 50
import org.distorted.objects.RubikObjectList;
51
import org.distorted.purchase.PurchaseActivity;
51 52
import org.distorted.screens.RubikScreenSolving;
52 53
import org.distorted.screens.ScreenList;
53 54
import org.distorted.screens.RubikScreenPlay;
......
656 657
      startActivity(intent);
657 658
      }
658 659

  
660
///////////////////////////////////////////////////////////////////////////////////////////////////
661

  
662
    public void switchToPurchase(int objectOrdinal)
663
      {
664
      Intent intent = new Intent(this, PurchaseActivity.class);
665
      intent.putExtra("obj", objectOrdinal);
666
      startActivity(intent);
667
      }
668

  
659 669
///////////////////////////////////////////////////////////////////////////////////////////////////
660 670

  
661 671
    public void reloadObject(String shortName)
src/main/java/org/distorted/purchase/PurchaseActivity.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.purchase;
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.main.DistortedLibrary;
24
import org.distorted.main.R;
25
import org.distorted.objectlib.main.ObjectControl;
26
import org.distorted.objectlib.main.TwistyObject;
27
import org.distorted.objects.RubikObject;
28
import org.distorted.objects.RubikObjectList;
29

  
30
import java.io.InputStream;
31

  
32
///////////////////////////////////////////////////////////////////////////////////////////////////
33

  
34
public class PurchaseActivity extends AppCompatActivity
35
{
36
    private static final int ACTIVITY_NUMBER = 5;
37
    private static final float RATIO_BAR  = 0.10f;
38

  
39
    public static final float DIALOG_BUTTON_SIZE  = 0.06f;
40
    public static final float MENU_BIG_TEXT_SIZE  = 0.05f;
41

  
42
    public static final int FLAGS =  View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
43
                                   | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
44
                                   | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
45
                                   | View.SYSTEM_UI_FLAG_FULLSCREEN
46
                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
47

  
48
    private static int mScreenWidth, mScreenHeight;
49
    private int mCurrentApiVersion;
50
    private PurchaseScreen mScreen;
51
    private int mObjectOrdinal;
52
    private int mHeightBar;
53

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

  
56
    @Override
57
    protected void onCreate(Bundle savedState)
58
      {
59
      super.onCreate(savedState);
60
      DistortedLibrary.onCreate(ACTIVITY_NUMBER);
61
      setTheme(R.style.MaterialThemeNoActionBar);
62
      setContentView(R.layout.purchase);
63

  
64
      Bundle b = getIntent().getExtras();
65

  
66
      if(b != null) mObjectOrdinal = b.getInt("obj");
67

  
68
      DisplayMetrics displaymetrics = new DisplayMetrics();
69
      getWindowManager().getDefaultDisplay().getRealMetrics(displaymetrics);
70
      mScreenWidth =displaymetrics.widthPixels;
71
      mScreenHeight=displaymetrics.heightPixels;
72

  
73
      hideNavigationBar();
74
      cutoutHack();
75
      computeBarHeights();
76
      }
77

  
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79
// this does not include possible insets
80

  
81
    private void computeBarHeights()
82
      {
83
      int barHeight = (int)(mScreenHeight*RATIO_BAR);
84
      mHeightBar = barHeight;
85

  
86
      LinearLayout layout = findViewById(R.id.lowerBar);
87
      ViewGroup.LayoutParams params = layout.getLayoutParams();
88
      params.height = barHeight;
89
      layout.setLayoutParams(params);
90
      }
91

  
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93

  
94
    private void hideNavigationBar()
95
      {
96
      mCurrentApiVersion = Build.VERSION.SDK_INT;
97

  
98
      if(mCurrentApiVersion >= Build.VERSION_CODES.KITKAT)
99
        {
100
        final View decorView = getWindow().getDecorView();
101

  
102
        decorView.setSystemUiVisibility(FLAGS);
103

  
104
        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener()
105
          {
106
          @Override
107
          public void onSystemUiVisibilityChange(int visibility)
108
            {
109
            if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0)
110
              {
111
              decorView.setSystemUiVisibility(FLAGS);
112
              }
113
            }
114
          });
115
        }
116
      }
117

  
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119
// do not avoid cutouts
120

  
121
    private void cutoutHack()
122
      {
123
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
124
        {
125
        getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
126
        }
127
      }
128

  
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

  
131
    @Override
132
    public void onWindowFocusChanged(boolean hasFocus)
133
      {
134
      super.onWindowFocusChanged(hasFocus);
135

  
136
      if(mCurrentApiVersion >= Build.VERSION_CODES.KITKAT && hasFocus)
137
        {
138
        getWindow().getDecorView().setSystemUiVisibility(FLAGS);
139
        }
140
      }
141

  
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143
    
144
    @Override
145
    protected void onPause() 
146
      {
147
      super.onPause();
148
      PurchaseSurfaceView view = findViewById(R.id.purchaseSurfaceView);
149
      view.onPause();
150
      DistortedLibrary.onPause(ACTIVITY_NUMBER);
151
      }
152

  
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154
    
155
    @Override
156
    protected void onResume() 
157
      {
158
      super.onResume();
159
      DistortedLibrary.onResume(ACTIVITY_NUMBER);
160
      PurchaseSurfaceView view = findViewById(R.id.purchaseSurfaceView);
161
      view.onResume();
162

  
163
      if( mScreen==null ) mScreen = new PurchaseScreen();
164
      mScreen.onAttachedToWindow(this,mObjectOrdinal);
165

  
166
      if( mObjectOrdinal>=0 && mObjectOrdinal< RubikObjectList.getNumObjects() )
167
        {
168
        RubikObject object = RubikObjectList.getObject(mObjectOrdinal);
169
        changeIfDifferent(object,mObjectOrdinal,view.getObjectControl());
170
        }
171
      }
172

  
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
    
175
    @Override
176
    protected void onDestroy() 
177
      {
178
      super.onDestroy();
179
      DistortedLibrary.onDestroy(ACTIVITY_NUMBER);
180
      }
181

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

  
184
    void OpenGLError()
185
      {
186
      RubikDialogError errDiag = new RubikDialogError();
187
      errDiag.show(getSupportFragmentManager(), null);
188
      }
189

  
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

  
192
    private void changeIfDifferent(RubikObject object,int ordinal,ObjectControl control)
193
      {
194
      if( object!=null )
195
        {
196
        int meshState          = object.getMeshState();
197
        int iconMode           = TwistyObject.MODE_NORM;
198
        InputStream jsonStream = object.getObjectStream(this);
199
        InputStream meshStream = object.getMeshStream(this);
200
        String name            = object.getUpperName();
201

  
202
        control.changeIfDifferent(ordinal,name,meshState,iconMode,jsonStream,meshStream);
203
        }
204
      }
205

  
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207
// PUBLIC API
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

  
210
    public void changeObject(int ordinal)
211
      {
212
      mObjectOrdinal = ordinal;
213
      RubikObject object = RubikObjectList.getObject(ordinal);
214
      PurchaseSurfaceView view = findViewById(R.id.purchaseSurfaceView);
215
      ObjectControl control = view.getObjectControl();
216
      changeIfDifferent(object,ordinal,control);
217
      }
218

  
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

  
221
    public void changeMeshState(RubikObject object, int ordinal)
222
      {
223
      if( object!=null )
224
        {
225
        PurchaseSurfaceView view = findViewById(R.id.purchaseSurfaceView);
226
        ObjectControl control = view.getObjectControl();
227

  
228
        int meshState          = object.getMeshState();
229
        int iconMode           = TwistyObject.MODE_NORM;
230
        InputStream jsonStream = object.getObjectStream(this);
231
        InputStream meshStream = object.getMeshStream(this);
232

  
233
        control.changeObject(ordinal,meshState,iconMode,jsonStream,meshStream);
234
        }
235
      }
236

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

  
239
    public int getHeightBar()
240
      {
241
      return mHeightBar;
242
      }
243

  
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

  
246
    public int getScreenWidthInPixels()
247
      {
248
      return mScreenWidth;
249
      }
250

  
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

  
253
    public int getScreenHeightInPixels()
254
      {
255
      return mScreenHeight;
256
      }
257

  
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

  
260
    public ObjectControl getControl()
261
      {
262
      PurchaseSurfaceView view = findViewById(R.id.purchaseSurfaceView);
263
      return view.getObjectControl();
264
      }
265

  
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267

  
268
    public static int getDrawableSize()
269
      {
270
      if( mScreenHeight<1000 )
271
        {
272
        return 0;
273
        }
274
      if( mScreenHeight<1600 )
275
        {
276
        return 1;
277
        }
278
      if( mScreenHeight<1900 )
279
        {
280
        return 2;
281
        }
282

  
283
      return 3;
284
      }
285

  
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287

  
288
    public static int getDrawable(int small, int medium, int big, int huge)
289
      {
290
      int size = getDrawableSize();
291

  
292
      switch(size)
293
        {
294
        case 0 : return small;
295
        case 1 : return medium;
296
        case 2 : return big;
297
        default: return huge;
298
        }
299
      }
300

  
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

  
303
    public boolean isVertical()
304
      {
305
      PurchaseSurfaceView view = findViewById(R.id.purchaseSurfaceView);
306
      return view.isVertical();
307
      }
308
}
src/main/java/org/distorted/purchase/PurchaseObjectLibInterface.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 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.purchase;
11

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

  
14
import org.distorted.library.message.EffectMessageSender;
15
import org.distorted.objectlib.BuildConfig;
16
import org.distorted.objectlib.helpers.BlockController;
17
import org.distorted.objectlib.helpers.ObjectLibInterface;
18

  
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
public class PurchaseObjectLibInterface implements ObjectLibInterface
22
{
23
  public void onWinEffectFinished(long startTime, long endTime, String debug, int scrambleNum) { }
24
  public void onScrambleEffectFinished() { }
25
  public void onBeginRotation() { }
26
  public void onSolved() { }
27
  public void onObjectCreated(long time) { }
28
  public void onReplaceModeDown(int cubit, int face) { }
29
  public void onReplaceModeUp() { }
30
  public void onFinishRotation(int axis, int row, int angle) { }
31
  public void failedToDrag() { }
32
  public void reportJSONError(String error, int ordinal) { }
33

  
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35

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

  
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

  
61
  private void reportUIProblem(int place, long pause, long resume, long time)
62
    {
63
    String error = "UI BLOCK "+place+" blocked for "+time;
64

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

  
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

  
81
  private void reportTouchProblem(int place, long pause, long resume, long time)
82
    {
83
    String error = "TOUCH BLOCK "+place+" blocked for "+time;
84

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

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

  
101
  private void reportThreadProblem(int place, long pause, long resume, long time)
102
    {
103
    String error = EffectMessageSender.reportState();
104

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

  
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

  
121
  public void reportBlockProblem(int type, int place, long pause, long resume, long time)
122
    {
123
    switch(type)
124
      {
125
      case BlockController.TYPE_UI    : reportUIProblem(place,pause,resume,time); break;
126
      case BlockController.TYPE_TOUCH : reportTouchProblem(place,pause,resume,time); break;
127
      case BlockController.TYPE_THREAD: reportThreadProblem(place,pause,resume,time); break;
128
      }
129
    }
130
}
src/main/java/org/distorted/purchase/PurchaseRenderer.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.purchase;
11

  
12
import android.opengl.GLSurfaceView;
13

  
14
import org.distorted.library.effect.EffectType;
15
import org.distorted.library.effect.VertexEffectQuaternion;
16
import org.distorted.library.effect.VertexEffectRotate;
17
import org.distorted.library.main.DistortedLibrary;
18
import org.distorted.library.main.DistortedScreen;
19
import org.distorted.objectlib.effects.BaseEffect;
20
import org.distorted.objectlib.main.ObjectControl;
21

  
22
import javax.microedition.khronos.egl.EGLConfig;
23
import javax.microedition.khronos.opengles.GL10;
24

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

  
27
public class PurchaseRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
28
{
29
   private final PurchaseSurfaceView mView;
30
   private final DistortedScreen mScreen;
31

  
32
///////////////////////////////////////////////////////////////////////////////////////////////////
33

  
34
   PurchaseRenderer(PurchaseSurfaceView v)
35
     {
36
     final float BRIGHTNESS = 0.333f;
37

  
38
     mView = v;
39
     mScreen = new DistortedScreen();
40
     mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
41
     }
42

  
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44

  
45
   @Override
46
   public void onDrawFrame(GL10 glUnused)
47
     {
48
     long time = System.currentTimeMillis();
49
     mView.getObjectControl().preRender();
50
     mScreen.render(time);
51
     }
52

  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

  
55
   @Override
56
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
57
      {
58
      mScreen.resize(width,height);
59
      mView.setScreenSize(width,height);
60
      }
61

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

  
64
   @Override
65
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
66
      {
67
      DistortedLibrary.setMax(EffectType.VERTEX, ObjectControl.MAX_QUATS+1);
68
      VertexEffectRotate.enable();
69
      VertexEffectQuaternion.enable();
70
      BaseEffect.Type.enableEffects();
71

  
72
      DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
73
      }
74

  
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

  
77
   public void distortedException(Exception ex)
78
     {
79
     android.util.Log.e("PURCHASE", "unexpected exception: "+ex.getMessage() );
80
     }
81

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

  
84
   DistortedScreen getScreen()
85
     {
86
     return mScreen;
87
     }
88
}
src/main/java/org/distorted/purchase/PurchaseScreen.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.purchase;
11

  
12
import android.os.Build;
13
import android.util.TypedValue;
14
import android.view.Gravity;
15
import android.view.View;
16
import android.widget.GridLayout;
17
import android.widget.ImageButton;
18
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.PopupCreator;
24
import org.distorted.helpers.TransparentImageButton;
25
import org.distorted.main.R;
26
import org.distorted.main.RubikActivity;
27
import org.distorted.objectlib.main.ObjectControl;
28
import org.distorted.objects.RubikObject;
29
import org.distorted.objects.RubikObjectList;
30

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

  
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

  
35
public class PurchaseScreen
36
{
37
  private static final int NUM_COLUMNS = 5;
38
  private static final int[] mLocation = new int[2];
39

  
40
  private TransparentImageButton mBackButton, mObjectButton, mPrevButton, mNextButton;
41
  private TextView mMovesText;
42
  private PopupWindow mObjectPopup;
43
  private PurchaseScreenPane mPane;
44
  private int mObjectOrdinal;
45
  private int mColCount, mRowCount, mMaxRowCount;
46
  private int mObjectSize;
47
  private int mBarHeight;
48
  private float mButtonSize;
49

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

  
52
  private void setupObjectWindow(final PurchaseActivity act, final float width, final float height)
53
    {
54
    int numObjects= RubikObjectList.getNumObjects();
55
    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
56
    mColCount = NUM_COLUMNS;
57

  
58
    int cubeSize  = (int)(width/9);
59
    int margin    = (int)(width*RubikActivity.LARGE_MARGIN);
60
    int padding   = (int)(width*RubikActivity.POPUP_PADDING);
61
    mObjectSize   = (int)(cubeSize + 2*margin + 0.5f);
62
    mMaxRowCount  = (int)((height-mBarHeight)/mObjectSize);
63

  
64
    ScrollView view = (ScrollView)inflate( act, R.layout.popup_object_simple, null);
65
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
66

  
67
    PopupCreator.createObjectGrid(objectGrid,act,mRowCount,mColCount,numObjects,margin,cubeSize,padding);
68

  
69
    for(int child=0; child<numObjects; child++)
70
      {
71
      final RubikObject obj = RubikObjectList.getObject(child);
72
      View v = objectGrid.getChildAt(child);
73
      ImageButton button = PopupCreator.getButton(obj,v);
74
      final int ordinal = child;
75

  
76
      button.setOnClickListener( new View.OnClickListener()
77
        {
78
        @Override
79
        public void onClick(View v)
80
          {
81
          if( act.getControl().isUINotBlocked() && mObjectOrdinal!=ordinal )
82
            {
83
            mObjectOrdinal = ordinal;
84
            act.changeObject(mObjectOrdinal);
85
            mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
86
            mPane.updatePane(act,mObjectOrdinal);
87
            }
88

  
89
          mObjectPopup.dismiss();
90
          }
91
        });
92
      }
93

  
94
    mObjectPopup = new PopupWindow(act);
95
    mObjectPopup.setFocusable(true);
96
    mObjectPopup.setContentView(view);
97
    }
98

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

  
101
  private void setupBackButton(final PurchaseActivity act)
102
    {
103
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_smallback,R.drawable.ui_medium_smallback, R.drawable.ui_big_smallback, R.drawable.ui_huge_smallback);
104
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
105
    mBackButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
106

  
107
    mBackButton.setOnClickListener( new View.OnClickListener()
108
      {
109
      @Override
110
      public void onClick(View v)
111
        {
112
        ObjectControl control = act.getControl();
113
        if( control!=null ) control.unblockEverything();
114
        act.finish();
115
        }
116
      });
117
    }
118

  
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

  
121
  private void setupObjectButton(final PurchaseActivity act, final int width)
122
    {
123
    final int margin= (int)(width*RubikActivity.SMALL_MARGIN);
124
    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);
125
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
126
    mObjectButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
127

  
128
    mObjectButton.setOnClickListener( new View.OnClickListener()
129
      {
130
      @Override
131
      public void onClick(View view)
132
        {
133
        if( mObjectPopup==null )
134
          {
135
          float height= act.getScreenHeightInPixels();
136
          setupObjectWindow(act,width,height);
137
          }
138

  
139
        if( act.getControl().isUINotBlocked())
140
          {
141
          int rowCount = Math.min(mMaxRowCount,mRowCount);
142
          View popupView = mObjectPopup.getContentView();
143
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
144
          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount+5*margin,margin,margin);
145
          }
146
        }
147
      });
148
    }
149

  
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
152

  
153
  private void displayPopup(PurchaseActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
154
    {
155
    View topLayout = act.findViewById(R.id.mainLayout);
156
    boolean isFullScreen;
157

  
158
    if( topLayout!=null )
159
      {
160
      topLayout.getLocationOnScreen(mLocation);
161
      isFullScreen = (mLocation[1]==0);
162
      }
163
    else
164
      {
165
      isFullScreen = true;
166
      }
167

  
168
    try
169
      {
170
      // if on Android 11 or we are fullscreen
171
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
172
        {
173
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
174
        window.update(view, w, h);
175
        }
176
      else  // Android 10 or below in pop-up mode or split-screen mode
177
        {
178
        view.getLocationOnScreen(mLocation);
179
        int width  = view.getWidth();
180
        int height = view.getHeight();
181
        int x = mLocation[0]+(width-w)/2;
182
        int y = mLocation[1]+height+yoff;
183

  
184
        window.showAsDropDown(view);
185
        window.update(x,y,w,h);
186
        }
187
      }
188
    catch( IllegalArgumentException iae )
189
      {
190
      // ignore, this means window is 'not attached to window manager' -
191
      // which most probably is because we are already exiting the app.
192
      }
193
    }
194

  
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

  
197
  private void prevObject(PurchaseActivity act, int numObjects)
198
    {
199
    mObjectOrdinal--;
200
    if( mObjectOrdinal<0 ) mObjectOrdinal=numObjects-1;
201

  
202
    act.changeObject(mObjectOrdinal);
203
    mPane.updatePane(act,mObjectOrdinal);
204
    }
205

  
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

  
208
  private void nextObject(PurchaseActivity act, int numObjects)
209
    {
210
    mObjectOrdinal++;
211
    if( mObjectOrdinal>=numObjects ) mObjectOrdinal=0;
212

  
213
    act.changeObject(mObjectOrdinal);
214
    mPane.updatePane(act,mObjectOrdinal);
215
    }
216

  
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

  
219
  private void setupPrevButton(final PurchaseActivity act)
220
    {
221
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_left,R.drawable.ui_medium_left, R.drawable.ui_big_left, R.drawable.ui_huge_left);
222
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
223
    mPrevButton = new TransparentImageButton(act,icon,TransparentImageButton.GRAVITY_MIDDLE,params);
224

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

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

  
239
  private void setupNextButton(final PurchaseActivity act)
240
    {
241
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_right,R.drawable.ui_medium_right, R.drawable.ui_big_right, R.drawable.ui_huge_right);
242
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
243
    mNextButton = new TransparentImageButton(act,icon,TransparentImageButton.GRAVITY_MIDDLE,params);
244

  
245
    mNextButton.setOnClickListener( new View.OnClickListener()
246
      {
247
      @Override
248
      public void onClick(View v)
249
        {
250
        int numObjects = RubikObjectList.getNumObjects();
251
        nextObject(act,numObjects);
252
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
253
        }
254
      });
255
    }
256

  
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

  
259
  private void setupTextView(final PurchaseActivity act, final float width, int numObjects)
260
    {
261
    int padding = (int)(width*RubikActivity.PADDING);
262
    int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
263
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,2.0f);
264
    params.topMargin    = margin;
265
    params.bottomMargin = margin;
266
    params.leftMargin   = margin;
267
    params.rightMargin  = margin;
268

  
269
    mMovesText = new TextView(act);
270
    mMovesText.setTextSize(20);
271
    mMovesText.setLayoutParams(params);
272
    mMovesText.setPadding(padding,0,padding,0);
273
    mMovesText.setGravity(Gravity.CENTER);
274
    mMovesText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
275
    mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
276
    }
277

  
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

  
280
  void onAttachedToWindow(final PurchaseActivity act, final int objectOrdinal)
281
    {
282
    int numObjects = RubikObjectList.getNumObjects();
283
    int width = act.getScreenWidthInPixels();
284
    mBarHeight = act.getHeightBar();
285
    mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
286
    mObjectOrdinal = objectOrdinal;
287

  
288
    LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
289
    LinearLayout.LayoutParams paramsM = new LinearLayout.LayoutParams(width/2, LinearLayout.LayoutParams.MATCH_PARENT);
290
    LinearLayout.LayoutParams paramsR = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
291

  
292
    LinearLayout layoutLeft = new LinearLayout(act);
293
    layoutLeft.setLayoutParams(paramsL);
294
    LinearLayout layoutMid  = new LinearLayout(act);
295
    layoutMid.setLayoutParams(paramsM);
296
    LinearLayout layoutRight= new LinearLayout(act);
297
    layoutRight.setLayoutParams(paramsR);
298

  
299
    setupObjectButton(act,width);
300
    setupPrevButton(act);
301
    setupNextButton(act);
302
    setupTextView(act,width,numObjects);
303
    setupBackButton(act);
304

  
305
    layoutLeft.addView(mObjectButton);
306
    layoutMid.addView(mPrevButton);
307
    layoutMid.addView(mMovesText);
308
    layoutMid.addView(mNextButton);
309
    layoutRight.addView(mBackButton);
310

  
311
    LinearLayout layout = act.findViewById(R.id.lowerBar);
312
    layout.removeAllViews();
313
    layout.addView(layoutLeft);
314
    layout.addView(layoutMid);
315
    layout.addView(layoutRight);
316

  
317
    mPane = new PurchaseScreenPane(act,mObjectOrdinal);
318
    }
319
}
src/main/java/org/distorted/purchase/PurchaseScreenPane.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.purchase;
11

  
12
import android.graphics.PorterDuff;
13
import android.util.TypedValue;
14
import android.widget.ImageView;
15
import android.widget.LinearLayout;
16
import android.widget.RadioButton;
17
import android.widget.RadioGroup;
18
import android.widget.TextView;
19

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

  
25
import java.io.InputStream;
26

  
27
import static org.distorted.objectlib.main.TwistyObject.MESH_FAST;
28
import static org.distorted.objectlib.main.TwistyObject.MESH_NICE;
29

  
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31

  
32
public class PurchaseScreenPane
33
{
34
  private static final int[] IDS =
35
    {
36
    R.id.purchaseDifficulty0,
37
    R.id.purchaseDifficulty1,
38
    R.id.purchaseDifficulty2,
39
    R.id.purchaseDifficulty3,
40
    R.id.purchaseDifficulty4
41
    };
42

  
43
  private static final int[] IMAGES =
44
    {
45
    R.drawable.difficulty1,
46
    R.drawable.difficulty2,
47
    R.drawable.difficulty3,
48
    R.drawable.difficulty4,
49
    R.drawable.difficulty5,
50
    };
51

  
52
  private static final int NUM_IDS         = IDS.length;
53
  public  static final float PADDING_RATIO = 0.025f;
54
  private static final float TEXT_RATIO    = 0.042f;
55
  private static final float RADIO_RATIO   = 0.900f;
56

  
57
  private int mObjectOrdinal;
58
  private boolean mProgramatic;
59

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

  
62
  private void switchMeshState(PurchaseActivity act, int meshState)
63
    {
64
    RubikObjectList.setMeshState(mObjectOrdinal,meshState);
65
    RubikObject object = RubikObjectList.getObject(mObjectOrdinal);
66
    act.changeMeshState(object,mObjectOrdinal);
67
    }
68

  
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

  
71
  void updatePane(PurchaseActivity act, int objectOrdinal)
72
    {
73
    RubikObject object = RubikObjectList.getObject(objectOrdinal);
74

  
75
    if( object!=null )
76
      {
77
      InputStream stream = object.getObjectStream(act);
78

  
79
      mObjectOrdinal = objectOrdinal;
80
      JsonReader reader = JsonReader.getInstance();
81
      String name,author;
82
      int year, difficulty;
83

  
84
      try
85
        {
86
        reader.parseJsonFileMetadata(stream);
87
        name       = reader.getObjectName();
88
        author     = reader.getInventor();
89
        year       = reader.getYearOfInvention();
90
        difficulty = reader.getComplexity();
91
        }
92
      catch(Exception ex)
93
        {
94
        name = "?";
95
        author = "?";
96
        year = 0;
97
        difficulty = 0;
98
        }
99

  
100
      String both = year>0 ? author+" "+year : author;
101

  
102
      LinearLayout layout = act.findViewById(R.id.purchaseLayout);
103
      TextView view = layout.findViewById(R.id.purchaseDetailsName2);
104
      view.setText(name);
105
      view = layout.findViewById(R.id.purchaseDetailsAuthor2);
106
      view.setText(both);
107

  
108
      if( difficulty<0       ) difficulty=0;
109
      if( difficulty>NUM_IDS ) difficulty=NUM_IDS;
110

  
111
      for(int i=0; i<NUM_IDS; i++)
112
        {
113
        ImageView image = layout.findViewById(IDS[i]);
114
        image.setImageResource(IMAGES[i]);
115
        image.setColorFilter( difficulty==i ? 0xffff0000 : 0xffffffff, PorterDuff.Mode.MULTIPLY );
116
        }
117

  
118
      int meshState = object.getMeshState();
119
      int id = meshState==MESH_NICE ? R.id.meshNice : R.id.meshSimple;
120
      RadioButton button = act.findViewById(id);
121

  
122
      mProgramatic = true;
123
      button.setChecked(true);
124
      mProgramatic = false;
125
      }
126
    }
127

  
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

  
130
  PurchaseScreenPane(final PurchaseActivity act, int objectOrdinal)
131
    {
132
    int width = act.getScreenWidthInPixels();
133
    float textSize = width*TEXT_RATIO;
134
    int padding = (int)(width*PADDING_RATIO);
135

  
136
    LinearLayout configLayout    = act.findViewById(R.id.purchaseLayout);
137
    LinearLayout nameLayout      = configLayout.findViewById(R.id.purchaseLayoutName);
138
    LinearLayout authorLayout    = configLayout.findViewById(R.id.purchaseLayoutAuthor);
139
    LinearLayout difficultyLayout= configLayout.findViewById(R.id.purchaseLayoutDifficulty);
140
    LinearLayout meshLayout      = configLayout.findViewById(R.id.purchaseLayoutMesh);
141

  
142
    nameLayout.setPadding(padding,padding,padding,padding/2);
143
    authorLayout.setPadding(padding,padding/2,padding,padding/2);
144
    difficultyLayout.setPadding(padding,padding/2,padding,padding/2);
145
    meshLayout.setPadding(padding,padding/2,padding,padding);
146

  
147
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 1.00f);
148
    params.bottomMargin = 0;
149
    params.topMargin    = padding;
150
    params.leftMargin   = padding;
151
    params.rightMargin  = padding;
152

  
153
    nameLayout.setLayoutParams(params);
154
    authorLayout.setLayoutParams(params);
155
    difficultyLayout.setLayoutParams(params);
156
    meshLayout.setLayoutParams(params);
157

  
158
    TextView text;
159
    text = nameLayout.findViewById(R.id.purchaseDetailsName1);
160
    text.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
161
    text = nameLayout.findViewById(R.id.purchaseDetailsName2);
162
    text.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
163
    text = authorLayout.findViewById(R.id.purchaseDetailsAuthor1);
164
    text.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
165
    text = authorLayout.findViewById(R.id.purchaseDetailsAuthor2);
166
    text.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
167
    text = difficultyLayout.findViewById(R.id.purchaseDifficultyTitle);
168
    text.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
169
    text = meshLayout.findViewById(R.id.purchaseMeshTitle);
170
    text.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
171

  
172
    RadioButton butt1 = meshLayout.findViewById(R.id.meshNice);
173
    butt1.setTextSize(TypedValue.COMPLEX_UNIT_PX, RADIO_RATIO*textSize);
174
    RadioButton butt2 = meshLayout.findViewById(R.id.meshSimple);
175
    butt2.setTextSize(TypedValue.COMPLEX_UNIT_PX, RADIO_RATIO*textSize);
176

  
177
    LinearLayout layoutDiff = difficultyLayout.findViewById(R.id.purchaseDifficultyLayout);
178
    layoutDiff.setPadding(padding,padding,padding,padding);
179

  
180
    RadioGroup radioGroup = meshLayout.findViewById(R.id.meshRadioGroup);
181

  
182
    radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
183
      {
184
      @Override
185
      public void onCheckedChanged(RadioGroup group, int checkedId)
186
        {
187
        if( !mProgramatic )
188
          {
189
          int meshState = checkedId == R.id.meshNice ? MESH_NICE : MESH_FAST;
190
          switchMeshState( act, meshState );
191
          }
192
        }
193
      });
194

  
195
    updatePane(act,objectOrdinal);
196
    }
197
}
src/main/java/org/distorted/purchase/PurchaseSurfaceView.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.purchase;
11

  
12
import android.app.ActivityManager;
13
import android.content.Context;
14
import android.content.pm.ConfigurationInfo;
15
import android.opengl.GLES30;
16
import android.opengl.GLSurfaceView;
17
import android.util.AttributeSet;
18

  
19
import com.google.firebase.crashlytics.FirebaseCrashlytics;
20

  
21
import org.distorted.objectlib.main.ObjectControl;
22
import org.distorted.objectlib.main.TwistyObjectNode;
23

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

  
26
public class PurchaseSurfaceView extends GLSurfaceView
27
{
28
    private ObjectControl mObjectController;
29
    private PurchaseRenderer mRenderer;
30
    private int mScreenWidth, mScreenHeight;
31
    private boolean mCreated;
32

  
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

  
35
    void setScreenSize(int width, int height)
36
      {
37
      mScreenWidth = width;
38
      mScreenHeight= height;
39
      mObjectController.setScreenSize(width,height);
40
      mObjectController.setObjectScale(1.00f);
41

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

  
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

  
53
    boolean isVertical()
54
      {
55
      return mScreenHeight>mScreenWidth;
56
      }
57

  
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

  
60
    ObjectControl getObjectControl()
61
      {
62
      return mObjectController;
63
      }
64

  
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66
// PUBLIC API
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

  
69
    public PurchaseSurfaceView(Context context, AttributeSet attrs)
70
      {
71
      super(context,attrs);
72

  
73
      mCreated = false;
74

  
75
      if(!isInEditMode())
76
        {
77
        PurchaseActivity act = (PurchaseActivity)context;
78
        PurchaseObjectLibInterface ref = new PurchaseObjectLibInterface();
79
        mObjectController = new ObjectControl(act,ref);
80
        mObjectController.setRotateOnCreation(true);
81
        mRenderer = new PurchaseRenderer(this);
82

  
83
        final ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
84

  
85
        try
86
          {
87
          final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
88
          int esVersion = configurationInfo.reqGlEsVersion>>16;
89
          setEGLContextClientVersion(esVersion);
90
          setRenderer(mRenderer);
91
          }
92
        catch(Exception ex)
93
          {
94
          act.OpenGLError();
95

  
96
          String shading = GLES30.glGetString(GLES30.GL_SHADING_LANGUAGE_VERSION);
97
          String version = GLES30.glGetString(GLES30.GL_VERSION);
98
          String vendor  = GLES30.glGetString(GLES30.GL_VENDOR);
99
          String renderer= GLES30.glGetString(GLES30.GL_RENDERER);
100

  
101
          FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
102
          crashlytics.setCustomKey("GLSL Version"  , shading );
103
          crashlytics.setCustomKey("GL version"    , version );
104
          crashlytics.setCustomKey("GL Vendor "    , vendor  );
105
          crashlytics.setCustomKey("GLSL renderer" , renderer);
106
          crashlytics.recordException(ex);
107
          }
108
        }
109
      }
110

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

  
113
    @Override
114
    public void onPause()
115
      {
116
      super.onPause();
117
      mObjectController.onPause();
118
      }
119

  
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

  
122
    @Override
123
    public void onResume()
124
      {
125
      super.onResume();
126
      mObjectController.onResume();
127
      }
128
}
129

  
src/main/java/org/distorted/screens/RubikScreenPlay.java
201 201
        @Override
202 202
        public void onClick(View v)
203 203
          {
204
          if( act.getControl().isUINotBlocked() && ScreenList.getCurrentScreen()== ScreenList.PLAY )
204
          if( obj!=null && act.getControl().isUINotBlocked() && ScreenList.getCurrentScreen()==ScreenList.PLAY )
205 205
            {
206
            RubikObjectList.setCurrObject(ordinal);
207
            act.changeObject(ordinal,true);
208
            if( mMenuPopup!=null ) setupLevelColors(act);
209
            mMovesController.clearMoves(act);
206
            if( obj.isFree() )
207
              {
208
              RubikObjectList.setCurrObject(ordinal);
209
              act.changeObject(ordinal,true);
210
              if( mMenuPopup!=null ) setupLevelColors(act);
211
              mMovesController.clearMoves(act);
212
              }
213
            else
214
              {
215
              act.switchToPurchase(ordinal);
216
              }
210 217
            }
211 218

  
212 219
          if( mObjectPopup!=null ) mObjectPopup.dismiss();
src/main/java/org/distorted/tutorials/TutorialActivity.java
22 22

  
23 23
import androidx.appcompat.app.AppCompatActivity;
24 24

  
25
import com.google.firebase.analytics.FirebaseAnalytics;
26

  
27 25
import org.distorted.library.main.DistortedLibrary;
28 26

  
29 27
import org.distorted.objectlib.main.ObjectControl;
......
53 51
                                   | View.SYSTEM_UI_FLAG_FULLSCREEN
54 52
                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
55 53

  
56
    private FirebaseAnalytics mFirebaseAnalytics;
57 54
    private static int mScreenWidth, mScreenHeight;
58 55
    private int mCurrentApiVersion;
59 56
    private TutorialScreen mScreen;
......
79 76
        mObjectOrdinal = b.getInt("obj");
80 77
        }
81 78

  
82
      mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
83

  
84 79
      DisplayMetrics displaymetrics = new DisplayMetrics();
85 80
      getWindowManager().getDefaultDisplay().getRealMetrics(displaymetrics);
86 81
      mScreenWidth =displaymetrics.widthPixels;
......
238 233

  
239 234
///////////////////////////////////////////////////////////////////////////////////////////////////
240 235
// PUBLIC API
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242

  
243
    public FirebaseAnalytics getAnalytics()
244
      {
245
      return mFirebaseAnalytics;
246
      }
247

  
248 236
///////////////////////////////////////////////////////////////////////////////////////////////////
249 237

  
250 238
    public int getScreenWidthInPixels()
src/main/res/layout/purchase.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:orientation="vertical">
7

  
8
    <org.distorted.purchase.PurchaseSurfaceView
9
        android:id="@+id/purchaseSurfaceView"
10
        android:layout_width="match_parent"
11
        android:layout_height="0dp"
12
        android:layout_weight="1.3"/>
13

  
14
    <LinearLayout
15
        android:id="@+id/purchaseLayout"
16
        android:layout_width="match_parent"
17
        android:layout_height="0dp"
18
        android:layout_weight="1.0"
19
        android:background="@color/light_grey"
20
        android:orientation="vertical" >
21

  
22
        <LinearLayout
23
            android:id="@+id/purchaseLayoutName"
24
            android:layout_width="fill_parent"
25
            android:layout_height="0dp"
26
            android:layout_weight="1"
27
            android:paddingLeft="5dp"
28
            android:paddingRight="5dp"
29
            android:background="@color/grey"
30
            android:orientation="horizontal">
31

  
32
            <TextView
33
                android:id="@+id/purchaseDetailsName1"
34
                android:layout_width="0dp"
35
                android:layout_height="match_parent"
36
                android:layout_weight="1.0"
37
                android:gravity="center_vertical|start"
38
                android:paddingStart="5dp"
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff