Project

General

Profile

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

magiccube / src / main / java / org / distorted / states / RubikStatePlay.java @ 011fcfe0

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.view.ViewGroup;
32
import android.widget.AdapterView;
33
import android.widget.ArrayAdapter;
34
import android.widget.Button;
35
import android.widget.ImageButton;
36
import android.widget.LinearLayout;
37
import android.widget.PopupWindow;
38
import android.widget.TextView;
39

    
40
import androidx.annotation.NonNull;
41
import androidx.appcompat.widget.AppCompatSpinner;
42

    
43
import org.distorted.dialogs.RubikDialogEffects;
44
import org.distorted.main.R;
45
import org.distorted.main.RubikActivity;
46
import org.distorted.objects.RubikObjectList;
47

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

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

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

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  void leaveState(RubikActivity act)
71
    {
72

    
73
    }
74

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

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

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

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

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

    
97
    // BOT ////////////////////////////
98

    
99
    LinearLayout layoutLeft = act.findViewById(R.id.mainBarLeft);
100
    layoutLeft.removeAllViews();
101

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

    
107
    LinearLayout layoutRight = act.findViewById(R.id.mainBarRight);
108
    layoutRight.removeAllViews();
109

    
110
    setupBackButton(act,scale);
111
    layoutRight.addView(mBackButton);
112

    
113
    setupPopupWindow(act, scale);
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

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

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

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

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

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

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

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

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

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

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

    
181
    if( mLevelValue>maxLevel ) mLevelValue=1;
182

    
183
    mSpinnerAdapter = new ArrayAdapter<String>(act, android.R.layout.simple_spinner_item, levels)
184
      {
185
      @NonNull
186
      public View getView(int position, View convertView, @NonNull ViewGroup parent)
187
        {
188
        View v = super.getView(position, convertView, parent);
189
        TextView tv = ((TextView) v);
190
        tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
191
        return v;
192
        }
193
      };
194

    
195
    mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
196
    mLevelSpinner.setAdapter(mSpinnerAdapter);
197
    mLevelSpinner.setSelection(mLevelValue-1);
198
    }
199

    
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

    
202
  private void setupPlayButton(final RubikActivity act, final float scale)
203
    {
204
    int padding = (int)(3*scale + 0.5f);
205
    LinearLayout.LayoutParams backParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
206
    mPlayButton = new Button(act);
207
    mPlayButton.setLayoutParams(backParams);
208
    mPlayButton.setPadding(padding,0,padding,0);
209
    mPlayButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
210
    mPlayButton.setText(R.string.play);
211

    
212
    mPlayButton.setOnClickListener( new View.OnClickListener()
213
      {
214
      @Override
215
      public void onClick(View v)
216
        {
217
        act.getPreRender().scrambleObject(mLevelValue);
218
        }
219
      });
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
  private void setupSettingsButton(final RubikActivity act, final float scale, final float width)
225
    {
226
    int padding = (int)(3*scale + 0.5f);
227
    int widthBut = (int)(width/6);
228
    LinearLayout.LayoutParams objectParams = new LinearLayout.LayoutParams(widthBut,LinearLayout.LayoutParams.MATCH_PARENT);
229
    mSettingsButton = new ImageButton(act);
230
    mSettingsButton.setLayoutParams(objectParams);
231
    mSettingsButton.setPadding(padding,0,padding,0);
232
    mSettingsButton.setImageResource(R.drawable.settings);
233

    
234
    mSettingsButton.setOnClickListener( new View.OnClickListener()
235
      {
236
      @Override
237
      public void onClick(View view)
238
        {
239
        RubikDialogEffects settings = new RubikDialogEffects();
240
        settings.show(act.getSupportFragmentManager(), null);
241
        }
242
      });
243
    }
244

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

    
247
  private void setupSolveButton(final RubikActivity act, final float scale)
248
    {
249
    int padding = (int)(3*scale + 0.5f);
250
    LinearLayout.LayoutParams backParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
251
    mSolveButton = new Button(act);
252
    mSolveButton.setLayoutParams(backParams);
253
    mSolveButton.setPadding(padding,0,padding,0);
254
    mSolveButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
255

    
256
    mSolveButton.setText(R.string.solve);
257

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

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

    
270
  private void setupBackButton(final RubikActivity act, final float scale)
271
    {
272
    int padding = (int)(3*scale + 0.5f);
273
    LinearLayout.LayoutParams backParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
274
    mBackButton = new Button(act);
275
    mBackButton.setLayoutParams(backParams);
276
    mBackButton.setPadding(padding,0,padding,0);
277
    mBackButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
278
    mBackButton.setText(R.string.back);
279

    
280
    mBackButton.setOnClickListener( new View.OnClickListener()
281
      {
282
      @Override
283
      public void onClick(View v)
284
        {
285
        if( act.getPreRender().canPlay() ) RubikState.goBack(act);
286
        }
287
      });
288
    }
289

    
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

    
292
  private void setupPopupWindow(final RubikActivity act, final float scale)
293
    {
294
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
295
    final View layout = layoutInflater.inflate(R.layout.popup_objects, null);
296
    mLayout = layout.findViewById(R.id.popup);
297

    
298
    mPopup = new PopupWindow(act);
299
    mPopup.setContentView(layout);
300
    mPopup.setFocusable(true);
301
    int margin = (int)(5*scale + 0.5f);
302

    
303
    BitmapDrawable bd = (BitmapDrawable) act.getResources().getDrawable(R.drawable.cube2);
304
    int cubeWidth  = bd.getIntrinsicWidth();
305
    mLayoutWidth = (int)(cubeWidth + 2*margin + 0.5f);
306

    
307
    for(int object=0; object<RubikObjectList.NUM_OBJECTS; object++)
308
      {
309
      final RubikObjectList list = RubikObjectList.getObject(object);
310
      final int[] sizes = list.getSizes();
311
      int[] icons = list.getIconIDs();
312
      int len = sizes.length;
313
      final int obj = object;
314

    
315
      for(int i=0; i<len; i++)
316
        {
317
        final int size = i;
318

    
319
        LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
320
        p.setMargins(margin, margin, margin, margin);
321

    
322
        ImageButton button = new ImageButton(act);
323
        button.setLayoutParams(p);
324

    
325
        button.setBackgroundResource(icons[i]);
326
        button.setOnClickListener( new View.OnClickListener()
327
          {
328
          @Override
329
          public void onClick(View v)
330
            {
331
            if( act.getPreRender().canPlay() && RubikState.getCurrentState()==RubikState.PLAY )
332
              {
333
              mObject = obj;
334
              mSize   = sizes[size];
335
              act.changeObject(list,sizes[size], true);
336
              adjustSpinner(act);
337
              }
338

    
339
            mPopup.dismiss();
340
            }
341
          });
342

    
343
        mLayout.addView(button);
344
        }
345
      }
346
    }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349

    
350
  public void savePreferences(SharedPreferences.Editor editor)
351
    {
352
    editor.putInt("statePlay_level" , mLevelValue);
353
    editor.putInt("statePlay_object", mObject);
354
    editor.putInt("statePlay_size"  , mSize);
355

    
356
    if( mPopup!=null )
357
      {
358
      mPopup.dismiss();
359
      mPopup = null;
360
      }
361
    }
362

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

    
365
  public void restorePreferences(SharedPreferences preferences)
366
    {
367
    mLevelValue = preferences.getInt("statePlay_level" , DEF_LEVEL );
368
    mObject     = preferences.getInt("statePlay_object", DEF_OBJECT);
369
    mSize       = preferences.getInt("statePlay_size"  , DEF_SIZE  );
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  public boolean setObjectAndSize(RubikActivity act, RubikObjectList obj, int size)
375
    {
376
    if( mObject!=obj.ordinal() || mSize != size )
377
      {
378
      boolean success = false;
379

    
380
      for( int s: obj.getSizes() )
381
        if( s==size )
382
          {
383
          success = true;
384
          break;
385
          }
386

    
387
      if( success )
388
        {
389
        mObject = obj.ordinal();
390
        mSize   = size;
391

    
392
        if( mLevelSpinner!=null ) adjustSpinner(act);
393
        }
394

    
395
      return success;
396
      }
397

    
398
    return true;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  private void adjustSpinner(RubikActivity act)
404
    {
405
    int sizeIndex = RubikObjectList.getSizeIndex(mObject,mSize);
406
    int maxLevel  = RubikObjectList.getMaxLevel(mObject, sizeIndex);
407
    String[] levels = new String[maxLevel];
408

    
409
    for(int i=0; i<maxLevel; i++)
410
      {
411
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
412
      }
413

    
414
    mSpinnerAdapter = new ArrayAdapter<String>(act, android.R.layout.simple_spinner_item, levels)
415
      {
416
      @NonNull
417
      public View getView(int position, View convertView, @NonNull ViewGroup parent)
418
        {
419
        View v = super.getView(position, convertView, parent);
420
        TextView tv = ((TextView) v);
421
        tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
422
        return v;
423
        }
424
      };
425

    
426
    mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
427
    mLevelSpinner.setAdapter(mSpinnerAdapter);
428
    }
429

    
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431

    
432
  int getLevel()
433
    {
434
    return mLevelValue;
435
    }
436

    
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

    
439
  public int getObject()
440
    {
441
    return mObject;
442
    }
443

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445

    
446
  public int getSize()
447
    {
448
    return mSize;
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

    
453
  public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
454
    {
455
    mLevelValue = pos+1;
456
    }
457

    
458
///////////////////////////////////////////////////////////////////////////////////////////////////
459

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