Project

General

Profile

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

magiccube / src / main / java / org / distorted / states / RubikStatePlay.java @ e07c48a2

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.states;
21

    
22
import android.content.Context;
23
import android.content.SharedPreferences;
24
import android.graphics.drawable.BitmapDrawable;
25
import android.os.Build;
26
import android.os.Bundle;
27
import android.util.DisplayMetrics;
28
import android.util.TypedValue;
29
import android.view.Gravity;
30
import android.view.LayoutInflater;
31
import android.view.View;
32
import android.view.ViewGroup;
33
import android.widget.AdapterView;
34
import android.widget.ArrayAdapter;
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.TextView;
41

    
42
import androidx.annotation.NonNull;
43
import androidx.appcompat.widget.AppCompatSpinner;
44

    
45
import org.distorted.dialogs.RubikDialogAbout;
46
import org.distorted.dialogs.RubikDialogScores;
47
import org.distorted.main.R;
48
import org.distorted.main.RubikActivity;
49
import org.distorted.main.RubikPreRender;
50
import org.distorted.objects.RubikObject;
51
import org.distorted.objects.RubikObjectList;
52

    
53
import java.util.ArrayList;
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

    
57
public class RubikStatePlay extends RubikStateAbstract implements AdapterView.OnItemSelectedListener,
58
                                                                  RubikPreRender.ActionFinishedListener
59
  {
60
  private static final int DURATION_MILLIS = 750;
61
  private static final int DEF_LEVEL =  1;
62
  public  static final int DEF_OBJECT= RubikObjectList.CUBE.ordinal();
63
  public  static final int DEF_SIZE  =  3;
64

    
65
  private static int[] BUTTON_LABELS = { R.string.scores, R.string.patterns, R.string.solver, R.string.about };
66
  private static final int NUM_BUTTONS = BUTTON_LABELS.length;
67

    
68
  private ImageButton mObjButton, mMenuButton, mPrevButton, mSolveButton;
69
  private Button mPlayButton;
70
  private PopupWindow mObjectPopup, mMenuPopup;
71
  private int mObject = DEF_OBJECT;
72
  private int mSize   = DEF_SIZE;
73
  private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight;
74
  private GridLayout mObjectGrid;
75
  private AppCompatSpinner mLevelSpinner;
76
  private ArrayAdapter<String> mSpinnerAdapter;
77
  private int mLevelValue;
78
  private int mBarHeight;
79
  private float mButtonSize, mMenuItemSize, mMenuTextSize;
80
  private int mColCount, mRowCount;
81

    
82
  private ArrayList<Move> mMoves;
83
  private boolean mCanPrevMove;
84

    
85
  private static class Move
86
    {
87
    private int mAxis, mRow, mAngle;
88

    
89
    Move(int axis, int row, int angle)
90
      {
91
      mAxis = axis;
92
      mRow  = row;
93
      mAngle= angle;
94
      }
95
    }
96

    
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

    
99
  void leaveState(RubikActivity act)
100
    {
101

    
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

    
106
  void enterState(final RubikActivity act)
107
    {
108
    float width = act.getScreenWidthInPixels();
109
    mMenuTextSize = width*RubikActivity.MENU_MEDIUM_TEXT_SIZE;
110
    mButtonSize   = width*RubikActivity.BUTTON_TEXT_SIZE;
111
    mMenuItemSize = width*RubikActivity.MENU_ITEM_SIZE;
112

    
113
    mCanPrevMove = true;
114

    
115
    if( mMoves==null ) mMoves = new ArrayList<>();
116
    else               mMoves.clear();
117

    
118
    mRowCount = RubikObjectList.getRowCount();
119
    mColCount = RubikObjectList.getColumnCount();
120

    
121
    // TOP ////////////////////////////
122
    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
123
    layoutTop.removeAllViews();
124

    
125
    setupObjectWindow(act,width);
126
    setupObjectButton(act,width);
127
    layoutTop.addView(mObjButton);
128
    setupLevelSpinner(act,width);
129
    layoutTop.addView(mLevelSpinner);
130
    setupPlayButton(act,width);
131
    layoutTop.addView(mPlayButton);
132

    
133
    // BOT ////////////////////////////
134
    LinearLayout layoutLeft = act.findViewById(R.id.mainBarLeft);
135
    layoutLeft.removeAllViews();
136

    
137
    setupPrevButton(act,width);
138
    layoutLeft.addView(mPrevButton);
139
    setupSolveButton(act,width);
140
    layoutLeft.addView(mSolveButton);
141

    
142
    LinearLayout layoutRight = act.findViewById(R.id.mainBarRight);
143
    layoutRight.removeAllViews();
144

    
145
    setupMenuWindow(act,width);
146
    setupMenuButton(act,width);
147
    layoutRight.addView(mMenuButton);
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
  private void setupObjectButton(final RubikActivity act, final float width)
153
    {
154
    final int padding = (int)(width*RubikActivity.PADDING);
155
    final int margin  = (int)(width*RubikActivity.MARGIN);
156
    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);
157

    
158
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
159
    params.topMargin    = margin;
160
    params.bottomMargin = margin;
161
    params.leftMargin   = margin;
162
    params.rightMargin  = margin;
163

    
164
    mObjButton = new ImageButton(act);
165
    mObjButton.setLayoutParams(params);
166
    mObjButton.setPadding(padding,0,padding,0);
167
    mObjButton.setImageResource(icon);
168

    
169
    mObjButton.setOnClickListener( new View.OnClickListener()
170
      {
171
      @Override
172
      public void onClick(View view)
173
        {
174
        if( act.getPreRender().canPlay() )
175
          {
176
          boolean vertical = act.isVertical();
177
          mObjectGrid.setOrientation(vertical ? GridLayout.VERTICAL:GridLayout.HORIZONTAL);
178
          mObjectPopup.showAsDropDown(view, 0, margin, Gravity.LEFT);
179

    
180
          if( android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 )
181
            {
182
            int layhei = mObjectSize * (vertical? mRowCount:mColCount);
183
            int laywid = mObjectSize * (vertical? mColCount:mRowCount);
184
            mObjectPopup.update(view, laywid, layhei);
185
            }
186
          }
187
        }
188
      });
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  private void setupLevelSpinner(final RubikActivity act, final float width)
194
    {
195
    int padding = (int)(width*RubikActivity.PADDING);
196
    int margin  = (int)(width*RubikActivity.MARGIN);
197
    int spin = RubikActivity.getDrawable(R.drawable.ui_small_spinner,R.drawable.ui_big_spinner, R.drawable.ui_big_spinner, R.drawable.ui_huge_spinner);
198

    
199
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
200
    params.topMargin    = margin;
201
    params.bottomMargin = margin;
202
    params.leftMargin   = margin;
203
    params.rightMargin  = margin;
204

    
205
    mLevelSpinner = new AppCompatSpinner(act);
206
    mLevelSpinner.setLayoutParams(params);
207
    mLevelSpinner.setPadding(padding,0,padding,0);
208
    mLevelSpinner.setBackgroundResource(spin);
209
    mLevelSpinner.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
210

    
211
    mLevelSpinner.setOnItemSelectedListener(this);
212
    int sizeIndex = RubikObjectList.getSizeIndex(mObject,mSize);
213
    int maxLevel = RubikObjectList.getMaxLevel(mObject, sizeIndex);
214
    String[] levels = new String[maxLevel];
215

    
216
    for(int i=0; i<maxLevel; i++)
217
      {
218
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
219
      }
220

    
221
    if( mLevelValue>maxLevel ) mLevelValue=1;
222

    
223
    mSpinnerAdapter = new ArrayAdapter<String>(act, android.R.layout.simple_spinner_item, levels)
224
      {
225
      @NonNull
226
      public View getView(int position, View convertView, @NonNull ViewGroup parent)
227
        {
228
        View v = super.getView(position, convertView, parent);
229
        TextView tv = ((TextView) v);
230
        tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
231
        return v;
232
        }
233
      };
234

    
235
    mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
236
    mLevelSpinner.setAdapter(mSpinnerAdapter);
237
    mLevelSpinner.setSelection(mLevelValue-1);
238
    }
239

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

    
242
  private void setupPlayButton(final RubikActivity act, final float width)
243
    {
244
    int padding = (int)(width*RubikActivity.PADDING);
245
    int margin  = (int)(width*RubikActivity.MARGIN);
246
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
247
    params.topMargin    = margin;
248
    params.bottomMargin = margin;
249
    params.leftMargin   = margin;
250
    params.rightMargin  = margin;
251

    
252
    mPlayButton = new Button(act);
253
    mPlayButton.setLayoutParams(params);
254
    mPlayButton.setPadding(padding,0,padding,0);
255
    mPlayButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
256
    mPlayButton.setText(R.string.play);
257

    
258
    mPlayButton.setOnClickListener( new View.OnClickListener()
259
      {
260
      @Override
261
      public void onClick(View v)
262
        {
263
        act.getPreRender().scrambleObject(mLevelValue);
264
        }
265
      });
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

    
270
  private void setupMenuButton(final RubikActivity act, final float width)
271
    {
272
    int padding = (int)(width*RubikActivity.PADDING);
273
    int margin  = (int)(width*RubikActivity.MARGIN);
274
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_menu,R.drawable.ui_medium_menu, R.drawable.ui_big_menu, R.drawable.ui_huge_menu);
275

    
276
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
277
    params.topMargin    = margin;
278
    params.bottomMargin = margin;
279
    params.leftMargin   = margin;
280
    params.rightMargin  = margin;
281

    
282
    mMenuButton = new ImageButton(act);
283
    mMenuButton.setLayoutParams(params);
284
    mMenuButton.setPadding(padding,0,padding,0);
285
    mMenuButton.setImageResource(icon);
286

    
287
    mMenuButton.setOnClickListener( new View.OnClickListener()
288
      {
289
      @Override
290
      public void onClick(View view)
291
        {
292
        if( act.getPreRender().canPlay() )
293
          {
294
          if( mBarHeight<=0 )
295
            {
296
            DisplayMetrics displaymetrics = new DisplayMetrics();
297
            act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
298
            mBarHeight=displaymetrics.heightPixels/10;
299
            }
300

    
301
          mMenuPopup.showAsDropDown(view, 0, -mMenuLayoutHeight-mBarHeight, Gravity.LEFT);
302
          mMenuPopup.update(view, mMenuLayoutWidth, mMenuLayoutHeight);
303
          }
304
        }
305
      });
306
    }
307

    
308
///////////////////////////////////////////////////////////////////////////////////////////////////
309

    
310
  private void setupSolveButton(final RubikActivity act, final float width)
311
    {
312
    int padding  = (int)(width*RubikActivity.PADDING);
313
    int margin   = (int)(width*RubikActivity.MARGIN);
314
    int widthBut = (int)(width/6);
315
    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);
316

    
317
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(widthBut, LinearLayout.LayoutParams.MATCH_PARENT);
318
    params.topMargin    = margin;
319
    params.bottomMargin = margin;
320
    params.leftMargin   = margin;
321
    params.rightMargin  = margin;
322

    
323
    mSolveButton = new ImageButton(act);
324
    mSolveButton.setLayoutParams(params);
325
    mSolveButton.setPadding(padding,0,padding,0);
326
    mSolveButton.setImageResource(icon);
327

    
328
    mSolveButton.setOnClickListener( new View.OnClickListener()
329
      {
330
      @Override
331
      public void onClick(View v)
332
        {
333
        act.getPreRender().solveObject();
334
        mMoves.clear();
335
        }
336
      });
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  private void setupPrevButton(final RubikActivity act, final float width)
342
    {
343
    int padding  = (int)(width*RubikActivity.PADDING);
344
    int margin   = (int)(width*RubikActivity.MARGIN);
345
    int widthBut = (int)(width/6);
346
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_back,R.drawable.ui_medium_cube_back, R.drawable.ui_big_cube_back, R.drawable.ui_huge_cube_back);
347

    
348
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(widthBut, LinearLayout.LayoutParams.MATCH_PARENT);
349
    params.topMargin    = margin;
350
    params.bottomMargin = margin;
351
    params.leftMargin   = margin;
352
    params.rightMargin  = margin;
353

    
354
    mPrevButton = new ImageButton(act);
355
    mPrevButton.setLayoutParams(params);
356
    mPrevButton.setPadding(padding,0,padding,0);
357
    mPrevButton.setImageResource(icon);
358

    
359
    mPrevButton.setOnClickListener( new View.OnClickListener()
360
      {
361
      @Override
362
      public void onClick(View v)
363
        {
364
        RubikPreRender pre = act.getPreRender();
365
        backMove(pre);
366
        }
367
      });
368
    }
369

    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371

    
372
  private void setupObjectWindow(final RubikActivity act, final float width)
373
    {
374
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
375
    final View layout = layoutInflater.inflate(R.layout.popup_objects, null);
376
    mObjectGrid = layout.findViewById(R.id.objectGrid);
377

    
378
    int[] indices = RubikObjectList.getIndices();
379

    
380
    GridLayout.Spec[] rowSpecs = new GridLayout.Spec[mRowCount];
381
    GridLayout.Spec[] colSpecs = new GridLayout.Spec[mColCount];
382

    
383
    mObjectGrid.setColumnCount(mColCount);
384
    mObjectGrid.setRowCount(mRowCount);
385

    
386
    for(int row=0; row<mRowCount; row++)
387
      {
388
      rowSpecs[row] = GridLayout.spec(row);
389
      }
390
    for(int col=0; col<mColCount; col++)
391
      {
392
      colSpecs[col] = GridLayout.spec(col);
393
      }
394

    
395
    mObjectPopup = new PopupWindow(act);
396
    mObjectPopup.setContentView(layout);
397
    mObjectPopup.setFocusable(true);
398
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube2,R.drawable.ui_medium_cube2, R.drawable.ui_big_cube2, R.drawable.ui_huge_cube2);
399

    
400
    BitmapDrawable bd = (BitmapDrawable) act.getResources().getDrawable(icon);
401
    int cubeWidth = bd.getIntrinsicWidth();
402
    int margin = (int)(width*RubikActivity.LARGE_MARGIN);
403
    mObjectSize = (int)(cubeWidth + 2*margin + 0.5f);
404

    
405
    for(int object=0; object<RubikObjectList.NUM_OBJECTS; object++)
406
      {
407
      final RubikObjectList list = RubikObjectList.getObject(object);
408
      final int[] sizes = list.getSizes();
409
      int[] icons = list.getIconIDs();
410
      int len = sizes.length;
411
      final int obj = object;
412

    
413
      for(int i=0; i<len; i++)
414
        {
415
        final int index = i;
416

    
417
        ImageButton button = new ImageButton(act);
418
        button.setBackgroundResource(icons[i]);
419
        button.setOnClickListener( new View.OnClickListener()
420
          {
421
          @Override
422
          public void onClick(View v)
423
            {
424
            if( act.getPreRender().canPlay() && RubikState.getCurrentState()==RubikState.PLAY )
425
              {
426
              mObject = obj;
427
              mSize   = sizes[index];
428
              act.changeObject(list,sizes[index], true);
429
              adjustSpinner(act);
430
              mMoves.clear();
431
              }
432

    
433
            mObjectPopup.dismiss();
434
            }
435
          });
436

    
437
        GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpecs[index],colSpecs[indices[object]]);
438
        params.bottomMargin = margin;
439
        params.topMargin    = margin;
440
        params.leftMargin   = margin;
441
        params.rightMargin  = margin;
442

    
443
        mObjectGrid.addView(button, params);
444
        }
445
      }
446
    }
447

    
448
///////////////////////////////////////////////////////////////////////////////////////////////////
449

    
450
  private void setupMenuWindow(final RubikActivity act, final float width)
451
    {
452
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
453
    final View layout = layoutInflater.inflate(R.layout.popup_menu, null);
454
    LinearLayout menuLayout = layout.findViewById(R.id.menuGrid);
455

    
456
    mMenuPopup = new PopupWindow(act);
457
    mMenuPopup.setContentView(layout);
458
    mMenuPopup.setFocusable(true);
459
    int margin  = (int)(width*RubikActivity.MARGIN);
460
    int padding = (int)(width*RubikActivity.PADDING);
461

    
462
    LinearLayout.LayoutParams p0 = new LinearLayout.LayoutParams( (int)width/2 - 2*padding, (int)mMenuItemSize);
463
    p0.setMargins(margin, 0, margin, margin);
464
    LinearLayout.LayoutParams p1 = new LinearLayout.LayoutParams( (int)width/2 - 2*padding, (int)mMenuItemSize);
465
    p1.setMargins(margin, margin, margin, margin);
466

    
467
    for(int i=0; i<NUM_BUTTONS; i++)
468
      {
469
      final int but = i;
470
      Button button = new Button(act);
471
      button.setLayoutParams(i==0 ? p1:p0);
472
      button.setText(BUTTON_LABELS[i]);
473
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
474

    
475
      button.setOnClickListener( new View.OnClickListener()
476
        {
477
        @Override
478
        public void onClick(View v)
479
          {
480
          mMenuPopup.dismiss();
481
          Action(act,but);
482
          }
483
        });
484

    
485
      menuLayout.addView(button);
486
      }
487

    
488
    mMenuLayoutWidth = (int)(width/2);
489
    mMenuLayoutHeight= (int)(margin + NUM_BUTTONS*(mMenuItemSize+margin));
490
    }
491

    
492
///////////////////////////////////////////////////////////////////////////////////////////////////
493

    
494
  private void backMove(RubikPreRender pre)
495
    {
496
    if( mCanPrevMove )
497
      {
498
      int numMoves = mMoves.size();
499

    
500
      if( numMoves>0 )
501
        {
502
        Move move = mMoves.remove(numMoves-1);
503
        RubikObject object = pre.getObject();
504

    
505
        int axis  = move.mAxis;
506
        int row   = (1<<move.mRow);
507
        int angle = move.mAngle;
508
        int numRot= Math.abs(angle*object.getBasicAngle()/360);
509

    
510
        if( angle!=0 )
511
          {
512
          mCanPrevMove = false;
513
          pre.addRotation(this, axis, row, -angle, numRot*DURATION_MILLIS);
514
          }
515
        else
516
          {
517
          android.util.Log.e("solution", "error: trying to back move of angle 0");
518
          }
519
        }
520
      }
521
    }
522
///////////////////////////////////////////////////////////////////////////////////////////////////
523

    
524
  private void Action(RubikActivity act, int button)
525
    {
526
    switch(button)
527
      {
528
      case 0: RubikStatePlay play = (RubikStatePlay) RubikState.PLAY.getStateClass();
529
              int object = play.getObject();
530
              int size   = play.getSize();
531
              int sizeIndex = RubikObjectList.getSizeIndex(object,size);
532

    
533
              Bundle bundle = new Bundle();
534
              bundle.putInt("tab", RubikObjectList.pack(object,sizeIndex) );
535
              bundle.putBoolean("submitting", false);
536

    
537
              RubikDialogScores scores = new RubikDialogScores();
538
              scores.setArguments(bundle);
539
              scores.show(act.getSupportFragmentManager(), null);
540
              break;
541
      case 1: RubikState.switchState(act,RubikState.PATT);
542
              break;
543
      case 2: RubikState.switchState(act,RubikState.SVER);
544
              break;
545
      case 3: RubikDialogAbout diag = new RubikDialogAbout();
546
              diag.show(act.getSupportFragmentManager(), null);
547
              break;
548
      }
549
    }
550

    
551
///////////////////////////////////////////////////////////////////////////////////////////////////
552

    
553
  public void savePreferences(SharedPreferences.Editor editor)
554
    {
555
    editor.putInt("statePlay_level" , mLevelValue);
556
    editor.putInt("statePlay_object", mObject);
557
    editor.putInt("statePlay_size"  , mSize);
558

    
559
    if( mObjectPopup!=null )
560
      {
561
      mObjectPopup.dismiss();
562
      mObjectPopup = null;
563
      }
564

    
565
    if( mMenuPopup!=null )
566
      {
567
      mMenuPopup.dismiss();
568
      mMenuPopup = null;
569
      }
570
    }
571

    
572
///////////////////////////////////////////////////////////////////////////////////////////////////
573

    
574
  public void restorePreferences(SharedPreferences preferences)
575
    {
576
    mLevelValue = preferences.getInt("statePlay_level" , DEF_LEVEL );
577
    mObject     = preferences.getInt("statePlay_object", DEF_OBJECT);
578
    mSize       = preferences.getInt("statePlay_size"  , DEF_SIZE  );
579
    }
580

    
581
///////////////////////////////////////////////////////////////////////////////////////////////////
582

    
583
  public boolean setObjectAndSize(RubikActivity act, RubikObjectList obj, int size)
584
    {
585
    if( mObject!=obj.ordinal() || mSize != size )
586
      {
587
      boolean success = false;
588

    
589
      for( int s: obj.getSizes() )
590
        if( s==size )
591
          {
592
          success = true;
593
          break;
594
          }
595

    
596
      if( success )
597
        {
598
        mObject = obj.ordinal();
599
        mSize   = size;
600

    
601
        if( mLevelSpinner!=null ) adjustSpinner(act);
602
        }
603

    
604
      return success;
605
      }
606

    
607
    return true;
608
    }
609

    
610
///////////////////////////////////////////////////////////////////////////////////////////////////
611

    
612
  private void adjustSpinner(RubikActivity act)
613
    {
614
    int sizeIndex = RubikObjectList.getSizeIndex(mObject,mSize);
615
    int maxLevel  = RubikObjectList.getMaxLevel(mObject, sizeIndex);
616
    String[] levels = new String[maxLevel];
617

    
618
    for(int i=0; i<maxLevel; i++)
619
      {
620
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
621
      }
622

    
623
    mSpinnerAdapter = new ArrayAdapter<String>(act, android.R.layout.simple_spinner_item, levels)
624
      {
625
      @NonNull
626
      public View getView(int position, View convertView, @NonNull ViewGroup parent)
627
        {
628
        View v = super.getView(position, convertView, parent);
629
        TextView tv = ((TextView) v);
630
        tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
631
        return v;
632
        }
633
      };
634

    
635
    mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
636
    mLevelSpinner.setAdapter(mSpinnerAdapter);
637
    }
638

    
639
///////////////////////////////////////////////////////////////////////////////////////////////////
640

    
641
  int getLevel()
642
    {
643
    return mLevelValue;
644
    }
645

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

    
648
  public void addMove(int axis, int row, int angle)
649
    {
650
    mMoves.add(new Move(axis,row,angle));
651
    }
652

    
653
///////////////////////////////////////////////////////////////////////////////////////////////////
654

    
655
  public int getObject()
656
    {
657
    return mObject;
658
    }
659

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

    
662
  public int getSize()
663
    {
664
    return mSize;
665
    }
666

    
667
///////////////////////////////////////////////////////////////////////////////////////////////////
668

    
669
  public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
670
    {
671
    mLevelValue = pos+1;
672
    }
673

    
674
///////////////////////////////////////////////////////////////////////////////////////////////////
675

    
676
  public void onNothingSelected(AdapterView<?> parent) { }
677

    
678
///////////////////////////////////////////////////////////////////////////////////////////////////
679

    
680
  public void onActionFinished(final long effectID)
681
    {
682
    mCanPrevMove = true;
683
    }
684
  }
(5-5/9)