22 |
22 |
import android.content.Context;
|
23 |
23 |
import android.content.SharedPreferences;
|
24 |
24 |
import android.graphics.drawable.BitmapDrawable;
|
25 |
|
import android.os.Build;
|
26 |
25 |
import android.os.Bundle;
|
27 |
|
import android.util.DisplayMetrics;
|
28 |
26 |
import android.util.TypedValue;
|
29 |
27 |
import android.view.Gravity;
|
30 |
28 |
import android.view.LayoutInflater;
|
31 |
29 |
import android.view.View;
|
32 |
|
import android.view.ViewGroup;
|
33 |
|
import android.widget.AdapterView;
|
34 |
|
import android.widget.ArrayAdapter;
|
35 |
30 |
import android.widget.Button;
|
36 |
31 |
import android.widget.GridLayout;
|
37 |
32 |
import android.widget.ImageButton;
|
38 |
33 |
import android.widget.LinearLayout;
|
39 |
34 |
import android.widget.PopupWindow;
|
40 |
|
import android.widget.TextView;
|
41 |
|
|
42 |
|
import androidx.annotation.NonNull;
|
43 |
|
import androidx.appcompat.widget.AppCompatSpinner;
|
44 |
35 |
|
45 |
36 |
import org.distorted.dialogs.RubikDialogAbout;
|
46 |
37 |
import org.distorted.dialogs.RubikDialogScores;
|
... | ... | |
54 |
45 |
|
55 |
46 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
56 |
47 |
|
57 |
|
public class RubikStatePlay extends RubikStateAbstract implements AdapterView.OnItemSelectedListener,
|
58 |
|
RubikPreRender.ActionFinishedListener
|
|
48 |
public class RubikStatePlay extends RubikStateAbstract implements RubikPreRender.ActionFinishedListener
|
59 |
49 |
{
|
60 |
50 |
private static final int DURATION_MILLIS = 750;
|
61 |
|
private static final int DEF_LEVEL = 1;
|
|
51 |
private static final int LEVELS_SHOWN = 10;
|
62 |
52 |
public static final int DEF_OBJECT= RubikObjectList.CUBE.ordinal();
|
63 |
53 |
public static final int DEF_SIZE = 3;
|
64 |
54 |
|
... | ... | |
67 |
57 |
|
68 |
58 |
private ImageButton mObjButton, mMenuButton, mPrevButton, mSolveButton;
|
69 |
59 |
private Button mPlayButton;
|
70 |
|
private PopupWindow mObjectPopup, mMenuPopup;
|
|
60 |
private PopupWindow mObjectPopup, mMenuPopup, mPlayPopup;
|
71 |
61 |
private int mObject = DEF_OBJECT;
|
72 |
62 |
private int mSize = DEF_SIZE;
|
73 |
|
private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight;
|
|
63 |
private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight, mPlayLayoutWidth;
|
74 |
64 |
private GridLayout mObjectGrid;
|
75 |
|
private AppCompatSpinner mLevelSpinner;
|
76 |
|
private ArrayAdapter<String> mSpinnerAdapter;
|
77 |
65 |
private int mLevelValue;
|
78 |
|
private int mBarHeight;
|
79 |
66 |
private float mButtonSize, mMenuItemSize, mMenuTextSize;
|
80 |
67 |
private int mColCount, mRowCount;
|
|
68 |
private LinearLayout mPlayLayout;
|
81 |
69 |
|
82 |
70 |
private ArrayList<Move> mMoves;
|
83 |
71 |
private boolean mCanPrevMove;
|
... | ... | |
125 |
113 |
setupObjectWindow(act,width);
|
126 |
114 |
setupObjectButton(act,width);
|
127 |
115 |
layoutTop.addView(mObjButton);
|
128 |
|
setupLevelSpinner(act,width);
|
129 |
|
layoutTop.addView(mLevelSpinner);
|
|
116 |
|
|
117 |
setupMenuWindow(act,width);
|
|
118 |
setupMenuButton(act,width);
|
|
119 |
layoutTop.addView(mMenuButton);
|
|
120 |
|
|
121 |
setupPlayWindow(act,width);
|
130 |
122 |
setupPlayButton(act,width);
|
131 |
123 |
layoutTop.addView(mPlayButton);
|
132 |
124 |
|
... | ... | |
141 |
133 |
|
142 |
134 |
LinearLayout layoutRight = act.findViewById(R.id.mainBarRight);
|
143 |
135 |
layoutRight.removeAllViews();
|
144 |
|
|
145 |
|
setupMenuWindow(act,width);
|
146 |
|
setupMenuButton(act,width);
|
147 |
|
layoutRight.addView(mMenuButton);
|
148 |
136 |
}
|
149 |
137 |
|
150 |
138 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
... | ... | |
185 |
173 |
});
|
186 |
174 |
}
|
187 |
175 |
|
188 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
189 |
|
|
190 |
|
private void setupLevelSpinner(final RubikActivity act, final float width)
|
191 |
|
{
|
192 |
|
int padding = (int)(width*RubikActivity.PADDING);
|
193 |
|
int margin = (int)(width*RubikActivity.MARGIN);
|
194 |
|
int spin = RubikActivity.getDrawable(R.drawable.ui_small_spinner,R.drawable.ui_big_spinner, R.drawable.ui_big_spinner, R.drawable.ui_huge_spinner);
|
195 |
|
|
196 |
|
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
|
197 |
|
params.topMargin = margin;
|
198 |
|
params.bottomMargin = margin;
|
199 |
|
params.leftMargin = margin;
|
200 |
|
params.rightMargin = margin;
|
201 |
|
|
202 |
|
mLevelSpinner = new AppCompatSpinner(act);
|
203 |
|
mLevelSpinner.setLayoutParams(params);
|
204 |
|
mLevelSpinner.setPadding(padding,0,padding,0);
|
205 |
|
mLevelSpinner.setBackgroundResource(spin);
|
206 |
|
mLevelSpinner.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
207 |
|
|
208 |
|
mLevelSpinner.setOnItemSelectedListener(this);
|
209 |
|
int sizeIndex = RubikObjectList.getSizeIndex(mObject,mSize);
|
210 |
|
int maxLevel = RubikObjectList.getMaxLevel(mObject, sizeIndex);
|
211 |
|
String[] levels = new String[maxLevel];
|
212 |
|
|
213 |
|
for(int i=0; i<maxLevel; i++)
|
214 |
|
{
|
215 |
|
levels[i] = act.getString(R.string.lv_placeholder,i+1);
|
216 |
|
}
|
217 |
|
|
218 |
|
if( mLevelValue>maxLevel ) mLevelValue=1;
|
219 |
|
|
220 |
|
mSpinnerAdapter = new ArrayAdapter<String>(act, android.R.layout.simple_spinner_item, levels)
|
221 |
|
{
|
222 |
|
@NonNull
|
223 |
|
public View getView(int position, View convertView, @NonNull ViewGroup parent)
|
224 |
|
{
|
225 |
|
View v = super.getView(position, convertView, parent);
|
226 |
|
TextView tv = ((TextView) v);
|
227 |
|
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
|
228 |
|
return v;
|
229 |
|
}
|
230 |
|
};
|
231 |
|
|
232 |
|
mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
233 |
|
mLevelSpinner.setAdapter(mSpinnerAdapter);
|
234 |
|
mLevelSpinner.setSelection(mLevelValue-1);
|
235 |
|
}
|
236 |
|
|
237 |
176 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
238 |
177 |
|
239 |
178 |
private void setupPlayButton(final RubikActivity act, final float width)
|
240 |
179 |
{
|
241 |
|
int padding = (int)(width*RubikActivity.PADDING);
|
242 |
|
int margin = (int)(width*RubikActivity.MARGIN);
|
|
180 |
final int padding = (int)(width*RubikActivity.PADDING);
|
|
181 |
final int margin = (int)(width*RubikActivity.MARGIN);
|
243 |
182 |
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
|
244 |
183 |
params.topMargin = margin;
|
245 |
184 |
params.bottomMargin = margin;
|
... | ... | |
255 |
194 |
mPlayButton.setOnClickListener( new View.OnClickListener()
|
256 |
195 |
{
|
257 |
196 |
@Override
|
258 |
|
public void onClick(View v)
|
|
197 |
public void onClick(View view)
|
259 |
198 |
{
|
260 |
|
act.getPreRender().scrambleObject(mLevelValue);
|
|
199 |
mPlayPopup.showAsDropDown(view, margin, margin, Gravity.RIGHT);
|
|
200 |
mPlayPopup.update(view, mPlayLayoutWidth, (int)(LEVELS_SHOWN*(mMenuItemSize+margin)+margin));
|
261 |
201 |
}
|
262 |
202 |
});
|
263 |
203 |
}
|
... | ... | |
266 |
206 |
|
267 |
207 |
private void setupMenuButton(final RubikActivity act, final float width)
|
268 |
208 |
{
|
269 |
|
int padding = (int)(width*RubikActivity.PADDING);
|
270 |
|
int margin = (int)(width*RubikActivity.MARGIN);
|
271 |
|
int icon = RubikActivity.getDrawable(R.drawable.ui_small_menu,R.drawable.ui_medium_menu, R.drawable.ui_big_menu, R.drawable.ui_huge_menu);
|
|
209 |
final int padding = (int)(width*RubikActivity.PADDING);
|
|
210 |
final int margin = (int)(width*RubikActivity.MARGIN);
|
|
211 |
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);
|
272 |
212 |
|
273 |
|
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
|
|
213 |
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, 1.2f);
|
274 |
214 |
params.topMargin = margin;
|
275 |
215 |
params.bottomMargin = margin;
|
276 |
216 |
params.leftMargin = margin;
|
... | ... | |
288 |
228 |
{
|
289 |
229 |
if( act.getPreRender().canPlay() )
|
290 |
230 |
{
|
291 |
|
if( mBarHeight<=0 )
|
292 |
|
{
|
293 |
|
DisplayMetrics displaymetrics = new DisplayMetrics();
|
294 |
|
act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
295 |
|
mBarHeight=displaymetrics.heightPixels/10;
|
296 |
|
}
|
297 |
|
|
298 |
|
mMenuPopup.showAsDropDown(view, 0, -mMenuLayoutHeight-mBarHeight, Gravity.LEFT);
|
|
231 |
mMenuPopup.showAsDropDown(view, (int)(-width/12), margin, Gravity.CENTER);
|
299 |
232 |
mMenuPopup.update(view, mMenuLayoutWidth, mMenuLayoutHeight);
|
300 |
233 |
}
|
301 |
234 |
}
|
... | ... | |
427 |
360 |
mObject = obj;
|
428 |
361 |
mSize = sizes[index];
|
429 |
362 |
act.changeObject(list,sizes[index], true);
|
430 |
|
adjustSpinner(act);
|
|
363 |
adjustLevels(act);
|
431 |
364 |
mMoves.clear();
|
432 |
365 |
}
|
433 |
366 |
|
... | ... | |
462 |
395 |
int margin = (int)(width*RubikActivity.MARGIN);
|
463 |
396 |
int padding = (int)(width*RubikActivity.PADDING);
|
464 |
397 |
|
465 |
|
LinearLayout.LayoutParams p0 = new LinearLayout.LayoutParams( (int)width/2 - 2*padding, (int)mMenuItemSize);
|
466 |
|
p0.setMargins(margin, 0, margin, margin);
|
467 |
|
LinearLayout.LayoutParams p1 = new LinearLayout.LayoutParams( (int)width/2 - 2*padding, (int)mMenuItemSize);
|
468 |
|
p1.setMargins(margin, margin, margin, margin);
|
|
398 |
mMenuLayoutWidth = (int)(width/2);
|
|
399 |
mMenuLayoutHeight= (int)(2*margin + NUM_BUTTONS*(mMenuItemSize+margin));
|
|
400 |
|
|
401 |
LinearLayout.LayoutParams pT = new LinearLayout.LayoutParams( mMenuLayoutWidth - 2*padding, (int)mMenuItemSize);
|
|
402 |
pT.setMargins(margin, 0, margin, margin);
|
|
403 |
LinearLayout.LayoutParams pM = new LinearLayout.LayoutParams( mMenuLayoutWidth - 2*padding, (int)mMenuItemSize);
|
|
404 |
pM.setMargins(margin, margin, margin, margin);
|
|
405 |
LinearLayout.LayoutParams pB = new LinearLayout.LayoutParams( mMenuLayoutWidth - 2*padding, (int)mMenuItemSize);
|
|
406 |
pB.setMargins(margin, margin, margin, 2*margin);
|
469 |
407 |
|
470 |
408 |
for(int i=0; i<NUM_BUTTONS; i++)
|
471 |
409 |
{
|
472 |
410 |
final int but = i;
|
473 |
411 |
Button button = new Button(act);
|
474 |
|
button.setLayoutParams(i==0 ? p1:p0);
|
|
412 |
button.setLayoutParams(pT);//i==0 ? pT : (i==NUM_BUTTONS-1 ? pB : pM));
|
475 |
413 |
button.setText(BUTTON_LABELS[i]);
|
476 |
414 |
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
|
477 |
415 |
|
... | ... | |
481 |
419 |
public void onClick(View v)
|
482 |
420 |
{
|
483 |
421 |
mMenuPopup.dismiss();
|
484 |
|
Action(act,but);
|
|
422 |
MenuAction(act,but);
|
485 |
423 |
}
|
486 |
424 |
});
|
487 |
425 |
|
488 |
426 |
menuLayout.addView(button);
|
489 |
427 |
}
|
|
428 |
}
|
490 |
429 |
|
491 |
|
mMenuLayoutWidth = (int)(width/2);
|
492 |
|
mMenuLayoutHeight= (int)(margin + NUM_BUTTONS*(mMenuItemSize+margin));
|
|
430 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
431 |
|
|
432 |
private void setupPlayWindow(final RubikActivity act, final float width)
|
|
433 |
{
|
|
434 |
LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
435 |
final View layout = layoutInflater.inflate(R.layout.popup_play, null);
|
|
436 |
mPlayLayout = layout.findViewById(R.id.playGrid);
|
|
437 |
|
|
438 |
mPlayLayoutWidth = (int)(width*0.4f);
|
|
439 |
|
|
440 |
mPlayPopup = new PopupWindow(act);
|
|
441 |
mPlayPopup.setContentView(layout);
|
|
442 |
mPlayPopup.setFocusable(true);
|
|
443 |
|
|
444 |
adjustLevels(act);
|
493 |
445 |
}
|
494 |
446 |
|
495 |
447 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
... | ... | |
522 |
474 |
}
|
523 |
475 |
}
|
524 |
476 |
}
|
|
477 |
|
525 |
478 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
526 |
479 |
|
527 |
|
private void Action(RubikActivity act, int button)
|
|
480 |
private void MenuAction(RubikActivity act, int button)
|
528 |
481 |
{
|
529 |
482 |
switch(button)
|
530 |
483 |
{
|
... | ... | |
555 |
508 |
|
556 |
509 |
public void savePreferences(SharedPreferences.Editor editor)
|
557 |
510 |
{
|
558 |
|
editor.putInt("statePlay_level" , mLevelValue);
|
559 |
511 |
editor.putInt("statePlay_object", mObject);
|
560 |
512 |
editor.putInt("statePlay_size" , mSize);
|
561 |
513 |
|
... | ... | |
570 |
522 |
mMenuPopup.dismiss();
|
571 |
523 |
mMenuPopup = null;
|
572 |
524 |
}
|
|
525 |
|
|
526 |
if( mPlayPopup!=null )
|
|
527 |
{
|
|
528 |
mPlayPopup.dismiss();
|
|
529 |
mPlayPopup = null;
|
|
530 |
}
|
573 |
531 |
}
|
574 |
532 |
|
575 |
533 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
576 |
534 |
|
577 |
535 |
public void restorePreferences(SharedPreferences preferences)
|
578 |
536 |
{
|
579 |
|
mLevelValue = preferences.getInt("statePlay_level" , DEF_LEVEL );
|
580 |
537 |
mObject = preferences.getInt("statePlay_object", DEF_OBJECT);
|
581 |
538 |
mSize = preferences.getInt("statePlay_size" , DEF_SIZE );
|
582 |
539 |
}
|
... | ... | |
601 |
558 |
mObject = obj.ordinal();
|
602 |
559 |
mSize = size;
|
603 |
560 |
|
604 |
|
if( mLevelSpinner!=null ) adjustSpinner(act);
|
|
561 |
if( mPlayLayout!=null ) adjustLevels(act);
|
605 |
562 |
}
|
606 |
563 |
|
607 |
564 |
return success;
|
... | ... | |
612 |
569 |
|
613 |
570 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
614 |
571 |
|
615 |
|
private void adjustSpinner(RubikActivity act)
|
|
572 |
private void adjustLevels(final RubikActivity act)
|
616 |
573 |
{
|
617 |
574 |
int sizeIndex = RubikObjectList.getSizeIndex(mObject,mSize);
|
618 |
|
int maxLevel = RubikObjectList.getMaxLevel(mObject, sizeIndex);
|
|
575 |
int maxLevel = RubikObjectList.getMaxLevel(mObject, sizeIndex);
|
619 |
576 |
String[] levels = new String[maxLevel];
|
620 |
577 |
|
621 |
578 |
for(int i=0; i<maxLevel; i++)
|
... | ... | |
623 |
580 |
levels[i] = act.getString(R.string.lv_placeholder,i+1);
|
624 |
581 |
}
|
625 |
582 |
|
626 |
|
mSpinnerAdapter = new ArrayAdapter<String>(act, android.R.layout.simple_spinner_item, levels)
|
|
583 |
if( mLevelValue>maxLevel ) mLevelValue=1;
|
|
584 |
|
|
585 |
float width = act.getScreenWidthInPixels();
|
|
586 |
int margin = (int)(width*RubikActivity.MARGIN);
|
|
587 |
int padding = (int)(width*RubikActivity.PADDING);
|
|
588 |
|
|
589 |
LinearLayout.LayoutParams pM = new LinearLayout.LayoutParams( mPlayLayoutWidth - 2*padding, (int)mMenuItemSize);
|
|
590 |
pM.setMargins(margin, 0, margin, margin);
|
|
591 |
LinearLayout.LayoutParams pT = new LinearLayout.LayoutParams( mPlayLayoutWidth - 2*padding, (int)mMenuItemSize);
|
|
592 |
pT.setMargins(margin, margin, margin, margin);
|
|
593 |
LinearLayout.LayoutParams pB = new LinearLayout.LayoutParams( mPlayLayoutWidth - 2*padding, (int)mMenuItemSize);
|
|
594 |
pB.setMargins(margin, margin, margin, 2*margin);
|
|
595 |
|
|
596 |
mPlayLayout.removeAllViews();
|
|
597 |
|
|
598 |
for(int i=0; i<maxLevel; i++)
|
627 |
599 |
{
|
628 |
|
@NonNull
|
629 |
|
public View getView(int position, View convertView, @NonNull ViewGroup parent)
|
|
600 |
final int but = i;
|
|
601 |
Button button = new Button(act);
|
|
602 |
button.setLayoutParams(i==0 ? pT : (i==maxLevel-1 ? pB : pM));
|
|
603 |
button.setText(levels[i]);
|
|
604 |
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
|
|
605 |
|
|
606 |
button.setOnClickListener( new View.OnClickListener()
|
630 |
607 |
{
|
631 |
|
View v = super.getView(position, convertView, parent);
|
632 |
|
TextView tv = ((TextView) v);
|
633 |
|
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
|
634 |
|
return v;
|
635 |
|
}
|
636 |
|
};
|
|
608 |
@Override
|
|
609 |
public void onClick(View v)
|
|
610 |
{
|
|
611 |
mPlayPopup.dismiss();
|
|
612 |
mLevelValue = but+1;
|
|
613 |
act.getPreRender().scrambleObject(mLevelValue);
|
|
614 |
}
|
|
615 |
});
|
637 |
616 |
|
638 |
|
mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
639 |
|
mLevelSpinner.setAdapter(mSpinnerAdapter);
|
|
617 |
mPlayLayout.addView(button);
|
|
618 |
}
|
640 |
619 |
}
|
641 |
620 |
|
642 |
621 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
... | ... | |
667 |
646 |
return mSize;
|
668 |
647 |
}
|
669 |
648 |
|
670 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
671 |
|
|
672 |
|
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
|
673 |
|
{
|
674 |
|
mLevelValue = pos+1;
|
675 |
|
}
|
676 |
|
|
677 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
678 |
|
|
679 |
|
public void onNothingSelected(AdapterView<?> parent) { }
|
680 |
|
|
681 |
649 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
682 |
650 |
|
683 |
651 |
public void onActionFinished(final long effectID)
|
Add hiding the Navigation bar (still unfinished, the bar re-appears when a DialogFragment or a PopupWindow appears)
Integrate the Level Spinner and the Play button into one
Move the Menu button up