Project

General

Profile

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

magiccube / src / main / java / org / distorted / states / RubikStatePlay.java @ 98e7cc0f

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.util.DisplayMetrics;
27
import android.util.TypedValue;
28
import android.view.Gravity;
29
import android.view.LayoutInflater;
30
import android.view.View;
31
import android.widget.AdapterView;
32
import android.widget.ArrayAdapter;
33
import android.widget.Button;
34
import android.widget.ImageButton;
35
import android.widget.LinearLayout;
36
import android.widget.PopupWindow;
37
import android.widget.TextView;
38

    
39
import androidx.appcompat.widget.AppCompatSpinner;
40

    
41
import org.distorted.dialogs.RubikDialogEffects;
42
import org.distorted.main.R;
43
import org.distorted.main.RubikActivity;
44
import org.distorted.objects.RubikObjectList;
45

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

    
48
public class RubikStatePlay extends RubikStateAbstract implements AdapterView.OnItemSelectedListener
49
  {
50
  private static final int DEF_LEVEL =  1;
51
  public  static final int DEF_OBJECT= RubikObjectList.CUBE.ordinal();
52
  public  static final int DEF_SIZE  =  3;
53

    
54
  private ImageButton mObjButton, mSettingsButton;
55
  private Button mBackButton, mSolveButton, mPlayButton;
56
  private PopupWindow mPopup;
57
  private int mObject = DEF_OBJECT;
58
  private int mSize   = DEF_SIZE;
59
  private int mLayoutWidth;
60
  private LinearLayout mLayout;
61
  private AppCompatSpinner mLevelSpinner;
62
  private ArrayAdapter<String> mSpinnerAdapter;
63
  private int mLevelValue;
64
  private float mButtonSize, mTitleSize;
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  void leaveState(RubikActivity act)
69
    {
70

    
71
    }
72

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

    
75
  void enterState(final RubikActivity act)
76
    {
77
    DisplayMetrics metrics = act.getResources().getDisplayMetrics();
78
    final float scale = metrics.density;
79

    
80
    float width = act.getScreenWidthInPixels();
81
    mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
82
    mTitleSize  = width*RubikActivity.TITLE_TEXT_SIZE;
83

    
84
    // TOP ////////////////////////////
85
    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
86
    layoutTop.removeAllViews();
87

    
88
    setupObjectButton(act,scale);
89
    layoutTop.addView(mObjButton);
90
    setupLevelSpinner(act,scale);
91
    layoutTop.addView(mLevelSpinner);
92
    setupPlayButton(act,scale);
93
    layoutTop.addView(mPlayButton);
94

    
95
    // BOT ////////////////////////////
96

    
97
    LinearLayout layoutLeft = act.findViewById(R.id.mainBarLeft);
98
    layoutLeft.removeAllViews();
99

    
100
    setupSettingsButton(act,scale,width);
101
    layoutLeft.addView(mSettingsButton);
102
    setupSolveButton(act,scale);
103
    layoutLeft.addView(mSolveButton);
104

    
105
    LinearLayout layoutRight = act.findViewById(R.id.mainBarRight);
106
    layoutRight.removeAllViews();
107

    
108
    setupBackButton(act,scale);
109
    layoutRight.addView(mBackButton);
110

    
111
    setupPopupWindow(act, scale);
112
    }
113

    
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

    
116
  private void setupObjectButton(final RubikActivity act, final float scale)
117
    {
118
    int padding = (int)(3*scale + 0.5f);
119
    LinearLayout.LayoutParams objectParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
120
    mObjButton = new ImageButton(act);
121
    mObjButton.setLayoutParams(objectParams);
122
    mObjButton.setPadding(padding,0,padding,0);
123
    mObjButton.setImageResource(R.drawable.cube_menu);
124

    
125
    mObjButton.setOnClickListener( new View.OnClickListener()
126
      {
127
      @Override
128
      public void onClick(View view)
129
        {
130
        if( act.getPreRender().canPlay() )
131
          {
132
          int total = RubikObjectList.getTotal();
133
          boolean vertical = act.isVertical();
134
          mLayout.setOrientation(vertical ? LinearLayout.VERTICAL:LinearLayout.HORIZONTAL);
135

    
136
          int width  = view.getWidth();
137
          int layhei = mLayoutWidth * (vertical? total:1);
138
          int laywid = mLayoutWidth * (vertical? 1:total);
139

    
140
          mPopup.showAsDropDown(view, (width-laywid)/2, 0, Gravity.LEFT);
141

    
142
          if( android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 )
143
            {
144
            mPopup.update(view, laywid, layhei);
145
            }
146
          }
147
        }
148
      });
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  private void setupLevelSpinner(final RubikActivity act, final float scale)
154
    {
155
    int spinnerPadding = (int)(scale* 10 + 0.5f);
156
    int spinnerMargin  = (int)(scale*  3 + 0.5f);
157
    LinearLayout.LayoutParams spinnerLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
158
    spinnerLayoutParams.topMargin    =   spinnerMargin;
159
    spinnerLayoutParams.bottomMargin =   spinnerMargin;
160
    spinnerLayoutParams.leftMargin   =   spinnerMargin;
161
    spinnerLayoutParams.rightMargin  = 2*spinnerMargin;
162

    
163
    mLevelSpinner = new AppCompatSpinner(act);
164
    mLevelSpinner.setLayoutParams(spinnerLayoutParams);
165
    mLevelSpinner.setPadding(spinnerPadding,0,spinnerPadding,0);
166
    mLevelSpinner.setBackgroundResource(R.drawable.spinner);
167
    mLevelSpinner.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
168

    
169
    mLevelSpinner.setOnItemSelectedListener(this);
170
    int sizeIndex = RubikObjectList.getSizeIndex(mObject,mSize);
171
    int maxLevel = RubikObjectList.getMaxLevel(mObject, sizeIndex);
172
    String[] levels = new String[maxLevel];
173

    
174
    for(int i=0; i<maxLevel; i++)
175
      {
176
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
177
      }
178

    
179
    if( mLevelValue>maxLevel ) mLevelValue=1;
180

    
181
    mSpinnerAdapter = new ArrayAdapter<>(act,android.R.layout.simple_spinner_item, levels);
182
    mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
183
    mLevelSpinner.setAdapter(mSpinnerAdapter);
184
    mLevelSpinner.setSelection(mLevelValue-1);
185
    }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
  private void setupPlayButton(final RubikActivity act, final float scale)
190
    {
191
    int padding = (int)(3*scale + 0.5f);
192
    LinearLayout.LayoutParams backParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
193
    mPlayButton = new Button(act);
194
    mPlayButton.setLayoutParams(backParams);
195
    mPlayButton.setPadding(padding,0,padding,0);
196
    mPlayButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
197
    mPlayButton.setText(R.string.play);
198

    
199
    mPlayButton.setOnClickListener( new View.OnClickListener()
200
      {
201
      @Override
202
      public void onClick(View v)
203
        {
204
        act.getPreRender().scrambleObject(mLevelValue);
205
        }
206
      });
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

    
211
  private void setupSettingsButton(final RubikActivity act, final float scale, final float width)
212
    {
213
    int padding = (int)(3*scale + 0.5f);
214
    int widthBut = (int)(width/6);
215
    LinearLayout.LayoutParams objectParams = new LinearLayout.LayoutParams(widthBut,LinearLayout.LayoutParams.MATCH_PARENT);
216
    mSettingsButton = new ImageButton(act);
217
    mSettingsButton.setLayoutParams(objectParams);
218
    mSettingsButton.setPadding(padding,0,padding,0);
219
    mSettingsButton.setImageResource(R.drawable.settings);
220

    
221
    mSettingsButton.setOnClickListener( new View.OnClickListener()
222
      {
223
      @Override
224
      public void onClick(View view)
225
        {
226
        RubikDialogEffects settings = new RubikDialogEffects();
227
        settings.show(act.getSupportFragmentManager(), null);
228
        }
229
      });
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

    
234
  private void setupSolveButton(final RubikActivity act, final float scale)
235
    {
236
    int padding = (int)(3*scale + 0.5f);
237
    LinearLayout.LayoutParams backParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
238
    mSolveButton = new Button(act);
239
    mSolveButton.setLayoutParams(backParams);
240
    mSolveButton.setPadding(padding,0,padding,0);
241
    mSolveButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
242

    
243
    mSolveButton.setText(R.string.solve);
244

    
245
    mSolveButton.setOnClickListener( new View.OnClickListener()
246
      {
247
      @Override
248
      public void onClick(View v)
249
        {
250
        act.getPreRender().solveObject();
251
        }
252
      });
253
    }
254

    
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256

    
257
  private void setupBackButton(final RubikActivity act, final float scale)
258
    {
259
    int padding = (int)(3*scale + 0.5f);
260
    LinearLayout.LayoutParams backParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
261
    mBackButton = new Button(act);
262
    mBackButton.setLayoutParams(backParams);
263
    mBackButton.setPadding(padding,0,padding,0);
264
    mBackButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
265
    mBackButton.setText(R.string.back);
266

    
267
    mBackButton.setOnClickListener( new View.OnClickListener()
268
      {
269
      @Override
270
      public void onClick(View v)
271
        {
272
        if( act.getPreRender().canPlay() ) RubikState.goBack(act);
273
        }
274
      });
275
    }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

    
279
  private void setupPopupWindow(final RubikActivity act, final float scale)
280
    {
281
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
282
    final View layout = layoutInflater.inflate(R.layout.popup_objects, null);
283
    mLayout = layout.findViewById(R.id.popup);
284

    
285
    mPopup = new PopupWindow(act);
286
    mPopup.setContentView(layout);
287
    mPopup.setFocusable(true);
288
    int margin = (int)(5*scale + 0.5f);
289

    
290
    BitmapDrawable bd = (BitmapDrawable) act.getResources().getDrawable(R.drawable.cube2);
291
    int cubeWidth  = bd.getIntrinsicWidth();
292
    mLayoutWidth = (int)(cubeWidth + 2*margin + 0.5f);
293

    
294
    for(int object=0; object<RubikObjectList.NUM_OBJECTS; object++)
295
      {
296
      final RubikObjectList list = RubikObjectList.getObject(object);
297
      final int[] sizes = list.getSizes();
298
      int[] icons = list.getIconIDs();
299
      int len = sizes.length;
300
      final int obj = object;
301

    
302
      for(int i=0; i<len; i++)
303
        {
304
        final int size = i;
305

    
306
        LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
307
        p.setMargins(margin, margin, margin, margin);
308

    
309
        ImageButton button = new ImageButton(act);
310
        button.setLayoutParams(p);
311

    
312
        button.setBackgroundResource(icons[i]);
313
        button.setOnClickListener( new View.OnClickListener()
314
          {
315
          @Override
316
          public void onClick(View v)
317
            {
318
            if( act.getPreRender().canPlay() && RubikState.getCurrentState()==RubikState.PLAY )
319
              {
320
              mObject = obj;
321
              mSize   = sizes[size];
322
              act.changeObject(list,sizes[size], true);
323
              adjustSpinner(act);
324
              }
325

    
326
            mPopup.dismiss();
327
            }
328
          });
329

    
330
        mLayout.addView(button);
331
        }
332
      }
333
    }
334

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

    
337
  public void savePreferences(SharedPreferences.Editor editor)
338
    {
339
    editor.putInt("statePlay_level" , mLevelValue);
340
    editor.putInt("statePlay_object", mObject);
341
    editor.putInt("statePlay_size"  , mSize);
342

    
343
    if( mPopup!=null )
344
      {
345
      mPopup.dismiss();
346
      mPopup = null;
347
      }
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

    
352
  public void restorePreferences(SharedPreferences preferences)
353
    {
354
    mLevelValue = preferences.getInt("statePlay_level" , DEF_LEVEL );
355
    mObject     = preferences.getInt("statePlay_object", DEF_OBJECT);
356
    mSize       = preferences.getInt("statePlay_size"  , DEF_SIZE  );
357
    }
358

    
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

    
361
  public boolean setObjectAndSize(RubikActivity act, RubikObjectList obj, int size)
362
    {
363
    if( mObject!=obj.ordinal() || mSize != size )
364
      {
365
      boolean success = false;
366

    
367
      for( int s: obj.getSizes() )
368
        if( s==size )
369
          {
370
          success = true;
371
          break;
372
          }
373

    
374
      if( success )
375
        {
376
        mObject = obj.ordinal();
377
        mSize   = size;
378

    
379
        if( mLevelSpinner!=null ) adjustSpinner(act);
380
        }
381

    
382
      return success;
383
      }
384

    
385
    return true;
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389

    
390
  private void adjustSpinner(RubikActivity act)
391
    {
392
    int sizeIndex = RubikObjectList.getSizeIndex(mObject,mSize);
393
    int maxLevel  = RubikObjectList.getMaxLevel(mObject, sizeIndex);
394
    String[] levels = new String[maxLevel];
395

    
396
    for(int i=0; i<maxLevel; i++)
397
      {
398
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
399
      }
400

    
401
    mSpinnerAdapter = new ArrayAdapter<>(act,android.R.layout.simple_spinner_item, levels);
402
    mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
403
    mLevelSpinner.setAdapter(mSpinnerAdapter);
404
    }
405

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

    
408
  int getLevel()
409
    {
410
    return mLevelValue;
411
    }
412

    
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414

    
415
  public int getObject()
416
    {
417
    return mObject;
418
    }
419

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

    
422
  public int getSize()
423
    {
424
    return mSize;
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
430
    {
431
    ((TextView) parent.getChildAt(0)).setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
432
    mLevelValue = pos+1;
433
    }
434

    
435
///////////////////////////////////////////////////////////////////////////////////////////////////
436

    
437
  public void onNothingSelected(AdapterView<?> parent) { }
438
  }
(6-6/10)