Project

General

Profile

Download (24.7 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / screens / RubikScreenPlay.java @ ca280c3f

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.screens;
21

    
22
import java.lang.ref.WeakReference;
23

    
24
import android.app.Activity;
25
import android.content.Context;
26
import android.content.SharedPreferences;
27
import android.content.res.ColorStateList;
28
import android.content.res.Resources;
29
import android.os.Build;
30
import android.os.Bundle;
31
import android.util.TypedValue;
32
import android.view.Gravity;
33
import android.view.LayoutInflater;
34
import android.view.View;
35
import android.widget.Button;
36
import android.widget.GridLayout;
37
import android.widget.ImageButton;
38
import android.widget.LinearLayout;
39
import android.widget.PopupWindow;
40
import android.widget.RelativeLayout;
41
import android.widget.TextView;
42

    
43
import org.distorted.dialogs.RubikDialogUpdates;
44
import org.distorted.external.RubikNetwork;
45
import org.distorted.external.RubikScores;
46
import org.distorted.external.RubikUpdates;
47

    
48
import org.distorted.main.R;
49
import org.distorted.main.RubikActivity;
50
import org.distorted.dialogs.RubikDialogAbout;
51
import org.distorted.dialogs.RubikDialogPattern;
52
import org.distorted.dialogs.RubikDialogScores;
53
import org.distorted.dialogs.RubikDialogTutorial;
54
import org.distorted.helpers.TransparentImageButton;
55
import org.distorted.objectlib.main.ObjectControl;
56
import org.distorted.objects.MainEntry;
57
import org.distorted.objects.MainEntryList;
58
import org.distorted.objects.RubikObject;
59
import org.distorted.objects.RubikObjectList;
60

    
61
import static android.view.View.inflate;
62

    
63
///////////////////////////////////////////////////////////////////////////////////////////////////
64

    
65
public class RubikScreenPlay extends RubikScreenBase implements RubikNetwork.Updatee
66
  {
67
  public static final int NUM_COLUMNS  = 5;
68
  public static final int LEVELS_SHOWN = 8;
69
  private static final int NUM_BUTTONS = 5;
70
  private static final int[] mLocation = new int[2];
71

    
72
  private TransparentImageButton mObjButton, mMenuButton, mSolveButton, mScrambleButton;
73
  private PopupWindow mObjectPopup, mMenuPopup;
74
  private WeakReference<RubikActivity> mWeakAct;
75
  private TextView mBubbleUpdates;
76
  private Button[] mLevel;
77
  private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight, mMenuButtonHeight, mMenuTextSize;
78
  private int mLevelValue;
79
  private int mColCount, mRowCount, mMaxRowCount;
80
  private int mUpperBarHeight;
81
  private boolean mShouldReactToEndOfScrambling;
82
  private float mScreenWidth;
83

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

    
86
  void leaveScreen(RubikActivity act)
87
    {
88

    
89
    }
90

    
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

    
93
  void enterScreen(final RubikActivity act)
94
    {
95
    mWeakAct = new WeakReference<>(act);
96
    mScreenWidth = act.getScreenWidthInPixels();
97
    mUpperBarHeight = act.getHeightUpperBar();
98

    
99
    mMenuButtonHeight = (int)(mScreenWidth*RubikActivity.MENU_BUTTON_HEIGHT);
100
    mMenuTextSize     = (int)(mScreenWidth*RubikActivity.MENU_MAIN_TEXT_SIZE);
101

    
102
    mObjectPopup = null;
103

    
104
    // TOP ////////////////////////////
105
    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
106
    layoutTop.removeAllViews();
107

    
108
    setupSolveButton(act);
109
    layoutTop.addView(mSolveButton);
110
    setupMenuButton(act,mScreenWidth);
111
    layoutTop.addView(mMenuButton);
112
    setupScrambleButton(act);
113
    layoutTop.addView(mScrambleButton);
114

    
115
    // BOTTOM /////////////////////////
116
    setupObjectButton(act,mScreenWidth);
117
    createBottomPane(act,mObjButton,null);
118
    }
119

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

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

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

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

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

    
154
  private void setupMenuButton(final RubikActivity act, final float width)
155
    {
156
    final int icon = RubikActivity.getDrawable(R.drawable.ui_small_menu,R.drawable.ui_medium_menu, R.drawable.ui_big_menu, R.drawable.ui_huge_menu);
157
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
158
    mMenuButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
159

    
160
    mMenuButton.setOnClickListener( new View.OnClickListener()
161
      {
162
      @Override
163
      public void onClick(View view)
164
        {
165
        if( mMenuPopup==null )
166
          {
167
          float width = act.getScreenWidthInPixels();
168
          setupMenuWindow(act,width);
169
          }
170

    
171
        if( act.getControl().isUINotBlocked())
172
          {
173
          View popupView = mMenuPopup.getContentView();
174
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
175
          setupLevelColors(act);
176
          displayPopup(act,view,mMenuPopup,mMenuLayoutWidth,mMenuLayoutHeight,(int)(-mMenuLayoutWidth/2 + width/6),0);
177
          }
178
        }
179
      });
180
    }
181

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

    
184
  private void setupObjectWindow(final RubikActivity act, final float width, final float height)
185
    {
186
    MainEntryList list = MainEntryList.getInstance();
187
    int numEntries = list.getNumOfEntries();
188
    mRowCount = (numEntries + NUM_COLUMNS-1) / NUM_COLUMNS;
189
    mColCount = NUM_COLUMNS;
190

    
191
    int cubeSize = (int)(width/9);
192
    int margin   = (int)(width*RubikActivity.LARGE_MARGIN);
193
    mObjectSize  = (int)(cubeSize + 2*margin + 0.5f);
194
    mMaxRowCount = (int)((height-1.8f*mUpperBarHeight)/mObjectSize);
195

    
196
    LinearLayout view = (LinearLayout)inflate( act, R.layout.popup_object, null);
197
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
198

    
199
    GridLayout.Spec[] rowSpecs = new GridLayout.Spec[mRowCount];
200
    GridLayout.Spec[] colSpecs = new GridLayout.Spec[mColCount];
201

    
202
    objectGrid.setColumnCount(mColCount);
203
    objectGrid.setRowCount(mRowCount);
204

    
205
    RelativeLayout bottomLayout = view.findViewById(R.id.bottomLayout);
206
    setupBottomLayout(act,bottomLayout);
207

    
208
    mObjectPopup = new PopupWindow(act);
209
    mObjectPopup.setFocusable(true);
210
    mObjectPopup.setContentView(view);
211

    
212
    int[] nextInRow = new int[mRowCount];
213

    
214
    for(int row=0; row<mRowCount; row++)
215
      {
216
      rowSpecs[row] = GridLayout.spec(row);
217
      nextInRow[row]= 0;
218
      }
219
    for(int col=0; col<mColCount; col++)
220
      {
221
      colSpecs[col] = GridLayout.spec(col);
222
      }
223

    
224
    for(int entry=0; entry<numEntries; entry++)
225
      {
226
      final MainEntry mainEntry = list.getEntry(entry);
227
      int row = entry/NUM_COLUMNS;
228
      ImageButton button = new ImageButton(act);
229
      if( mainEntry!=null ) mainEntry.setIconTo(act,button);
230

    
231
      button.setOnClickListener( new View.OnClickListener()
232
        {
233
        @Override
234
        public void onClick(View v)
235
          {
236
          if( act.getControl().isUINotBlocked() && ScreenList.getCurrentScreen()== ScreenList.PLAY )
237
            {
238
            int type = mainEntry!=null ? mainEntry.getType() : -1;
239

    
240
            if( type==MainEntry.TYPE_OBJECT )
241
              {
242
              int ordinal = mainEntry.getOrdinal();
243
              RubikObjectList.setCurrObject(ordinal);
244
              act.changeObject(ordinal,true);
245
              if( mMenuPopup!=null ) setupLevelColors(act);
246
              mMovesController.clearMoves(act);
247
              }
248
            else if( type==MainEntry.TYPE_CREATOR )
249
              {
250
              act.switchToBandagedCreator();
251
              }
252
            }
253

    
254
          if( mObjectPopup!=null ) mObjectPopup.dismiss();
255
          }
256
        });
257

    
258
      GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpecs[row],colSpecs[nextInRow[row]]);
259
      params.bottomMargin = margin;
260
      params.topMargin    = margin;
261
      params.leftMargin   = margin;
262
      params.rightMargin  = margin;
263

    
264
      params.width = cubeSize;
265
      params.height= cubeSize;
266

    
267
      nextInRow[row]++;
268

    
269
      objectGrid.addView(button, params);
270
      }
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
  private void setupBottomLayout(final RubikActivity act, final RelativeLayout layout)
276
    {
277
    int iconT = RubikActivity.getDrawable(R.drawable.ui_small_tutorial,R.drawable.ui_medium_tutorial, R.drawable.ui_big_tutorial, R.drawable.ui_huge_tutorial);
278
    int iconD = RubikActivity.getDrawable(R.drawable.ui_small_download,R.drawable.ui_medium_download, R.drawable.ui_big_download, R.drawable.ui_huge_download);
279
    int iconI = RubikActivity.getDrawable(R.drawable.ui_small_info,R.drawable.ui_medium_info, R.drawable.ui_big_info, R.drawable.ui_huge_info);
280

    
281
    ImageButton buttonTut = layout.findViewById(R.id.buttonTut);
282
    ImageButton buttonDow = layout.findViewById(R.id.buttonDow);
283
    ImageButton buttonInf = layout.findViewById(R.id.buttonInf);
284

    
285
    buttonTut.setImageResource(iconT);
286
    buttonDow.setImageResource(iconD);
287
    buttonInf.setImageResource(iconI);
288

    
289
    TypedValue outValue = new TypedValue();
290
    act.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, outValue, true);
291
    buttonTut.setBackgroundResource(outValue.resourceId);
292
    buttonDow.setBackgroundResource(outValue.resourceId);
293
    buttonInf.setBackgroundResource(outValue.resourceId);
294

    
295
    buttonTut.setOnClickListener( new View.OnClickListener()
296
      {
297
      @Override
298
      public void onClick(View v)
299
        {
300
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
301
        RubikDialogTutorial tDiag = new RubikDialogTutorial();
302
        tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
303
        }
304
      });
305

    
306
    buttonDow.setOnClickListener( new View.OnClickListener()
307
      {
308
      @Override
309
      public void onClick(View v)
310
        {
311
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
312
        RubikDialogUpdates uDiag = new RubikDialogUpdates();
313
        uDiag.show( act.getSupportFragmentManager(), RubikDialogUpdates.getDialogTag() );
314
        }
315
      });
316

    
317
    buttonInf.setOnClickListener( new View.OnClickListener()
318
      {
319
      @Override
320
      public void onClick(View v)
321
        {
322
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
323
        int currObject = RubikObjectList.getCurrObject();
324
        act.switchConfig(currObject);
325
        }
326
      });
327

    
328
    mBubbleUpdates = layout.findViewById(R.id.bubbleUpdates);
329
    mBubbleUpdates.setVisibility(View.INVISIBLE);
330

    
331
    RubikNetwork network = RubikNetwork.getInstance();
332
    network.signUpForUpdates(this);
333
    }
334

    
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336

    
337
  void setupSolveButton(final RubikActivity act)
338
    {
339
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_solve,R.drawable.ui_medium_cube_solve, R.drawable.ui_big_cube_solve, R.drawable.ui_huge_cube_solve);
340
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
341
    mSolveButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE,params);
342

    
343
    mSolveButton.setOnClickListener( new View.OnClickListener()
344
      {
345
      @Override
346
      public void onClick(View v)
347
        {
348
        act.getControl().solveObject();
349
        mMovesController.clearMoves(act);
350
        }
351
      });
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

    
356
  private void setupScrambleButton(final RubikActivity act)
357
    {
358
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_scramble,R.drawable.ui_medium_cube_scramble, R.drawable.ui_big_cube_scramble, R.drawable.ui_huge_cube_scramble);
359
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
360
    mScrambleButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
361

    
362
    mScrambleButton.setOnClickListener( new View.OnClickListener()
363
      {
364
      @Override
365
      public void onClick(View v)
366
        {
367
        int currObject = RubikObjectList.getCurrObject();
368
        RubikObject object = RubikObjectList.getObject(currObject);
369
        int numScrambles = object==null ? 0 : 2*object.getNumScramble();
370
        mShouldReactToEndOfScrambling = false;
371
        act.getControl().fastScrambleObject(numScrambles);
372
        }
373
      });
374
    }
375

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

    
378
  private void setupMenuWindow(final RubikActivity act, final float width)
379
    {
380
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
381
    final View layout = layoutInflater.inflate(R.layout.popup_menu, null);
382

    
383
    mMenuPopup = new PopupWindow(act);
384
    mMenuPopup.setContentView(layout);
385
    mMenuPopup.setFocusable(true);
386
    int padding = (int)(width*RubikActivity.MEDIUM_MARGIN);
387

    
388
    mMenuLayoutWidth = (int)(width*0.6f);
389
    mMenuLayoutHeight= (int)( padding + NUM_BUTTONS*(mMenuButtonHeight+padding) + 4*mMenuButtonHeight+6*padding);
390

    
391
    layout.setPadding(padding,0,padding,0);
392

    
393
    Button highScores = layout.findViewById(R.id.menuHighScores);
394
    highScores.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
395
    highScores.setOnClickListener( new View.OnClickListener()
396
        {
397
        @Override
398
        public void onClick(View v)
399
          {
400
          mMenuPopup.dismiss();
401
          Bundle sBundle = new Bundle();
402
          int currObject = RubikObjectList.getCurrObject();
403
          sBundle.putInt("tab", currObject );
404
          sBundle.putBoolean("submitting", false);
405
          RubikDialogScores scores = new RubikDialogScores();
406
          scores.setArguments(sBundle);
407
          scores.show(act.getSupportFragmentManager(), null);
408
          }
409
        });
410

    
411
    Button prettyPatterns = layout.findViewById(R.id.menuPrettyPatterns);
412
    prettyPatterns.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
413
    prettyPatterns.setOnClickListener( new View.OnClickListener()
414
        {
415
        @Override
416
        public void onClick(View v)
417
          {
418
          mMenuPopup.dismiss();
419
          RubikDialogPattern pDiag = new RubikDialogPattern();
420
          pDiag.show( act.getSupportFragmentManager(), RubikDialogPattern.getDialogTag() );
421
          }
422
        });
423

    
424
    Button solver = layout.findViewById(R.id.menuSolver);
425
    solver.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
426
    solver.setOnClickListener( new View.OnClickListener()
427
        {
428
        @Override
429
        public void onClick(View v)
430
          {
431
          mMenuPopup.dismiss();
432
          ScreenList.switchScreen(act, ScreenList.SVER);
433
          }
434
        });
435

    
436
    Button tutorials = layout.findViewById(R.id.menuTutorials);
437
    tutorials.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
438
    tutorials.setOnClickListener( new View.OnClickListener()
439
        {
440
        @Override
441
        public void onClick(View v)
442
          {
443
          mMenuPopup.dismiss();
444
          RubikDialogTutorial tDiag = new RubikDialogTutorial();
445
          tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
446
          }
447
        });
448

    
449
    Button about = layout.findViewById(R.id.menuAbout);
450
    about.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
451
    about.setOnClickListener( new View.OnClickListener()
452
        {
453
        @Override
454
        public void onClick(View v)
455
          {
456
          mMenuPopup.dismiss();
457
          RubikDialogAbout aDiag = new RubikDialogAbout();
458
          aDiag.show(act.getSupportFragmentManager(), null);
459
          }
460
        });
461

    
462
    TextView levels = layout.findViewById(R.id.menuLevels);
463
    levels.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
464

    
465
    setupLevelButtons(act,layout,padding);
466
    }
467

    
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469

    
470
  private void setupLevelButtons(RubikActivity act, View layout, int padding)
471
    {
472
    int sizeW = (mMenuLayoutWidth-4*padding)/3;
473
    int sizeH = (int)(sizeW*0.8f);
474
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(sizeW,sizeH);
475
    params.setMargins(padding/2,0,padding/2,0);
476

    
477
    mLevel = new Button[LEVELS_SHOWN+1];
478

    
479
    mLevel[0] = layout.findViewById(R.id.level1);
480
    mLevel[1] = layout.findViewById(R.id.level2);
481
    mLevel[2] = layout.findViewById(R.id.level3);
482
    mLevel[3] = layout.findViewById(R.id.level4);
483
    mLevel[4] = layout.findViewById(R.id.level5);
484
    mLevel[5] = layout.findViewById(R.id.level6);
485
    mLevel[6] = layout.findViewById(R.id.level7);
486
    mLevel[7] = layout.findViewById(R.id.level8);
487
    mLevel[8] = layout.findViewById(R.id.levelM);
488

    
489
    for(int i=0; i<=LEVELS_SHOWN; i++)
490
      {
491
      final int ii = i;
492
      mLevel[i].setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
493
      mLevel[i].setLayoutParams(params);
494
      mLevel[i].setOnClickListener( new View.OnClickListener()
495
        {
496
        @Override
497
        public void onClick(View v)
498
          {
499
          ObjectControl control = act.getControl();
500

    
501
          if(control.isUINotBlocked())
502
            {
503
            if( mMenuPopup!=null ) mMenuPopup.dismiss();
504

    
505
            int currObject = RubikObjectList.getCurrObject();
506
            RubikObject object = RubikObjectList.getObject(currObject);
507
            final int scrambles = ii<LEVELS_SHOWN ? ii+1 : (object==null ? 0 : object.getNumScramble());
508
            mLevelValue = ii+1;
509
            mShouldReactToEndOfScrambling = true;
510
            control.scrambleObject(scrambles);
511
            }
512
          }
513
        });
514
      }
515
    }
516

    
517
///////////////////////////////////////////////////////////////////////////////////////////////////
518

    
519
  private void setupLevelColors(RubikActivity act)
520
    {
521
    int currObject = RubikObjectList.getCurrObject();
522
    int dbLevel = RubikObjectList.getDBLevel(currObject);
523
    RubikScores scores = RubikScores.getInstance();
524
    Resources res = act.getResources();
525
    ColorStateList colorG = ColorStateList.valueOf(res.getColor(R.color.green));
526
    ColorStateList colorD = ColorStateList.valueOf(res.getColor(R.color.dark_grey));
527

    
528
    for(int i=0; i<=LEVELS_SHOWN; i++)
529
      {
530
      int level = i<LEVELS_SHOWN ? i : dbLevel;
531
      boolean isSolved = scores.isSolved(currObject,level);
532
      mLevel[i].setBackgroundTintList( isSolved ? colorG : colorD);
533
      }
534
    }
535

    
536
///////////////////////////////////////////////////////////////////////////////////////////////////
537
// This is necessary! Otherwise the ObjectPopup will not be re-created next time and we will still
538
// hold a reference to the old instance of the RubikActivity class (because setupObjectWindow is not
539
// going to be called)
540
// An reference to the old instance of RubikActivity will cause all sorts of strange issues.
541

    
542
  public void savePreferences(SharedPreferences.Editor editor)
543
    {
544
    editor.putInt("play_LevelValue", mLevelValue );
545

    
546
    if( mObjectPopup!=null )
547
      {
548
      mObjectPopup.dismiss();
549
      mObjectPopup = null;
550
      }
551

    
552
    if( mMenuPopup!=null )
553
      {
554
      mMenuPopup.dismiss();
555
      mMenuPopup = null;
556
      }
557
    }
558

    
559
///////////////////////////////////////////////////////////////////////////////////////////////////
560

    
561
  public void restorePreferences(SharedPreferences preferences)
562
    {
563
    mLevelValue = preferences.getInt("play_LevelValue", 0);
564
    }
565

    
566
///////////////////////////////////////////////////////////////////////////////////////////////////
567
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
568

    
569
  private void displayPopup(RubikActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
570
    {
571
    View topLayout = act.findViewById(R.id.relativeLayout);
572
    boolean isFullScreen;
573

    
574
    if( topLayout!=null )
575
      {
576
      topLayout.getLocationOnScreen(mLocation);
577
      isFullScreen = (mLocation[1]==0);
578
      }
579
    else
580
      {
581
      isFullScreen = true;
582
      }
583

    
584
    try
585
      {
586
      // if on Android 11 or we are fullscreen
587
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
588
        {
589
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
590
        window.update(view, w, h);
591
        }
592
      else  // Android 10 or below in pop-up mode or split-screen mode
593
        {
594
        view.getLocationOnScreen(mLocation);
595
        int width  = view.getWidth();
596
        int height = view.getHeight();
597
        int x = mLocation[0]+(width-w)/2;
598
        int y = mLocation[1]+height+yoff;
599

    
600
        window.showAsDropDown(view);
601
        window.update(x,y,w,h);
602
        }
603
      }
604
    catch( IllegalArgumentException iae )
605
      {
606
      // ignore, this means window is 'not attached to window manager' -
607
      // which most probably is because we are already exiting the app.
608
      }
609
    }
610

    
611
///////////////////////////////////////////////////////////////////////////////////////////////////
612

    
613
  public int getLevel()
614
    {
615
    return mLevelValue;
616
    }
617

    
618
///////////////////////////////////////////////////////////////////////////////////////////////////
619

    
620
  public void recreatePopup()
621
    {
622
    mObjectPopup = null;
623
    }
624

    
625
///////////////////////////////////////////////////////////////////////////////////////////////////
626

    
627
  public boolean shouldReactToEndOfScrambling()
628
    {
629
    return mShouldReactToEndOfScrambling;
630
    }
631

    
632
///////////////////////////////////////////////////////////////////////////////////////////////////
633

    
634
  public void receiveUpdate(RubikUpdates updates)
635
    {
636
    Activity act = mWeakAct.get();
637

    
638
    if( act!=null )
639
      {
640
      act.runOnUiThread(new Runnable()
641
        {
642
        @Override
643
        public void run()
644
          {
645
          int num = updates.getCompletedNumber();
646

    
647
          if( num>0 )
648
            {
649
            String shownNum = String.valueOf(num);
650
            mBubbleUpdates.setText(shownNum);
651
            mBubbleUpdates.setVisibility(View.VISIBLE);
652
            int height = (int)(0.05f*mScreenWidth);
653
            mBubbleUpdates.setTextSize(TypedValue.COMPLEX_UNIT_PX,height);
654
            }
655
         else
656
            {
657
            mBubbleUpdates.setVisibility(View.INVISIBLE);
658
            }
659
          }
660
        });
661
      }
662
    }
663

    
664
///////////////////////////////////////////////////////////////////////////////////////////////////
665

    
666
  public void errorUpdate()
667
    {
668
    android.util.Log.e("D", "Screen: Error receiving update");
669
    }
670
  }
(5-5/10)