Project

General

Profile

« Previous | Next » 

Revision cc8ab8e3

Added by Leszek Koltunski almost 2 years ago

Progress witth new UI.

View differences:

src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
234 234
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "3");
235 235

  
236 236
        RubikScreenPlay play = (RubikScreenPlay)ScreenList.PLAY.getScreenClass();
237
        play.recreatePopup();
237
        play.recreateListOfObjects();
238 238

  
239 239
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "4");
240 240

  
src/main/java/org/distorted/main/RubikObjectLibInterface.java
235 235
    {
236 236
    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
237 237

  
238
    if( play.shouldReactToEndOfScrambling() )
238
   // if( play.shouldReactToEndOfScrambling() )
239 239
      {
240 240
      RubikActivity act = mAct.get();
241 241
      RubikScores.getInstance().incrementNumPlays();
src/main/java/org/distorted/objects/RubikObjectList.java
400 400
    if( mObject!=ordinal )
401 401
      {
402 402
      mObject = ordinal;
403
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
404
      play.setCurrObject(act);
405 403
      return true;
406 404
      }
407 405

  
src/main/java/org/distorted/screens/RubikScreenDetails.java
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 android.app.Activity;
23
import android.content.Context;
24
import android.content.SharedPreferences;
25
import android.content.res.Resources;
26
import android.graphics.drawable.BitmapDrawable;
27
import android.os.Build;
28
import android.os.Bundle;
29
import android.util.TypedValue;
30
import android.view.Gravity;
31
import android.view.LayoutInflater;
32
import android.view.View;
33
import android.widget.Button;
34
import android.widget.GridLayout;
35
import android.widget.ImageButton;
36
import android.widget.LinearLayout;
37
import android.widget.PopupWindow;
38
import android.widget.RelativeLayout;
39
import android.widget.TextView;
40

  
41
import org.distorted.dialogs.RubikDialogAbout;
42
import org.distorted.dialogs.RubikDialogPattern;
43
import org.distorted.dialogs.RubikDialogScores;
44
import org.distorted.dialogs.RubikDialogTutorial;
45
import org.distorted.dialogs.RubikDialogUpdates;
46
import org.distorted.external.RubikNetwork;
47
import org.distorted.external.RubikScores;
48
import org.distorted.external.RubikUpdates;
49
import org.distorted.helpers.TransparentButton;
50
import org.distorted.helpers.TransparentImageButton;
51
import org.distorted.main.R;
52
import org.distorted.main.RubikActivity;
53
import org.distorted.objectlib.main.ObjectControl;
54
import org.distorted.objects.RubikObject;
55
import org.distorted.objects.RubikObjectList;
56

  
57
import java.lang.ref.WeakReference;
58

  
59
import static android.view.View.inflate;
60

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

  
63
public class RubikScreenDetails extends RubikScreenBase implements RubikNetwork.Updatee
64
  {
65
  public static final int NUM_COLUMNS  = 5;
66
  public static final int LEVELS_SHOWN = 10;
67

  
68
  private static final int[] BUTTON_LABELS = { R.string.scores,
69
                                               R.string.patterns,
70
                                               R.string.solver,
71
                                               R.string.tutorials,
72
                                               R.string.bandaged,
73
                                               R.string.about };
74
  private static final int NUM_BUTTONS = BUTTON_LABELS.length;
75

  
76
  private static final float LAST_BUTTON = 1.5f;
77
  private static final int[] mLocation = new int[2];
78

  
79
  private TransparentImageButton mObjButton, mMenuButton, mSolveButton, mScrambleButton;
80
  private TransparentButton mPlayButton;
81
  private PopupWindow mObjectPopup, mMenuPopup, mPlayPopup;
82
  private LinearLayout mPlayLayout;
83
  private TextView mBubbleUpdates;
84
  private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight, mPlayLayoutWidth;
85
  private int mLevelValue;
86
  private float mButtonSize, mMenuItemSize, mMenuTextSize;
87
  private int mColCount, mRowCount, mMaxRowCount;
88
  private int mUpperBarHeight;
89
  private boolean mShouldReactToEndOfScrambling;
90
  private int mBottomHeight;
91
  private float mScreenWidth;
92
  private WeakReference<RubikActivity> mWeakAct;
93

  
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

  
96
  void leaveScreen(RubikActivity act)
97
    {
98

  
99
    }
100

  
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

  
103
  void enterScreen(final RubikActivity act)
104
    {
105
    mWeakAct = new WeakReference<>(act);
106
    int numObjects = RubikObjectList.getNumObjects();
107
    mScreenWidth = act.getScreenWidthInPixels();
108
    mUpperBarHeight = act.getHeightUpperBar();
109

  
110
    mMenuTextSize = mScreenWidth*RubikActivity.MENU_MED_TEXT_SIZE;
111
    mButtonSize   = mScreenWidth*RubikActivity.BUTTON_TEXT_SIZE;
112
    mMenuItemSize = mScreenWidth*RubikActivity.MENU_ITEM_SIZE;
113

  
114
    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
115
    mColCount = NUM_COLUMNS;
116

  
117
    // TOP ////////////////////////////
118
    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
119
    layoutTop.removeAllViews();
120

  
121
    setupObjectButton(act,mScreenWidth);
122
    layoutTop.addView(mObjButton);
123

  
124
    setupMenuButton(act,mScreenWidth);
125
    layoutTop.addView(mMenuButton);
126

  
127
    setupPlayButton(act,mScreenWidth);
128
    layoutTop.addView(mPlayButton);
129

  
130
    setupSolveButton(act);
131
    setupScrambleButton(act);
132
    createBottomPane(act,mSolveButton,mScrambleButton);
133
    }
134

  
135
//////////////////////////////////////////////////////////////////////////////////////////////////
136

  
137
  private void setupObjectButton(final RubikActivity act, final float width)
138
    {
139
    final int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
140
    final int lMargin = (int)(width*RubikActivity.LARGE_MARGIN);
141
    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);
142
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
143
    mObjButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
144

  
145
    mObjButton.setOnClickListener( new View.OnClickListener()
146
      {
147
      @Override
148
      public void onClick(View view)
149
        {
150
        if( mObjectPopup==null )
151
          {
152
          float width = act.getScreenWidthInPixels();
153
          float height= act.getScreenHeightInPixels();
154
          setupObjectWindow(act,width,height);
155
          }
156

  
157
        if( act.getControl().isUINotBlocked())
158
          {
159
          int rowCount = Math.min(mMaxRowCount,mRowCount);
160
          View popupView = mObjectPopup.getContentView();
161
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
162
          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount+mBottomHeight+2*lMargin+5*margin,margin,margin);
163
          }
164
        }
165
      });
166
    }
167

  
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

  
170
  private void setupPlayButton(final RubikActivity act, final float width)
171
    {
172
    final int margin = (int)(width*RubikActivity.SMALL_MARGIN);
173

  
174
    mPlayButton = new TransparentButton(act, R.string.play, mButtonSize);
175

  
176
    mPlayButton.setOnClickListener( new View.OnClickListener()
177
      {
178
      @Override
179
      public void onClick(View view)
180
        {
181
        if( mPlayPopup==null )
182
          {
183
          float width = act.getScreenWidthInPixels();
184
          setupPlayWindow(act,width);
185
          }
186

  
187
        if( act.getControl().isUINotBlocked())
188
          {
189
          adjustSolvedIcons();
190
          float height= act.getScreenHeightInPixels();
191
          final int maxHeight= (int)(0.9f*(height-mUpperBarHeight) );
192
          View popupView = mPlayPopup.getContentView();
193
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
194
          final int object  = RubikObjectList.getCurrObject();
195
          final int dbLevel = RubikObjectList.getDBLevel(object);
196
          final int levelsShown = Math.min(dbLevel,LEVELS_SHOWN);
197
          final int popupHeight = (int)(levelsShown*(mMenuItemSize+margin)+3*margin+mMenuItemSize*(LAST_BUTTON-1.0f));
198
          final int realHeight = Math.min(popupHeight,maxHeight);
199
          displayPopup(act,view,mPlayPopup,mPlayLayoutWidth,realHeight,margin,margin);
200
          }
201
        }
202
      });
203
    }
204

  
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

  
207
  private void setupMenuButton(final RubikActivity act, final float width)
208
    {
209
    final int margin = (int)(width*RubikActivity.SMALL_MARGIN);
210
    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);
211
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
212
    mMenuButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
213

  
214
    mMenuButton.setOnClickListener( new View.OnClickListener()
215
      {
216
      @Override
217
      public void onClick(View view)
218
        {
219
        if( mMenuPopup==null )
220
          {
221
          float width = act.getScreenWidthInPixels();
222
          setupMenuWindow(act,width);
223
          }
224

  
225
        if( act.getControl().isUINotBlocked())
226
          {
227
          View popupView = mMenuPopup.getContentView();
228
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
229
          displayPopup(act,view,mMenuPopup,mMenuLayoutWidth,mMenuLayoutHeight,(int)(-width/12),margin);
230
          }
231
        }
232
      });
233
    }
234

  
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

  
237
  private void setupObjectWindow(final RubikActivity act, final float width, final float height)
238
    {
239
    int cubeWidth = (int)(width/9);
240
    int margin = (int)(width*RubikActivity.LARGE_MARGIN);
241
    mObjectSize = (int)(cubeWidth + 2*margin + 0.5f);
242
    mMaxRowCount = (int)((height-1.8f*mUpperBarHeight)/mObjectSize);
243

  
244
    LinearLayout view = (LinearLayout)inflate( act, R.layout.popup_object, null);
245
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
246

  
247
    GridLayout.Spec[] rowSpecs = new GridLayout.Spec[mRowCount];
248
    GridLayout.Spec[] colSpecs = new GridLayout.Spec[mColCount];
249

  
250
    objectGrid.setColumnCount(mColCount);
251
    objectGrid.setRowCount(mRowCount);
252

  
253
    RelativeLayout bottomLayout = view.findViewById(R.id.bottomLayout);
254
    setupBottomLayout(act,bottomLayout);
255

  
256
    mObjectPopup = new PopupWindow(act);
257
    mObjectPopup.setFocusable(true);
258
    mObjectPopup.setContentView(view);
259

  
260
    int[] nextInRow = new int[mRowCount];
261

  
262
    for(int row=0; row<mRowCount; row++)
263
      {
264
      rowSpecs[row] = GridLayout.spec(row);
265
      nextInRow[row]= 0;
266
      }
267
    for(int col=0; col<mColCount; col++)
268
      {
269
      colSpecs[col] = GridLayout.spec(col);
270
      }
271

  
272
    int numObjects = RubikObjectList.getNumObjects();
273

  
274
    for(int object=0; object<numObjects; object++)
275
      {
276
      final int ordinal = object;
277
      final RubikObject rObject = RubikObjectList.getObject(object);
278
      int row = object/NUM_COLUMNS;
279
      ImageButton button = new ImageButton(act);
280
      if( rObject!=null ) rObject.setIconTo(act,button);
281

  
282
      button.setOnClickListener( new View.OnClickListener()
283
        {
284
        @Override
285
        public void onClick(View v)
286
          {
287
          if( act.getControl().isUINotBlocked() && ScreenList.getCurrentScreen()== ScreenList.PLAY )
288
            {
289
            RubikObjectList.setCurrObject(act,ordinal);
290
            act.changeObject(ordinal,true);
291
            if( mPlayLayout!=null ) adjustLevels(act);
292
            mMovesController.clearMoves(act);
293
            }
294

  
295
          if( mObjectPopup!=null ) mObjectPopup.dismiss();
296
          }
297
        });
298

  
299
      GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpecs[row],colSpecs[nextInRow[row]]);
300
      params.bottomMargin = margin;
301
      params.topMargin    = margin;
302
      params.leftMargin   = margin;
303
      params.rightMargin  = margin;
304

  
305
      params.width = cubeWidth;
306
      params.height= cubeWidth;
307

  
308
      nextInRow[row]++;
309

  
310
      objectGrid.addView(button, params);
311
      }
312
    }
313

  
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315

  
316
  private void setupBottomLayout(final RubikActivity act, final RelativeLayout layout)
317
    {
318
    int iconT = RubikActivity.getDrawable(R.drawable.ui_small_tutorial,R.drawable.ui_medium_tutorial, R.drawable.ui_big_tutorial, R.drawable.ui_huge_tutorial);
319
    int iconD = RubikActivity.getDrawable(R.drawable.ui_small_download,R.drawable.ui_medium_download, R.drawable.ui_big_download, R.drawable.ui_huge_download);
320
    int iconI = RubikActivity.getDrawable(R.drawable.ui_small_info,R.drawable.ui_medium_info, R.drawable.ui_big_info, R.drawable.ui_huge_info);
321

  
322
    ImageButton buttonTut = layout.findViewById(R.id.buttonTut);
323
    ImageButton buttonDow = layout.findViewById(R.id.buttonDow);
324
    ImageButton buttonInf = layout.findViewById(R.id.buttonInf);
325

  
326
    buttonTut.setImageResource(iconT);
327
    buttonDow.setImageResource(iconD);
328
    buttonInf.setImageResource(iconI);
329

  
330
    Resources res = act.getResources();
331
    BitmapDrawable bd = (BitmapDrawable)res.getDrawable(iconI);
332
    mBottomHeight = bd.getIntrinsicHeight();
333

  
334
    TypedValue outValue = new TypedValue();
335
    act.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, outValue, true);
336
    buttonTut.setBackgroundResource(outValue.resourceId);
337
    buttonDow.setBackgroundResource(outValue.resourceId);
338
    buttonInf.setBackgroundResource(outValue.resourceId);
339

  
340
    buttonTut.setOnClickListener( new View.OnClickListener()
341
      {
342
      @Override
343
      public void onClick(View v)
344
        {
345
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
346
        RubikDialogTutorial tDiag = new RubikDialogTutorial();
347
        tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
348
        }
349
      });
350

  
351
    buttonDow.setOnClickListener( new View.OnClickListener()
352
      {
353
      @Override
354
      public void onClick(View v)
355
        {
356
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
357
        RubikDialogUpdates uDiag = new RubikDialogUpdates();
358
        uDiag.show( act.getSupportFragmentManager(), RubikDialogUpdates.getDialogTag() );
359
        }
360
      });
361

  
362
    buttonInf.setOnClickListener( new View.OnClickListener()
363
      {
364
      @Override
365
      public void onClick(View v)
366
        {
367
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
368
        int currObject = RubikObjectList.getCurrObject();
369
        act.switchConfig(currObject);
370
        }
371
      });
372

  
373
    mBubbleUpdates = layout.findViewById(R.id.bubbleUpdates);
374
    mBubbleUpdates.setVisibility(View.INVISIBLE);
375

  
376
    RubikNetwork network = RubikNetwork.getInstance();
377
    network.signUpForUpdates(this);
378
    }
379

  
380
///////////////////////////////////////////////////////////////////////////////////////////////////
381

  
382
  private void setupMenuWindow(final RubikActivity act, final float width)
383
    {
384
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
385
    final View layout = layoutInflater.inflate(R.layout.popup_menu, null);
386
    LinearLayout menuLayout = layout.findViewById(R.id.menuGrid);
387

  
388
    mMenuPopup = new PopupWindow(act);
389
    mMenuPopup.setContentView(layout);
390
    mMenuPopup.setFocusable(true);
391
    int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
392
    int padding = (int)(width*RubikActivity.PADDING);
393

  
394
    mMenuLayoutWidth = (int)(width/2);
395
    mMenuLayoutHeight= (int)(2*margin + NUM_BUTTONS*(mMenuItemSize+margin));
396

  
397
    LinearLayout.LayoutParams p = new LinearLayout.LayoutParams( mMenuLayoutWidth - 2*padding, (int)mMenuItemSize);
398

  
399
    for(int i=0; i<NUM_BUTTONS; i++)
400
      {
401
      final int but = i;
402
      Button button = new Button(act);
403
      button.setLayoutParams(p);
404
      button.setText(BUTTON_LABELS[i]);
405
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
406

  
407
      button.setOnClickListener( new View.OnClickListener()
408
        {
409
        @Override
410
        public void onClick(View v)
411
          {
412
          mMenuPopup.dismiss();
413
          MenuAction(act,but);
414
          }
415
        });
416

  
417
      menuLayout.addView(button);
418
      }
419
    }
420

  
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422

  
423
  private void setupPlayWindow(final RubikActivity act, final float width)
424
    {
425
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
426
    final View layout = layoutInflater.inflate(R.layout.popup_play, null);
427
    mPlayLayout = layout.findViewById(R.id.playGrid);
428

  
429
    mPlayLayoutWidth = (int)(width*0.4f);
430

  
431
    mPlayPopup = new PopupWindow(act);
432
    mPlayPopup.setContentView(layout);
433
    mPlayPopup.setFocusable(true);
434

  
435
    adjustLevels(act);
436
    }
437

  
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

  
440
  private void MenuAction(RubikActivity act, int button)
441
    {
442
    switch(button)
443
      {
444
      case 0: Bundle sBundle = new Bundle();
445
              int currObject = RubikObjectList.getCurrObject();
446
              sBundle.putInt("tab", currObject );
447
              sBundle.putBoolean("submitting", false);
448
              RubikDialogScores scores = new RubikDialogScores();
449
              scores.setArguments(sBundle);
450
              scores.show(act.getSupportFragmentManager(), null);
451
              break;
452
      case 1: RubikDialogPattern pDiag = new RubikDialogPattern();
453
              pDiag.show( act.getSupportFragmentManager(), RubikDialogPattern.getDialogTag() );
454
              break;
455
      case 2: ScreenList.switchScreen(act, ScreenList.SVER);
456
              break;
457
      case 3: RubikDialogTutorial tDiag = new RubikDialogTutorial();
458
              tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
459
              break;
460
      case 4: act.switchToBandagedCreator();
461
              break;
462
      case 5: RubikDialogAbout aDiag = new RubikDialogAbout();
463
              aDiag.show(act.getSupportFragmentManager(), null);
464
              break;
465
      }
466
    }
467

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

  
470
  void setupSolveButton(final RubikActivity act)
471
    {
472
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_solve_new,R.drawable.ui_medium_cube_solve_new, R.drawable.ui_big_cube_solve_new, R.drawable.ui_huge_cube_solve_new);
473
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
474
    mSolveButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_END,params);
475

  
476
    mSolveButton.setOnClickListener( new View.OnClickListener()
477
      {
478
      @Override
479
      public void onClick(View v)
480
        {
481
        act.getControl().solveObject();
482
        mMovesController.clearMoves(act);
483
        }
484
      });
485
    }
486

  
487
///////////////////////////////////////////////////////////////////////////////////////////////////
488

  
489
  private void setupScrambleButton(final RubikActivity act)
490
    {
491
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_scramble_new,R.drawable.ui_medium_cube_scramble_new, R.drawable.ui_big_cube_scramble_new, R.drawable.ui_huge_cube_scramble_new);
492
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
493
    mScrambleButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_START, params);
494

  
495
    mScrambleButton.setOnClickListener( new View.OnClickListener()
496
      {
497
      @Override
498
      public void onClick(View v)
499
        {
500
        int currObject = RubikObjectList.getCurrObject();
501
        RubikObject object = RubikObjectList.getObject(currObject);
502
        int numScrambles = object==null ? 0 : object.getNumScramble();
503
        mShouldReactToEndOfScrambling = false;
504
        act.getControl().scrambleObject(numScrambles);
505
        }
506
      });
507
    }
508

  
509
///////////////////////////////////////////////////////////////////////////////////////////////////
510
// This is necessary! Otherwise the ObjectPopup will not be re-created next time and we will still
511
// hold a reference to the old instance of the RubikActivity class (because setupObjectWindow is not
512
// going to be called)
513
// An reference to the old instance of RubikActivity will cause all sorts of strange issues.
514

  
515
  public void savePreferences(SharedPreferences.Editor editor)
516
    {
517
    editor.putInt("play_LevelValue", mLevelValue );
518

  
519
    if( mObjectPopup!=null )
520
      {
521
      mObjectPopup.dismiss();
522
      mObjectPopup = null;
523
      }
524

  
525
    if( mMenuPopup!=null )
526
      {
527
      mMenuPopup.dismiss();
528
      mMenuPopup = null;
529
      }
530

  
531
    if( mPlayPopup!=null )
532
      {
533
      mPlayPopup.dismiss();
534
      mPlayPopup = null;
535
      }
536
    }
537

  
538
///////////////////////////////////////////////////////////////////////////////////////////////////
539

  
540
  public void restorePreferences(SharedPreferences preferences)
541
    {
542
    mLevelValue = preferences.getInt("play_LevelValue", 0);
543
    }
544

  
545
///////////////////////////////////////////////////////////////////////////////////////////////////
546

  
547
  public void setCurrObject(RubikActivity act)
548
    {
549
    if( mPlayLayout!=null ) adjustLevels(act);
550
    }
551

  
552
///////////////////////////////////////////////////////////////////////////////////////////////////
553
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
554

  
555
  private void displayPopup(RubikActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
556
    {
557
    View topLayout = act.findViewById(R.id.relativeLayout);
558
    boolean isFullScreen;
559

  
560
    if( topLayout!=null )
561
      {
562
      topLayout.getLocationOnScreen(mLocation);
563
      isFullScreen = (mLocation[1]==0);
564
      }
565
    else
566
      {
567
      isFullScreen = true;
568
      }
569

  
570
    try
571
      {
572
      // if on Android 11 or we are fullscreen
573
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
574
        {
575
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
576
        window.update(view, w, h);
577
        }
578
      else  // Android 10 or below in pop-up mode or split-screen mode
579
        {
580
        view.getLocationOnScreen(mLocation);
581
        int width  = view.getWidth();
582
        int height = view.getHeight();
583
        int x = mLocation[0]+(width-w)/2;
584
        int y = mLocation[1]+height+yoff;
585

  
586
        window.showAsDropDown(view);
587
        window.update(x,y,w,h);
588
        }
589
      }
590
    catch( IllegalArgumentException iae )
591
      {
592
      // ignore, this means window is 'not attached to window manager' -
593
      // which most probably is because we are already exiting the app.
594
      }
595
    }
596

  
597
///////////////////////////////////////////////////////////////////////////////////////////////////
598

  
599
  private void adjustSolvedIcons()
600
    {
601
    if( mPlayLayout!=null )
602
      {
603
      int currObject = RubikObjectList.getCurrObject();
604
      int dbLevel = RubikObjectList.getDBLevel(currObject);
605
      int numLevel= Math.min(dbLevel, LEVELS_SHOWN);
606
      RubikScores scores = RubikScores.getInstance();
607

  
608
      for(int i=0; i<numLevel; i++)
609
        {
610
        int level = i<numLevel-1 ? i+1 : dbLevel;
611
        Button button = (Button)mPlayLayout.getChildAt(i);
612
        int icon = scores.isSolved(currObject, level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
613
        button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
614
        }
615
      }
616
    }
617

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

  
620
  private void adjustLevels(final RubikActivity act)
621
    {
622
    int currObject = RubikObjectList.getCurrObject();
623
    int dbLevel = RubikObjectList.getDBLevel(currObject);
624
    RubikObject object = RubikObjectList.getObject(currObject);
625
    int numScrambles = object==null ? 0 : object.getNumScramble();
626
    int numLevel = Math.min(dbLevel, LEVELS_SHOWN);
627
    String[] levels = new String[numLevel];
628

  
629
    for(int i=0; i<numLevel-1; i++)
630
      {
631
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
632
      }
633

  
634
    if( numLevel>0 )
635
      {
636
      levels[numLevel-1] = act.getString(R.string.level_full);
637
      }
638

  
639
    if( mLevelValue>dbLevel || mLevelValue<1 ||
640
       (mLevelValue<dbLevel || mLevelValue>LEVELS_SHOWN ) )
641
      {
642
      mLevelValue=1;
643
      }
644

  
645
    float width  = act.getScreenWidthInPixels();
646
    int margin   = (int)(width*RubikActivity.SMALL_MARGIN);
647
    int padding  = (int)(width*RubikActivity.PADDING);
648
    int butWidth = mPlayLayoutWidth - 2*padding;
649
    int butHeight= (int)mMenuItemSize;
650
    int lastButH = (int)(mMenuItemSize*LAST_BUTTON) ;
651

  
652
    LinearLayout.LayoutParams pM = new LinearLayout.LayoutParams( butWidth, butHeight );
653
    pM.setMargins(margin, 0, margin, margin);
654
    LinearLayout.LayoutParams pT = new LinearLayout.LayoutParams( butWidth, butHeight );
655
    pT.setMargins(margin, margin, margin, margin);
656
    LinearLayout.LayoutParams pB = new LinearLayout.LayoutParams( butWidth, lastButH  );
657
    pB.setMargins(margin, margin, margin, 2*margin);
658

  
659
    mPlayLayout.removeAllViews();
660

  
661
    RubikScores scores = RubikScores.getInstance();
662

  
663
    for(int i=0; i<numLevel; i++)
664
      {
665
      final int level     = i<numLevel-1 ? i+1 : dbLevel;
666
      final int scrambles = i<numLevel-1 ? i+1 : numScrambles;
667
      Button button = new Button(act);
668
      button.setLayoutParams(i==0 ? pT : (i==numLevel-1 ? pB : pM));
669
      button.setText(levels[i]);
670
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
671

  
672
      int icon = scores.isSolved(currObject, level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
673
      button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
674

  
675
      button.setOnClickListener( new View.OnClickListener()
676
        {
677
        @Override
678
        public void onClick(View v)
679
          {
680
          ObjectControl control = act.getControl();
681

  
682
          if(control.isUINotBlocked())
683
            {
684
            if( mPlayPopup!=null ) mPlayPopup.dismiss();
685
            mLevelValue = level;
686
            mShouldReactToEndOfScrambling = true;
687
            control.scrambleObject(scrambles);
688
            }
689
          }
690
        });
691

  
692
      mPlayLayout.addView(button);
693
      }
694
    }
695

  
696
///////////////////////////////////////////////////////////////////////////////////////////////////
697

  
698
  public int getLevel()
699
    {
700
    return mLevelValue;
701
    }
702

  
703
///////////////////////////////////////////////////////////////////////////////////////////////////
704

  
705
  public void recreatePopup()
706
    {
707
    mObjectPopup = null;
708

  
709
    int numObjects = RubikObjectList.getNumObjects();
710
    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
711
    mColCount = NUM_COLUMNS;
712
    }
713

  
714
///////////////////////////////////////////////////////////////////////////////////////////////////
715

  
716
  public boolean shouldReactToEndOfScrambling()
717
    {
718
    return mShouldReactToEndOfScrambling;
719
    }
720

  
721
///////////////////////////////////////////////////////////////////////////////////////////////////
722

  
723
  public void receiveUpdate(RubikUpdates updates)
724
    {
725
    Activity act = mWeakAct.get();
726

  
727
    if( act!=null )
728
      {
729
      act.runOnUiThread(new Runnable()
730
        {
731
        @Override
732
        public void run()
733
          {
734
          int num = updates.getCompletedNumber();
735

  
736
          if( num>0 )
737
            {
738
            String shownNum = String.valueOf(num);
739
            mBubbleUpdates.setText(shownNum);
740
            mBubbleUpdates.setVisibility(View.VISIBLE);
741
            int height = (int)(0.05f*mScreenWidth);
742
            mBubbleUpdates.setTextSize(TypedValue.COMPLEX_UNIT_PX,height);
743
            }
744
         else
745
            {
746
            mBubbleUpdates.setVisibility(View.INVISIBLE);
747
            }
748
          }
749
        });
750
      }
751
    }
752

  
753
///////////////////////////////////////////////////////////////////////////////////////////////////
754

  
755
  public void errorUpdate()
756
    {
757
    android.util.Log.e("D", "Screen: Error receiving update");
758
    }
759
  }
src/main/java/org/distorted/screens/RubikScreenPlay.java
22 22
import java.lang.ref.WeakReference;
23 23

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

  
46
import org.distorted.config.ConfigActivity;
47 37
import org.distorted.dialogs.RubikDialogUpdates;
48 38
import org.distorted.external.RubikNetwork;
49 39
import org.distorted.external.RubikUpdates;
50
import org.distorted.main.RubikRenderer;
51
import org.distorted.objectlib.main.ObjectControl;
52 40

  
53 41
import org.distorted.main.R;
54 42
import org.distorted.main.RubikActivity;
55 43
import org.distorted.dialogs.RubikDialogAbout;
56
import org.distorted.dialogs.RubikDialogPattern;
57
import org.distorted.dialogs.RubikDialogScores;
58
import org.distorted.dialogs.RubikDialogTutorial;
59
import org.distorted.helpers.TransparentButton;
60 44
import org.distorted.helpers.TransparentImageButton;
61
import org.distorted.external.RubikScores;
62 45
import org.distorted.objects.RubikObject;
63 46
import org.distorted.objects.RubikObjectList;
64 47

  
65
import static android.view.View.inflate;
66

  
67 48
///////////////////////////////////////////////////////////////////////////////////////////////////
68 49

  
69 50
public class RubikScreenPlay extends RubikScreenAbstract implements RubikNetwork.Updatee
......
71 52
  public static final int NUM_COLUMNS  = 5;
72 53
  public static final int LEVELS_SHOWN = 10;
73 54

  
74
  private static final float LAST_BUTTON = 1.5f;
75
  private static final int[] mLocation = new int[2];
76

  
77 55
  private TransparentImageButton mAboutButton, mExitButton;
78
  private ImageButton mUpdatesButton;
79
 // private PopupWindow mObjectPopup, mMenuPopup, mPlayPopup;
80
  private LinearLayout mPlayLayout;
81 56
  private TextView mBubbleUpdates;
82 57
  private int mCurrentBubbleNumber;
83
  private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight, mPlayLayoutWidth;
84 58
  private int mLevelValue;
85
  private float mButtonSize, mMenuItemSize, mMenuTextSize;
86
  private int mColCount, mRowCount, mMaxRowCount;
87
  private int mUpperBarHeight, mLowerBarHeight;
88
  private boolean mShouldReactToEndOfScrambling;
89
  private int mBottomHeight;
90
  private float mScreenWidth, mScreenHeight;
59
  private int mColCount, mRowCount;
60
  private float mScreenWidth;
91 61
  private WeakReference<RubikActivity> mWeakAct;
92 62

  
93 63
///////////////////////////////////////////////////////////////////////////////////////////////////
......
107 77
    mWeakAct = new WeakReference<>(act);
108 78
    int numObjects = RubikObjectList.getNumObjects();
109 79
    mScreenWidth = act.getScreenWidthInPixels();
110
    mScreenHeight= act.getScreenHeightInPixels();
111
    mUpperBarHeight = act.getHeightUpperBar();
112
    mLowerBarHeight = act.getHeightLowerBar();
113

  
114
    mMenuTextSize = mScreenWidth*RubikActivity.MENU_MED_TEXT_SIZE;
115
    mButtonSize   = mScreenWidth*RubikActivity.BUTTON_TEXT_SIZE;
116
    mMenuItemSize = mScreenWidth*RubikActivity.MENU_ITEM_SIZE;
80
    int screenHeight= act.getScreenHeightInPixels();
81
    int upperBarHeight = act.getHeightUpperBar();
82
    int lowerBarHeight = act.getHeightLowerBar();
117 83

  
118 84
    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
119 85
    mColCount = NUM_COLUMNS;
......
161 127
    hiddenView.removeAllViews();
162 128

  
163 129
    ViewGroup.LayoutParams paramsMid = hiddenView.getLayoutParams();
164
    paramsMid.height = (int)(mScreenHeight-mUpperBarHeight-mLowerBarHeight);
130
    paramsMid.height = (int)(screenHeight-upperBarHeight-lowerBarHeight);
165 131
    hiddenView.setLayoutParams(paramsMid);
166 132

  
167 133
    ScrollView scroll = (ScrollView)inflater.inflate(R.layout.popup_object_simple, null);
168 134
    hiddenView.addView(scroll);
169 135

  
170
    setupScrollingObjects(act,scroll,mScreenWidth,mScreenHeight);
136
    setupScrollingObjects(act,scroll,mScreenWidth);
171 137
    }
172 138

  
173 139
//////////////////////////////////////////////////////////////////////////////////////////////////
......
214 180
    TypedValue value = new TypedValue();
215 181
    act.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, value, true);
216 182
    final int icon = RubikActivity.getDrawable(R.drawable.ui_small_download,R.drawable.ui_medium_download, R.drawable.ui_big_download, R.drawable.ui_huge_download);
217
    mUpdatesButton = relLayout.findViewById(R.id.buttonUpdates);
218
    mUpdatesButton.setImageResource(icon);
219
    mUpdatesButton.setBackgroundResource(value.resourceId);
183
    ImageButton updatesButton = relLayout.findViewById(R.id.buttonUpdates);
184
    updatesButton.setImageResource(icon);
185
    updatesButton.setBackgroundResource(value.resourceId);
220 186

  
221
    mUpdatesButton.setOnClickListener( new View.OnClickListener()
187
    updatesButton.setOnClickListener( new View.OnClickListener()
222 188
      {
223 189
      @Override
224 190
      public void onClick(View v)
......
237 203

  
238 204
///////////////////////////////////////////////////////////////////////////////////////////////////
239 205

  
240
  private void setupScrollingObjects(final RubikActivity act, final ScrollView view, final float width, final float height)
206
  private void setupScrollingObjects(final RubikActivity act, final ScrollView view, final float width)
241 207
    {
242
    int margin = (int)(width*RubikActivity.LARGE_MARGIN);
243
    int cubeWidth = (int)(width/NUM_COLUMNS) - 2*margin;
244

  
245
    mObjectSize = (int)(cubeWidth + 2*margin + 0.5f);
246
    mMaxRowCount = (int)((height-mUpperBarHeight-mLowerBarHeight)/mObjectSize);
208
    int margin   = (int)(width*RubikActivity.LARGE_MARGIN);
209
    int cubeSize = (int)(width/NUM_COLUMNS) - 2*margin;
247 210

  
248 211
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
249 212

  
......
293 256
      params.leftMargin   = margin;
294 257
      params.rightMargin  = margin;
295 258

  
296
      params.width = cubeWidth;
297
      params.height= cubeWidth;
298

  
299
      nextInRow[row]++;
300

  
301
      objectGrid.addView(button, params);
302
      }
303
    }
304

  
305
//////////////////////////////////////////////////////////////////////////////////////////////////
306
/*
307
  private void setupObjectButton(final RubikActivity act, final float width)
308
    {
309
    final int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
310
    final int lMargin = (int)(width*RubikActivity.LARGE_MARGIN);
311
    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);
312
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
313
    mObjButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
314

  
315
    mObjButton.setOnClickListener( new View.OnClickListener()
316
      {
317
      @Override
318
      public void onClick(View view)
319
        {
320
        if( mObjectPopup==null )
321
          {
322
          float width = act.getScreenWidthInPixels();
323
          float height= act.getScreenHeightInPixels();
324
          setupObjectWindow(act,width,height);
325
          }
326

  
327
        if( act.getControl().isUINotBlocked())
328
          {
329
          int rowCount = Math.min(mMaxRowCount,mRowCount);
330
          View popupView = mObjectPopup.getContentView();
331
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
332
          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount+mBottomHeight+2*lMargin+5*margin,margin,margin);
333
          }
334
        }
335
      });
336
    }
337

  
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

  
340
  private void setupPlayButton(final RubikActivity act, final float width)
341
    {
342
    final int margin = (int)(width*RubikActivity.SMALL_MARGIN);
343

  
344
    mPlayButton = new TransparentButton(act, R.string.play, mButtonSize);
345

  
346
    mPlayButton.setOnClickListener( new View.OnClickListener()
347
      {
348
      @Override
349
      public void onClick(View view)
350
        {
351
        if( mPlayPopup==null )
352
          {
353
          float width = act.getScreenWidthInPixels();
354
          setupPlayWindow(act,width);
355
          }
356

  
357
        if( act.getControl().isUINotBlocked())
358
          {
359
          adjustSolvedIcons();
360
          float height= act.getScreenHeightInPixels();
361
          final int maxHeight= (int)(0.9f*(height-mUpperBarHeight) );
362
          View popupView = mPlayPopup.getContentView();
363
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
364
          final int object  = RubikObjectList.getCurrObject();
365
          final int dbLevel = RubikObjectList.getDBLevel(object);
366
          final int levelsShown = Math.min(dbLevel,LEVELS_SHOWN);
367
          final int popupHeight = (int)(levelsShown*(mMenuItemSize+margin)+3*margin+mMenuItemSize*(LAST_BUTTON-1.0f));
368
          final int realHeight = Math.min(popupHeight,maxHeight);
369
          displayPopup(act,view,mPlayPopup,mPlayLayoutWidth,realHeight,margin,margin);
370
          }
371
        }
372
      });
373
    }
374

  
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

  
377
  private void setupMenuButton(final RubikActivity act, final float width)
378
    {
379
    final int margin = (int)(width*RubikActivity.SMALL_MARGIN);
380
    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);
381
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
382
    mMenuButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
383

  
384
    mMenuButton.setOnClickListener( new View.OnClickListener()
385
      {
386
      @Override
387
      public void onClick(View view)
388
        {
389
        if( mMenuPopup==null )
390
          {
391
          float width = act.getScreenWidthInPixels();
392
          setupMenuWindow(act,width);
393
          }
394

  
395
        if( act.getControl().isUINotBlocked())
396
          {
397
          View popupView = mMenuPopup.getContentView();
398
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
399
          displayPopup(act,view,mMenuPopup,mMenuLayoutWidth,mMenuLayoutHeight,(int)(-width/12),margin);
400
          }
401
        }
402
      });
403
    }
404

  
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406

  
407
  private void setupObjectWindow(final RubikActivity act, final float width, final float height)
408
    {
409
    int cubeWidth = (int)(width/9);
410
    int margin = (int)(width*RubikActivity.LARGE_MARGIN);
411
    mObjectSize = (int)(cubeWidth + 2*margin + 0.5f);
412
    mMaxRowCount = (int)((height-1.8f*mUpperBarHeight)/mObjectSize);
413

  
414
    LinearLayout view = (LinearLayout)inflate( act, R.layout.popup_object, null);
415
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
416

  
417
    GridLayout.Spec[] rowSpecs = new GridLayout.Spec[mRowCount];
418
    GridLayout.Spec[] colSpecs = new GridLayout.Spec[mColCount];
419

  
420
    objectGrid.setColumnCount(mColCount);
421
    objectGrid.setRowCount(mRowCount);
422

  
423
    mObjectPopup = new PopupWindow(act);
424
    mObjectPopup.setFocusable(true);
425
    mObjectPopup.setContentView(view);
426

  
427
    int[] nextInRow = new int[mRowCount];
428

  
429
    for(int row=0; row<mRowCount; row++)
430
      {
431
      rowSpecs[row] = GridLayout.spec(row);
432
      nextInRow[row]= 0;
433
      }
434
    for(int col=0; col<mColCount; col++)
435
      {
436
      colSpecs[col] = GridLayout.spec(col);
437
      }
438

  
439
    int numObjects = RubikObjectList.getNumObjects();
440

  
441
    for(int object=0; object<numObjects; object++)
442
      {
443
      final int ordinal = object;
444
      final RubikObject rObject = RubikObjectList.getObject(object);
445
      int row = object/NUM_COLUMNS;
446
      ImageButton button = new ImageButton(act);
447
      if( rObject!=null ) rObject.setIconTo(act,button);
448

  
449
      button.setOnClickListener( new View.OnClickListener()
450
        {
451
        @Override
452
        public void onClick(View v)
453
          {
454
          // TODO
455
          }
456
        });
457

  
458
      GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpecs[row],colSpecs[nextInRow[row]]);
459
      params.bottomMargin = margin;
460
      params.topMargin    = margin;
461
      params.leftMargin   = margin;
462
      params.rightMargin  = margin;
463

  
464
      params.width = cubeWidth;
465
      params.height= cubeWidth;
259
      params.width = cubeSize;
260
      params.height= cubeSize;
466 261

  
467 262
      nextInRow[row]++;
468 263

  
......
470 265
      }
471 266
    }
472 267

  
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474

  
475
  private void setupBottomLayout(final RubikActivity act, final RelativeLayout layout)
476
    {
477
    int iconT = RubikActivity.getDrawable(R.drawable.ui_small_tutorial,R.drawable.ui_medium_tutorial, R.drawable.ui_big_tutorial, R.drawable.ui_huge_tutorial);
478
    int iconD = RubikActivity.getDrawable(R.drawable.ui_small_download,R.drawable.ui_medium_download, R.drawable.ui_big_download, R.drawable.ui_huge_download);
479
    int iconI = RubikActivity.getDrawable(R.drawable.ui_small_info,R.drawable.ui_medium_info, R.drawable.ui_big_info, R.drawable.ui_huge_info);
480

  
481
    ImageButton buttonTut = layout.findViewById(R.id.buttonTut);
482
    ImageButton buttonDow = layout.findViewById(R.id.buttonDow);
483
    ImageButton buttonInf = layout.findViewById(R.id.buttonInf);
484

  
485
    buttonTut.setImageResource(iconT);
486
    buttonDow.setImageResource(iconD);
487
    buttonInf.setImageResource(iconI);
488

  
489
    Resources res = act.getResources();
490
    BitmapDrawable bd = (BitmapDrawable)res.getDrawable(iconI);
491
    mBottomHeight = bd.getIntrinsicHeight();
492

  
493
    TypedValue outValue = new TypedValue();
494
    act.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, outValue, true);
495
    buttonTut.setBackgroundResource(outValue.resourceId);
496
    buttonDow.setBackgroundResource(outValue.resourceId);
497
    buttonInf.setBackgroundResource(outValue.resourceId);
498

  
499
    buttonTut.setOnClickListener( new View.OnClickListener()
500
      {
501
      @Override
502
      public void onClick(View v)
503
        {
504
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
505
        RubikDialogTutorial tDiag = new RubikDialogTutorial();
506
        tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
507
        }
508
      });
509

  
510
    buttonDow.setOnClickListener( new View.OnClickListener()
511
      {
512
      @Override
513
      public void onClick(View v)
514
        {
515
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
516
        RubikDialogUpdates uDiag = new RubikDialogUpdates();
517
        uDiag.show( act.getSupportFragmentManager(), RubikDialogUpdates.getDialogTag() );
518
        }
519
      });
520

  
521
    buttonInf.setOnClickListener( new View.OnClickListener()
522
      {
523
      @Override
524
      public void onClick(View v)
525
        {
526
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
527
        int currObject = RubikObjectList.getCurrObject();
528
        act.switchConfig(currObject);
529
        }
530
      });
531

  
532
    mBubbleUpdates = layout.findViewById(R.id.bubbleUpdates);
533
    mBubbleUpdates.setVisibility(View.INVISIBLE);
534

  
535
    RubikNetwork network = RubikNetwork.getInstance();
536
    network.signUpForUpdates(this);
537
    }
538

  
539
///////////////////////////////////////////////////////////////////////////////////////////////////
540

  
541
  private void setupMenuWindow(final RubikActivity act, final float width)
542
    {
543
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
544
    final View layout = layoutInflater.inflate(R.layout.popup_menu, null);
545
    LinearLayout menuLayout = layout.findViewById(R.id.menuGrid);
546

  
547
    mMenuPopup = new PopupWindow(act);
548
    mMenuPopup.setContentView(layout);
549
    mMenuPopup.setFocusable(true);
550
    int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
551
    int padding = (int)(width*RubikActivity.PADDING);
552

  
553
    mMenuLayoutWidth = (int)(width/2);
554
    mMenuLayoutHeight= (int)(2*margin + NUM_BUTTONS*(mMenuItemSize+margin));
555

  
556
    LinearLayout.LayoutParams p = new LinearLayout.LayoutParams( mMenuLayoutWidth - 2*padding, (int)mMenuItemSize);
557

  
558
    for(int i=0; i<NUM_BUTTONS; i++)
559
      {
560
      final int but = i;
561
      Button button = new Button(act);
562
      button.setLayoutParams(p);
563
      button.setText(BUTTON_LABELS[i]);
564
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
565

  
566
      button.setOnClickListener( new View.OnClickListener()
567
        {
568
        @Override
569
        public void onClick(View v)
570
          {
571
          mMenuPopup.dismiss();
572
          MenuAction(act,but);
573
          }
574
        });
575

  
576
      menuLayout.addView(button);
577
      }
578
    }
579

  
580
///////////////////////////////////////////////////////////////////////////////////////////////////
581

  
582
  private void setupPlayWindow(final RubikActivity act, final float width)
583
    {
584
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
585
    final View layout = layoutInflater.inflate(R.layout.popup_play, null);
586
    mPlayLayout = layout.findViewById(R.id.playGrid);
587

  
588
    mPlayLayoutWidth = (int)(width*0.4f);
589

  
590
    mPlayPopup = new PopupWindow(act);
591
    mPlayPopup.setContentView(layout);
592
    mPlayPopup.setFocusable(true);
593

  
594
    adjustLevels(act);
595
    }
596

  
597
///////////////////////////////////////////////////////////////////////////////////////////////////
598

  
599
  private void MenuAction(RubikActivity act, int button)
600
    {
601
    switch(button)
602
      {
603
      case 0: Bundle sBundle = new Bundle();
604
              int currObject = RubikObjectList.getCurrObject();
605
              sBundle.putInt("tab", currObject );
606
              sBundle.putBoolean("submitting", false);
607
              RubikDialogScores scores = new RubikDialogScores();
608
              scores.setArguments(sBundle);
609
              scores.show(act.getSupportFragmentManager(), null);
610
              break;
611
      case 1: RubikDialogPattern pDiag = new RubikDialogPattern();
612
              pDiag.show( act.getSupportFragmentManager(), RubikDialogPattern.getDialogTag() );
613
              break;
614
      case 2: ScreenList.switchScreen(act, ScreenList.SVER);
615
              break;
616
      case 3: RubikDialogTutorial tDiag = new RubikDialogTutorial();
617
              tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
618
              break;
619
      case 4: act.switchToBandagedCreator();
620
              break;
621
      case 5: RubikDialogAbout aDiag = new RubikDialogAbout();
622
              aDiag.show(act.getSupportFragmentManager(), null);
623
              break;
624
      }
625
    }
626

  
627
///////////////////////////////////////////////////////////////////////////////////////////////////
628

  
629
  void setupSolveButton(final RubikActivity act)
630
    {
631
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_solve_new,R.drawable.ui_medium_cube_solve_new, R.drawable.ui_big_cube_solve_new, R.drawable.ui_huge_cube_solve_new);
632
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
633
    mSolveButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_END,params);
634

  
635
    mSolveButton.setOnClickListener( new View.OnClickListener()
636
      {
637
      @Override
638
      public void onClick(View v)
639
        {
640
        act.getControl().solveObject();
641
        mMovesController.clearMoves(act);
642
        }
643
      });
644
    }
645

  
646
///////////////////////////////////////////////////////////////////////////////////////////////////
647

  
648
  private void setupScrambleButton(final RubikActivity act)
649
    {
650
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_scramble_new,R.drawable.ui_medium_cube_scramble_new, R.drawable.ui_big_cube_scramble_new, R.drawable.ui_huge_cube_scramble_new);
651
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
652
    mScrambleButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_START, params);
653

  
654
    mScrambleButton.setOnClickListener( new View.OnClickListener()
655
      {
656
      @Override
657
      public void onClick(View v)
658
        {
659
        int currObject = RubikObjectList.getCurrObject();
660
        RubikObject object = RubikObjectList.getObject(currObject);
661
        int numScrambles = object==null ? 0 : object.getNumScramble();
662
        mShouldReactToEndOfScrambling = false;
663
        act.getControl().scrambleObject(numScrambles);
664
        }
665
      });
666
    }
667
*/
668 268
///////////////////////////////////////////////////////////////////////////////////////////////////
669 269

  
670 270
  public void savePreferences(SharedPreferences.Editor editor)
......
679 279
    mLevelValue = preferences.getInt("play_LevelValue", 0);
680 280
    }
681 281

  
682
///////////////////////////////////////////////////////////////////////////////////////////////////
683

  
684
  public void setCurrObject(RubikActivity act)
685
    {
686
    if( mPlayLayout!=null ) adjustLevels(act);
687
    }
688

  
689
///////////////////////////////////////////////////////////////////////////////////////////////////
690
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
691

  
692
  private void displayPopup(RubikActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
693
    {
694
    View topLayout = act.findViewById(R.id.relativeLayout);
695
    boolean isFullScreen;
696

  
697
    if( topLayout!=null )
698
      {
699
      topLayout.getLocationOnScreen(mLocation);
700
      isFullScreen = (mLocation[1]==0);
701
      }
702
    else
703
      {
704
      isFullScreen = true;
705
      }
706

  
707
    try
708
      {
709
      // if on Android 11 or we are fullscreen
710
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
711
        {
712
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
713
        window.update(view, w, h);
714
        }
715
      else  // Android 10 or below in pop-up mode or split-screen mode
716
        {
717
        view.getLocationOnScreen(mLocation);
718
        int width  = view.getWidth();
719
        int height = view.getHeight();
720
        int x = mLocation[0]+(width-w)/2;
721
        int y = mLocation[1]+height+yoff;
722

  
723
        window.showAsDropDown(view);
724
        window.update(x,y,w,h);
725
        }
726
      }
727
    catch( IllegalArgumentException iae )
728
      {
729
      // ignore, this means window is 'not attached to window manager' -
730
      // which most probably is because we are already exiting the app.
731
      }
732
    }
733

  
734
///////////////////////////////////////////////////////////////////////////////////////////////////
735

  
736
  private void adjustSolvedIcons()
737
    {
738
    if( mPlayLayout!=null )
739
      {
740
      int currObject = RubikObjectList.getCurrObject();
741
      int dbLevel = RubikObjectList.getDBLevel(currObject);
742
      int numLevel= Math.min(dbLevel, LEVELS_SHOWN);
743
      RubikScores scores = RubikScores.getInstance();
744

  
745
      for(int i=0; i<numLevel; i++)
746
        {
747
        int level = i<numLevel-1 ? i+1 : dbLevel;
748
        Button button = (Button)mPlayLayout.getChildAt(i);
749
        int icon = scores.isSolved(currObject, level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
750
        button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
751
        }
752
      }
753
    }
754

  
755
///////////////////////////////////////////////////////////////////////////////////////////////////
756

  
757
  private void adjustLevels(final RubikActivity act)
758
    {
759
    int currObject = RubikObjectList.getCurrObject();
760
    int dbLevel = RubikObjectList.getDBLevel(currObject);
761
    RubikObject object = RubikObjectList.getObject(currObject);
762
    int numScrambles = object==null ? 0 : object.getNumScramble();
763
    int numLevel = Math.min(dbLevel, LEVELS_SHOWN);
764
    String[] levels = new String[numLevel];
765

  
766
    for(int i=0; i<numLevel-1; i++)
767
      {
768
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
769
      }
770

  
771
    if( numLevel>0 )
772
      {
773
      levels[numLevel-1] = act.getString(R.string.level_full);
774
      }
775

  
776
    if( mLevelValue>dbLevel || mLevelValue<1 ||
777
       (mLevelValue<dbLevel || mLevelValue>LEVELS_SHOWN ) )
778
      {
779
      mLevelValue=1;
780
      }
781

  
782
    float width  = act.getScreenWidthInPixels();
783
    int margin   = (int)(width*RubikActivity.SMALL_MARGIN);
784
    int padding  = (int)(width*RubikActivity.PADDING);
785
    int butWidth = mPlayLayoutWidth - 2*padding;
786
    int butHeight= (int)mMenuItemSize;
787
    int lastButH = (int)(mMenuItemSize*LAST_BUTTON) ;
788

  
789
    LinearLayout.LayoutParams pM = new LinearLayout.LayoutParams( butWidth, butHeight );
790
    pM.setMargins(margin, 0, margin, margin);
791
    LinearLayout.LayoutParams pT = new LinearLayout.LayoutParams( butWidth, butHeight );
792
    pT.setMargins(margin, margin, margin, margin);
793
    LinearLayout.LayoutParams pB = new LinearLayout.LayoutParams( butWidth, lastButH  );
794
    pB.setMargins(margin, margin, margin, 2*margin);
795

  
796
    mPlayLayout.removeAllViews();
797

  
798
    RubikScores scores = RubikScores.getInstance();
799

  
800
    for(int i=0; i<numLevel; i++)
801
      {
802
      final int level     = i<numLevel-1 ? i+1 : dbLevel;
803
      final int scrambles = i<numLevel-1 ? i+1 : numScrambles;
804
      Button button = new Button(act);
805
      button.setLayoutParams(i==0 ? pT : (i==numLevel-1 ? pB : pM));
806
      button.setText(levels[i]);
807
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
808

  
809
      int icon = scores.isSolved(currObject, level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
810
      button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
811

  
812
      button.setOnClickListener( new View.OnClickListener()
813
        {
814
        @Override
815
        public void onClick(View v)
816
          {
817
          ObjectControl control = act.getControl();
818

  
819
          if(control.isUINotBlocked())
820
            {
821
         //   if( mPlayPopup!=null ) mPlayPopup.dismiss();
822
            mLevelValue = level;
823
            mShouldReactToEndOfScrambling = true;
824
            control.scrambleObject(scrambles);
825
            }
826
          }
827
        });
828

  
829
      mPlayLayout.addView(button);
830
      }
831
    }
832

  
833 282
///////////////////////////////////////////////////////////////////////////////////////////////////
834 283

  
835 284
  public int getLevel()
......
839 288

  
840 289
///////////////////////////////////////////////////////////////////////////////////////////////////
841 290

  
842
  public void recreatePopup()
291
  public void recreateListOfObjects()
843 292
    {
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff