Project

General

Profile

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

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

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);
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)
212
    {
213
    int padding = (int)(3*scale + 0.5f);
214
    LinearLayout.LayoutParams objectParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.MATCH_PARENT);
215
    mSettingsButton = new ImageButton(act);
216
    mSettingsButton.setLayoutParams(objectParams);
217
    mSettingsButton.setPadding(padding,0,padding,0);
218
    mSettingsButton.setImageResource(R.drawable.settings);
219

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

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

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

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

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

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

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

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

    
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277

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

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

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

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

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

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

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

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

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

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

    
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

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

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

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350

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

    
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359

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

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

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

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

    
381
      return success;
382
      }
383

    
384
    return true;
385
    }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

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

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

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

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

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

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

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

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

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

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

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

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

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