Project

General

Profile

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

magiccube / src / main / java / org / distorted / screens / RubikScreenPlay.java @ 63dd19c4

1 211b48f2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 fcd5b990 Leszek Koltunski
package org.distorted.screens;
21 211b48f2 Leszek Koltunski
22 4c0cd600 Leszek Koltunski
import android.content.Context;
23 211b48f2 Leszek Koltunski
import android.content.SharedPreferences;
24 b600ccd9 Leszek Koltunski
import android.content.res.Resources;
25 4c0cd600 Leszek Koltunski
import android.graphics.drawable.BitmapDrawable;
26 255492a0 Leszek Koltunski
import android.os.Build;
27 e03e0352 Leszek Koltunski
import android.os.Bundle;
28 e3c74c0f Leszek Koltunski
import android.util.TypedValue;
29 255492a0 Leszek Koltunski
import android.view.Gravity;
30 211b48f2 Leszek Koltunski
import android.view.LayoutInflater;
31
import android.view.View;
32
import android.widget.Button;
33 e07c48a2 Leszek Koltunski
import android.widget.GridLayout;
34 211b48f2 Leszek Koltunski
import android.widget.ImageButton;
35
import android.widget.LinearLayout;
36 4c0cd600 Leszek Koltunski
import android.widget.PopupWindow;
37 211b48f2 Leszek Koltunski
38 63dd19c4 Leszek Koltunski
import org.distorted.network.RubikNetwork;
39
import org.distorted.network.RubikUpdates;
40 2afc6754 Leszek Koltunski
import org.distorted.objectlib.main.ObjectControl;
41 3f7a4363 Leszek Koltunski
42
import org.distorted.main.R;
43
import org.distorted.main.RubikActivity;
44 e03e0352 Leszek Koltunski
import org.distorted.dialogs.RubikDialogAbout;
45 a8576d91 Leszek Koltunski
import org.distorted.dialogs.RubikDialogPattern;
46 e03e0352 Leszek Koltunski
import org.distorted.dialogs.RubikDialogScores;
47 234a7582 Leszek Koltunski
import org.distorted.dialogs.RubikDialogTutorial;
48 55e6be1d Leszek Koltunski
import org.distorted.helpers.TransparentButton;
49
import org.distorted.helpers.TransparentImageButton;
50 6a083c6a Leszek Koltunski
import org.distorted.network.RubikScores;
51 d433b50e Leszek Koltunski
import org.distorted.objects.RubikObject;
52
import org.distorted.objects.RubikObjectList;
53 211b48f2 Leszek Koltunski
54 b600ccd9 Leszek Koltunski
import static android.view.View.inflate;
55 88d28110 Leszek Koltunski
56 211b48f2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
57
58 63dd19c4 Leszek Koltunski
public class RubikScreenPlay extends RubikScreenBase implements RubikNetwork.Updatee
59 211b48f2 Leszek Koltunski
  {
60 6e3fcb91 Leszek Koltunski
  public static final int NUM_COLUMNS  = 5;
61 00af5060 Leszek Koltunski
  public static final int LEVELS_SHOWN = 10;
62 211b48f2 Leszek Koltunski
63 7cf2637d Leszek Koltunski
  private static final int[] BUTTON_LABELS = { R.string.scores,
64
                                               R.string.patterns,
65
                                               R.string.solver,
66
                                               R.string.tutorials,
67
                                               R.string.about };
68
69 e03e0352 Leszek Koltunski
  private static final int NUM_BUTTONS = BUTTON_LABELS.length;
70 de62316a Leszek Koltunski
  private static final float LAST_BUTTON = 1.5f;
71 dc78f395 Leszek Koltunski
  private static final int[] mLocation = new int[2];
72 e03e0352 Leszek Koltunski
73 0873a75a Leszek Koltunski
  private TransparentImageButton mObjButton, mMenuButton, mSolveButton, mScrambleButton;
74 033100af Leszek Koltunski
  private TransparentButton mPlayButton;
75 0254cfd7 Leszek Koltunski
  private PopupWindow mObjectPopup, mMenuPopup, mPlayPopup;
76 400ff34d Leszek Koltunski
  private LinearLayout mPlayLayout;
77 0254cfd7 Leszek Koltunski
  private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight, mPlayLayoutWidth;
78 85b09df4 Leszek Koltunski
  private int mLevelValue;
79 e07c48a2 Leszek Koltunski
  private float mButtonSize, mMenuItemSize, mMenuTextSize;
80 598de3ee Leszek Koltunski
  private int mColCount, mRowCount, mMaxRowCount;
81 255492a0 Leszek Koltunski
  private int mUpperBarHeight;
82 dd874ae8 Leszek Koltunski
  private boolean mShouldReactToEndOfScrambling;
83 6e3fcb91 Leszek Koltunski
  private int mBottomHeight;
84 255492a0 Leszek Koltunski
85 211b48f2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
86
87 f5da732a Leszek Koltunski
  void leaveScreen(RubikActivity act)
88 211b48f2 Leszek Koltunski
    {
89 85b09df4 Leszek Koltunski
90 211b48f2 Leszek Koltunski
    }
91
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93
94 f5da732a Leszek Koltunski
  void enterScreen(final RubikActivity act)
95 211b48f2 Leszek Koltunski
    {
96 d433b50e Leszek Koltunski
    int numObjects = RubikObjectList.getNumObjects();
97 e3c74c0f Leszek Koltunski
    float width = act.getScreenWidthInPixels();
98 255492a0 Leszek Koltunski
    mUpperBarHeight = act.getHeightUpperBar();
99 a8576d91 Leszek Koltunski
100 eb376d3a Leszek Koltunski
    mMenuTextSize = width*RubikActivity.MENU_MED_TEXT_SIZE;
101 88fb92ba Leszek Koltunski
    mButtonSize   = width*RubikActivity.BUTTON_TEXT_SIZE;
102
    mMenuItemSize = width*RubikActivity.MENU_ITEM_SIZE;
103 e3c74c0f Leszek Koltunski
104 d433b50e Leszek Koltunski
    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
105 287e91a6 Leszek Koltunski
    mColCount = NUM_COLUMNS;
106 e07c48a2 Leszek Koltunski
107 211b48f2 Leszek Koltunski
    // TOP ////////////////////////////
108 7289fd6c Leszek Koltunski
    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
109 211b48f2 Leszek Koltunski
    layoutTop.removeAllViews();
110 85b09df4 Leszek Koltunski
111 ad0c8e0e Leszek Koltunski
    setupObjectButton(act,width);
112 85b09df4 Leszek Koltunski
    layoutTop.addView(mObjButton);
113 0254cfd7 Leszek Koltunski
114
    setupMenuButton(act,width);
115
    layoutTop.addView(mMenuButton);
116
117 2da68298 Leszek Koltunski
    setupPlayButton(act,width);
118 85b09df4 Leszek Koltunski
    layoutTop.addView(mPlayButton);
119 211b48f2 Leszek Koltunski
120 dd874ae8 Leszek Koltunski
    setupSolveButton(act);
121
    setupScrambleButton(act);
122
    createBottomPane(act,mSolveButton,mScrambleButton);
123 769d7b9f Leszek Koltunski
    }
124 211b48f2 Leszek Koltunski
125 8ab435b9 Leszek Koltunski
//////////////////////////////////////////////////////////////////////////////////////////////////
126 4c0cd600 Leszek Koltunski
127 ad0c8e0e Leszek Koltunski
  private void setupObjectButton(final RubikActivity act, final float width)
128 769d7b9f Leszek Koltunski
    {
129 e07c48a2 Leszek Koltunski
    final int margin  = (int)(width*RubikActivity.MARGIN);
130 6e3fcb91 Leszek Koltunski
    final int lMargin = (int)(width*RubikActivity.LARGE_MARGIN);
131 e07c48a2 Leszek Koltunski
    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);
132 b600ccd9 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
133
    mObjButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
134 769d7b9f Leszek Koltunski
135
    mObjButton.setOnClickListener( new View.OnClickListener()
136
      {
137
      @Override
138
      public void onClick(View view)
139 4c0cd600 Leszek Koltunski
        {
140 2da68298 Leszek Koltunski
        if( mObjectPopup==null )
141
          {
142
          float width = act.getScreenWidthInPixels();
143
          float height= act.getScreenHeightInPixels();
144
          setupObjectWindow(act,width,height);
145
          }
146
147
        if( act.getControl().isUINotBlocked())
148 a42e25a6 Leszek Koltunski
          {
149 598de3ee Leszek Koltunski
          int rowCount = Math.min(mMaxRowCount,mRowCount);
150 c5b4af4a Leszek Koltunski
          View popupView = mObjectPopup.getContentView();
151
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
152 1071fb69 Leszek Koltunski
          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount+mBottomHeight+2*lMargin+5*margin,margin,margin);
153 c5b4af4a Leszek Koltunski
          }
154 769d7b9f Leszek Koltunski
        }
155
      });
156
    }
157 4c0cd600 Leszek Koltunski
158 85b09df4 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
159
160 2da68298 Leszek Koltunski
  private void setupPlayButton(final RubikActivity act, final float width)
161 85b09df4 Leszek Koltunski
    {
162 2da68298 Leszek Koltunski
    final int margin = (int)(width*RubikActivity.MARGIN);
163 d90c55cc Leszek Koltunski
164 033100af Leszek Koltunski
    mPlayButton = new TransparentButton(act, R.string.play, mButtonSize);
165 85b09df4 Leszek Koltunski
166
    mPlayButton.setOnClickListener( new View.OnClickListener()
167
      {
168
      @Override
169 0254cfd7 Leszek Koltunski
      public void onClick(View view)
170 85b09df4 Leszek Koltunski
        {
171 2da68298 Leszek Koltunski
         if( mPlayPopup==null )
172
          {
173
          float width = act.getScreenWidthInPixels();
174
          setupPlayWindow(act,width);
175
          }
176
177
        if( act.getControl().isUINotBlocked())
178 6e194411 Leszek Koltunski
          {
179 d38a302b Leszek Koltunski
          adjustSolvedIcons();
180 2da68298 Leszek Koltunski
          float height= act.getScreenHeightInPixels();
181
          final int maxHeight= (int)(0.9f*(height-mUpperBarHeight) );
182 c5b4af4a Leszek Koltunski
          View popupView = mPlayPopup.getContentView();
183
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
184 400ff34d Leszek Koltunski
          final int object  = RubikObjectList.getCurrObject();
185
          final int dbLevel = RubikObjectList.getDBLevel(object);
186 0a7aa15b Leszek Koltunski
          final int levelsShown = Math.min(dbLevel,LEVELS_SHOWN);
187 d90c55cc Leszek Koltunski
          final int popupHeight = (int)(levelsShown*(mMenuItemSize+margin)+3*margin+mMenuItemSize*(LAST_BUTTON-1.0f));
188 255492a0 Leszek Koltunski
          final int realHeight = Math.min(popupHeight,maxHeight);
189
          displayPopup(act,view,mPlayPopup,mPlayLayoutWidth,realHeight,margin,margin);
190 6fad862b Leszek Koltunski
          }
191 85b09df4 Leszek Koltunski
        }
192
      });
193
    }
194
195 e31abc1e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
196
197 ad0c8e0e Leszek Koltunski
  private void setupMenuButton(final RubikActivity act, final float width)
198 e31abc1e Leszek Koltunski
    {
199 2da68298 Leszek Koltunski
    final int margin = (int)(width*RubikActivity.MARGIN);
200 0254cfd7 Leszek Koltunski
    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);
201 b600ccd9 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
202
    mMenuButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
203 e31abc1e Leszek Koltunski
204 e03e0352 Leszek Koltunski
    mMenuButton.setOnClickListener( new View.OnClickListener()
205 e31abc1e Leszek Koltunski
      {
206
      @Override
207
      public void onClick(View view)
208
        {
209 2da68298 Leszek Koltunski
        if( mMenuPopup==null )
210
          {
211
          float width = act.getScreenWidthInPixels();
212
          setupMenuWindow(act,width);
213
          }
214
215
        if( act.getControl().isUINotBlocked())
216 e03e0352 Leszek Koltunski
          {
217 c5b4af4a Leszek Koltunski
          View popupView = mMenuPopup.getContentView();
218
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
219 255492a0 Leszek Koltunski
          displayPopup(act,view,mMenuPopup,mMenuLayoutWidth,mMenuLayoutHeight,(int)(-width/12),margin);
220 6fad862b Leszek Koltunski
          }
221 e31abc1e Leszek Koltunski
        }
222
      });
223
    }
224
225 4c0cd600 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
226
227 598de3ee Leszek Koltunski
  private void setupObjectWindow(final RubikActivity act, final float width, final float height)
228 4c0cd600 Leszek Koltunski
    {
229 6e3fcb91 Leszek Koltunski
    int cubeWidth = (int)(width/9);
230 598de3ee Leszek Koltunski
    int margin = (int)(width*RubikActivity.LARGE_MARGIN);
231
    mObjectSize = (int)(cubeWidth + 2*margin + 0.5f);
232 0b162619 Leszek Koltunski
    mMaxRowCount = (int)((height-1.8f*mUpperBarHeight)/mObjectSize);
233 598de3ee Leszek Koltunski
234 63dd19c4 Leszek Koltunski
    RubikNetwork network = RubikNetwork.getInstance();
235
    network.signUpForUpdates(this);
236
237 8d1da3f1 Leszek Koltunski
    LinearLayout view = (LinearLayout)inflate( act, R.layout.popup_object, null);
238 b600ccd9 Leszek Koltunski
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
239 e07c48a2 Leszek Koltunski
240
    GridLayout.Spec[] rowSpecs = new GridLayout.Spec[mRowCount];
241
    GridLayout.Spec[] colSpecs = new GridLayout.Spec[mColCount];
242
243 92843d3b Leszek Koltunski
    objectGrid.setColumnCount(mColCount);
244
    objectGrid.setRowCount(mRowCount);
245 e07c48a2 Leszek Koltunski
246 b600ccd9 Leszek Koltunski
    LinearLayout bottomLayout = view.findViewById(R.id.bottomLayout);
247 6e3fcb91 Leszek Koltunski
    setupBottomLayout(act,bottomLayout,(NUM_COLUMNS-2)*mObjectSize);
248 0b162619 Leszek Koltunski
249 b600ccd9 Leszek Koltunski
    mObjectPopup = new PopupWindow(act);
250
    mObjectPopup.setFocusable(true);
251
    mObjectPopup.setContentView(view);
252
253 0501a4b8 Leszek Koltunski
    int[] nextInRow = new int[mRowCount];
254 fa679111 Leszek Koltunski
255 e07c48a2 Leszek Koltunski
    for(int row=0; row<mRowCount; row++)
256
      {
257
      rowSpecs[row] = GridLayout.spec(row);
258 0501a4b8 Leszek Koltunski
      nextInRow[row]= 0;
259 e07c48a2 Leszek Koltunski
      }
260
    for(int col=0; col<mColCount; col++)
261
      {
262
      colSpecs[col] = GridLayout.spec(col);
263
      }
264 769d7b9f Leszek Koltunski
265 d433b50e Leszek Koltunski
    int numObjects = RubikObjectList.getNumObjects();
266
267
    for(int object=0; object<numObjects; object++)
268 769d7b9f Leszek Koltunski
      {
269 d433b50e Leszek Koltunski
      final RubikObject robject = RubikObjectList.getObject(object);
270 6e3fcb91 Leszek Koltunski
      int icons = robject==null ? 0 : robject.getIconID();
271 287e91a6 Leszek Koltunski
      int row = object/NUM_COLUMNS;
272 400ff34d Leszek Koltunski
      final int ordinal = robject==null ? 0 : robject.getOrdinal();
273 769d7b9f Leszek Koltunski
274 7ac0ee88 Leszek Koltunski
      ImageButton button = new ImageButton(act);
275
      button.setBackgroundResource(icons);
276
      button.setOnClickListener( new View.OnClickListener()
277 769d7b9f Leszek Koltunski
        {
278 7ac0ee88 Leszek Koltunski
        @Override
279
        public void onClick(View v)
280 769d7b9f Leszek Koltunski
          {
281 2afc6754 Leszek Koltunski
          if( act.getControl().isUINotBlocked() && ScreenList.getCurrentScreen()== ScreenList.PLAY )
282 769d7b9f Leszek Koltunski
            {
283 400ff34d Leszek Koltunski
            RubikObjectList.setCurrObject(act,ordinal);
284
            act.changeObject(ordinal,true);
285 4c9947bd Leszek Koltunski
            if( mPlayLayout!=null ) adjustLevels(act);
286 dd1a65c1 Leszek Koltunski
            mMovesController.clearMoves(act);
287 769d7b9f Leszek Koltunski
            }
288
289 7ac0ee88 Leszek Koltunski
          mObjectPopup.dismiss();
290
          }
291
        });
292 e07c48a2 Leszek Koltunski
293 7ac0ee88 Leszek Koltunski
      GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpecs[row],colSpecs[nextInRow[row]]);
294
      params.bottomMargin = margin;
295
      params.topMargin    = margin;
296
      params.leftMargin   = margin;
297
      params.rightMargin  = margin;
298 fa679111 Leszek Koltunski
299 6e3fcb91 Leszek Koltunski
      params.width = cubeWidth;
300
      params.height= cubeWidth;
301
302 7ac0ee88 Leszek Koltunski
      nextInRow[row]++;
303
304
      objectGrid.addView(button, params);
305 769d7b9f Leszek Koltunski
      }
306 4c0cd600 Leszek Koltunski
    }
307
308 8d1da3f1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
309
310 d433b50e Leszek Koltunski
  private void setupBottomLayout(final RubikActivity act, final LinearLayout layout, int width)
311 8d1da3f1 Leszek Koltunski
    {
312
    int iconD = RubikActivity.getDrawable(R.drawable.ui_small_info,R.drawable.ui_medium_info, R.drawable.ui_big_info, R.drawable.ui_huge_info);
313
    int iconT = RubikActivity.getDrawable(R.drawable.ui_small_tutorial,R.drawable.ui_medium_tutorial, R.drawable.ui_big_tutorial, R.drawable.ui_huge_tutorial);
314
315
    ImageButton buttonTut = layout.findViewById(R.id.buttonTut);
316
         Button buttonNul = layout.findViewById(R.id.buttonNul);
317
    ImageButton buttonDet = layout.findViewById(R.id.buttonDet);
318
319
    buttonTut.setImageResource(iconT);
320
    buttonDet.setImageResource(iconD);
321
    buttonNul.setVisibility(View.INVISIBLE);
322
323
    buttonNul.setWidth(width);
324
325 6e3fcb91 Leszek Koltunski
    Resources res = act.getResources();
326
    BitmapDrawable bd = (BitmapDrawable)res.getDrawable(iconD);
327
    mBottomHeight = bd.getIntrinsicHeight();
328
329 8d1da3f1 Leszek Koltunski
    TypedValue outValue = new TypedValue();
330
    act.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, outValue, true);
331
    buttonTut.setBackgroundResource(outValue.resourceId);
332
    buttonDet.setBackgroundResource(outValue.resourceId);
333
334
    buttonTut.setOnClickListener( new View.OnClickListener()
335
      {
336
      @Override
337
      public void onClick(View v)
338
        {
339
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
340
        RubikDialogTutorial tDiag = new RubikDialogTutorial();
341
        tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
342
        }
343
      });
344
345
    buttonDet.setOnClickListener( new View.OnClickListener()
346
      {
347
      @Override
348
      public void onClick(View v)
349
        {
350 f12e4de9 Leszek Koltunski
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
351 400ff34d Leszek Koltunski
        int currObject = RubikObjectList.getCurrObject();
352
        act.switchConfig(currObject);
353 8d1da3f1 Leszek Koltunski
        }
354
      });
355
    }
356
357 e03e0352 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
358
359 ad0c8e0e Leszek Koltunski
  private void setupMenuWindow(final RubikActivity act, final float width)
360 e03e0352 Leszek Koltunski
    {
361
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
362 e07c48a2 Leszek Koltunski
    final View layout = layoutInflater.inflate(R.layout.popup_menu, null);
363
    LinearLayout menuLayout = layout.findViewById(R.id.menuGrid);
364 e03e0352 Leszek Koltunski
365
    mMenuPopup = new PopupWindow(act);
366
    mMenuPopup.setContentView(layout);
367
    mMenuPopup.setFocusable(true);
368 ad0c8e0e Leszek Koltunski
    int margin  = (int)(width*RubikActivity.MARGIN);
369
    int padding = (int)(width*RubikActivity.PADDING);
370 e03e0352 Leszek Koltunski
371 0254cfd7 Leszek Koltunski
    mMenuLayoutWidth = (int)(width/2);
372
    mMenuLayoutHeight= (int)(2*margin + NUM_BUTTONS*(mMenuItemSize+margin));
373
374 43162dfb Leszek Koltunski
    LinearLayout.LayoutParams p = new LinearLayout.LayoutParams( mMenuLayoutWidth - 2*padding, (int)mMenuItemSize);
375 e03e0352 Leszek Koltunski
376
    for(int i=0; i<NUM_BUTTONS; i++)
377
      {
378
      final int but = i;
379
      Button button = new Button(act);
380 43162dfb Leszek Koltunski
      button.setLayoutParams(p);
381 e03e0352 Leszek Koltunski
      button.setText(BUTTON_LABELS[i]);
382 88fb92ba Leszek Koltunski
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
383 e03e0352 Leszek Koltunski
384
      button.setOnClickListener( new View.OnClickListener()
385
        {
386
        @Override
387
        public void onClick(View v)
388
          {
389
          mMenuPopup.dismiss();
390 0254cfd7 Leszek Koltunski
          MenuAction(act,but);
391 e03e0352 Leszek Koltunski
          }
392
        });
393
394 e07c48a2 Leszek Koltunski
      menuLayout.addView(button);
395 e03e0352 Leszek Koltunski
      }
396 0254cfd7 Leszek Koltunski
    }
397 e03e0352 Leszek Koltunski
398 0254cfd7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
399
400
  private void setupPlayWindow(final RubikActivity act, final float width)
401
    {
402
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
403
    final View layout = layoutInflater.inflate(R.layout.popup_play, null);
404
    mPlayLayout = layout.findViewById(R.id.playGrid);
405
406
    mPlayLayoutWidth = (int)(width*0.4f);
407
408
    mPlayPopup = new PopupWindow(act);
409
    mPlayPopup.setContentView(layout);
410
    mPlayPopup.setFocusable(true);
411
412
    adjustLevels(act);
413 e03e0352 Leszek Koltunski
    }
414
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417 0254cfd7 Leszek Koltunski
  private void MenuAction(RubikActivity act, int button)
418 e03e0352 Leszek Koltunski
    {
419
    switch(button)
420
      {
421 8ab435b9 Leszek Koltunski
      case 0: Bundle sBundle = new Bundle();
422 400ff34d Leszek Koltunski
              int currObject = RubikObjectList.getCurrObject();
423
              sBundle.putInt("tab", currObject );
424 a8576d91 Leszek Koltunski
              sBundle.putBoolean("submitting", false);
425 e03e0352 Leszek Koltunski
              RubikDialogScores scores = new RubikDialogScores();
426 a8576d91 Leszek Koltunski
              scores.setArguments(sBundle);
427 e03e0352 Leszek Koltunski
              scores.show(act.getSupportFragmentManager(), null);
428
              break;
429 234a7582 Leszek Koltunski
      case 1: RubikDialogPattern pDiag = new RubikDialogPattern();
430
              pDiag.show( act.getSupportFragmentManager(), RubikDialogPattern.getDialogTag() );
431 e03e0352 Leszek Koltunski
              break;
432 b2a92941 Leszek Koltunski
      case 2: ScreenList.switchScreen(act, ScreenList.SVER);
433 e03e0352 Leszek Koltunski
              break;
434 b2a92941 Leszek Koltunski
      case 3: RubikDialogTutorial tDiag = new RubikDialogTutorial();
435 234a7582 Leszek Koltunski
              tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
436 2971588c Leszek Koltunski
              break;
437 b2a92941 Leszek Koltunski
      case 4: RubikDialogAbout aDiag = new RubikDialogAbout();
438 a8576d91 Leszek Koltunski
              aDiag.show(act.getSupportFragmentManager(), null);
439 e03e0352 Leszek Koltunski
              break;
440
      }
441
    }
442
443 46405bb4 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
444
445 dd874ae8 Leszek Koltunski
  void setupSolveButton(final RubikActivity act)
446 46405bb4 Leszek Koltunski
    {
447 dd874ae8 Leszek Koltunski
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_solve_new,R.drawable.ui_medium_cube_solve_new, R.drawable.ui_big_cube_solve_new, R.drawable.ui_huge_cube_solve_new);
448 b600ccd9 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
449
    mSolveButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_END,params);
450 46405bb4 Leszek Koltunski
451 a8576d91 Leszek Koltunski
    mSolveButton.setOnClickListener( new View.OnClickListener()
452 46405bb4 Leszek Koltunski
      {
453 a8576d91 Leszek Koltunski
      @Override
454
      public void onClick(View v)
455
        {
456 2afc6754 Leszek Koltunski
        act.getControl().solveObject();
457 dd1a65c1 Leszek Koltunski
        mMovesController.clearMoves(act);
458 a8576d91 Leszek Koltunski
        }
459
      });
460 46405bb4 Leszek Koltunski
    }
461
462 dd874ae8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
463
464
  private void setupScrambleButton(final RubikActivity act)
465
    {
466
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_scramble_new,R.drawable.ui_medium_cube_scramble_new, R.drawable.ui_big_cube_scramble_new, R.drawable.ui_huge_cube_scramble_new);
467 b600ccd9 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
468
    mScrambleButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_START, params);
469 dd874ae8 Leszek Koltunski
470
    mScrambleButton.setOnClickListener( new View.OnClickListener()
471
      {
472
      @Override
473
      public void onClick(View v)
474
        {
475 400ff34d Leszek Koltunski
        int currObject = RubikObjectList.getCurrObject();
476
        RubikObject object = RubikObjectList.getObject(currObject);
477 d433b50e Leszek Koltunski
        int numScrambles = object==null ? 0 : object.getNumScramble();
478 dd874ae8 Leszek Koltunski
        mShouldReactToEndOfScrambling = false;
479
        act.getControl().scrambleObject(numScrambles);
480
        }
481
      });
482
    }
483
484 211b48f2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
485 3398a606 Leszek Koltunski
// This is necessary! Otherwise the ObjectPopup will not be re-created next time and we will still
486
// hold a reference to the old instance of the RubikActivity class (because setupObjectWindow is not
487
// going to be called)
488
// An reference to the old instance of RubikActivity will cause all sorts of strange issues.
489 211b48f2 Leszek Koltunski
490
  public void savePreferences(SharedPreferences.Editor editor)
491
    {
492 d38a302b Leszek Koltunski
    editor.putInt("play_LevelValue", mLevelValue );
493
494 3398a606 Leszek Koltunski
    if( mObjectPopup!=null )
495
      {
496
      mObjectPopup.dismiss();
497
      mObjectPopup = null;
498
      }
499 87d86e5f Leszek Koltunski
500 3398a606 Leszek Koltunski
    if( mMenuPopup!=null )
501
      {
502
      mMenuPopup.dismiss();
503
      mMenuPopup = null;
504
      }
505
506
    if( mPlayPopup!=null )
507
      {
508
      mPlayPopup.dismiss();
509
      mPlayPopup = null;
510
      }
511 211b48f2 Leszek Koltunski
    }
512
513
///////////////////////////////////////////////////////////////////////////////////////////////////
514
515
  public void restorePreferences(SharedPreferences preferences)
516
    {
517 d38a302b Leszek Koltunski
    mLevelValue = preferences.getInt("play_LevelValue", 0);
518 211b48f2 Leszek Koltunski
    }
519
520 53f23b64 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
521
522 400ff34d Leszek Koltunski
  public void setCurrObject(RubikActivity act)
523 53f23b64 Leszek Koltunski
    {
524 400ff34d Leszek Koltunski
    if( mPlayLayout!=null ) adjustLevels(act);
525 7b7d65ce Leszek Koltunski
    }
526
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528 255492a0 Leszek Koltunski
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
529
530
  private void displayPopup(RubikActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
531
    {
532
    View topLayout = act.findViewById(R.id.relativeLayout);
533 7ac0ee88 Leszek Koltunski
    boolean isFullScreen;
534 00aa398a Leszek Koltunski
535
    if( topLayout!=null )
536
      {
537
      topLayout.getLocationOnScreen(mLocation);
538 7ac0ee88 Leszek Koltunski
      isFullScreen = (mLocation[1]==0);
539 00aa398a Leszek Koltunski
      }
540
    else
541
      {
542 7ac0ee88 Leszek Koltunski
      isFullScreen = true;
543 00aa398a Leszek Koltunski
      }
544 255492a0 Leszek Koltunski
545 69a271f3 Leszek Koltunski
    try
546 255492a0 Leszek Koltunski
      {
547 69a271f3 Leszek Koltunski
      // if on Android 11 or we are fullscreen
548
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
549
        {
550
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
551
        window.update(view, w, h);
552
        }
553
      else  // Android 10 or below in pop-up mode or split-screen mode
554
        {
555
        view.getLocationOnScreen(mLocation);
556
        int width  = view.getWidth();
557
        int height = view.getHeight();
558
        int x = mLocation[0]+(width-w)/2;
559
        int y = mLocation[1]+height+yoff;
560
561
        window.showAsDropDown(view);
562
        window.update(x,y,w,h);
563
        }
564 255492a0 Leszek Koltunski
      }
565 69a271f3 Leszek Koltunski
    catch( IllegalArgumentException iae )
566 255492a0 Leszek Koltunski
      {
567 69a271f3 Leszek Koltunski
      // ignore, this means window is 'not attached to window manager' -
568
      // which most probably is because we are already exiting the app.
569 255492a0 Leszek Koltunski
      }
570
    }
571
572 ae77f661 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
573
574 d38a302b Leszek Koltunski
  private void adjustSolvedIcons()
575 ae77f661 Leszek Koltunski
    {
576 59cc16ae Leszek Koltunski
    if( mPlayLayout!=null )
577 ae77f661 Leszek Koltunski
      {
578 59cc16ae Leszek Koltunski
      int currObject = RubikObjectList.getCurrObject();
579
      int dbLevel = RubikObjectList.getDBLevel(currObject);
580
      int numLevel= Math.min(dbLevel, LEVELS_SHOWN);
581
      RubikScores scores = RubikScores.getInstance();
582
583
      for(int i=0; i<numLevel; i++)
584
        {
585
        int level = i<numLevel-1 ? i+1 : dbLevel;
586
        Button button = (Button)mPlayLayout.getChildAt(i);
587
        int icon = scores.isSolved(currObject, level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
588
        button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
589
        }
590 ae77f661 Leszek Koltunski
      }
591
    }
592
593 255492a0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
594 7b7d65ce Leszek Koltunski
595 0254cfd7 Leszek Koltunski
  private void adjustLevels(final RubikActivity act)
596 7b7d65ce Leszek Koltunski
    {
597 400ff34d Leszek Koltunski
    int currObject = RubikObjectList.getCurrObject();
598
    int dbLevel = RubikObjectList.getDBLevel(currObject);
599
    RubikObject object = RubikObjectList.getObject(currObject);
600 d433b50e Leszek Koltunski
    int numScrambles = object==null ? 0 : object.getNumScramble();
601 0a7aa15b Leszek Koltunski
    int numLevel = Math.min(dbLevel, LEVELS_SHOWN);
602 00af5060 Leszek Koltunski
    String[] levels = new String[numLevel];
603 7b7d65ce Leszek Koltunski
604 00af5060 Leszek Koltunski
    for(int i=0; i<numLevel-1; i++)
605 53f23b64 Leszek Koltunski
      {
606 7b7d65ce Leszek Koltunski
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
607 53f23b64 Leszek Koltunski
      }
608
609 4fc7b1e6 Leszek Koltunski
    if( numLevel>0 )
610
      {
611
      levels[numLevel-1] = act.getString(R.string.level_full);
612
      }
613 00af5060 Leszek Koltunski
614 0a7aa15b Leszek Koltunski
    if( mLevelValue>dbLevel || mLevelValue<1 ||
615
       (mLevelValue<dbLevel || mLevelValue>LEVELS_SHOWN ) )
616 00af5060 Leszek Koltunski
      {
617
      mLevelValue=1;
618
      }
619 0254cfd7 Leszek Koltunski
620 de62316a Leszek Koltunski
    float width  = act.getScreenWidthInPixels();
621
    int margin   = (int)(width*RubikActivity.MARGIN);
622
    int padding  = (int)(width*RubikActivity.PADDING);
623
    int butWidth = mPlayLayoutWidth - 2*padding;
624
    int butHeight= (int)mMenuItemSize;
625
    int lastButH = (int)(mMenuItemSize*LAST_BUTTON) ;
626 0254cfd7 Leszek Koltunski
627 de62316a Leszek Koltunski
    LinearLayout.LayoutParams pM = new LinearLayout.LayoutParams( butWidth, butHeight );
628 0254cfd7 Leszek Koltunski
    pM.setMargins(margin, 0, margin, margin);
629 de62316a Leszek Koltunski
    LinearLayout.LayoutParams pT = new LinearLayout.LayoutParams( butWidth, butHeight );
630 0254cfd7 Leszek Koltunski
    pT.setMargins(margin, margin, margin, margin);
631 de62316a Leszek Koltunski
    LinearLayout.LayoutParams pB = new LinearLayout.LayoutParams( butWidth, lastButH  );
632 0254cfd7 Leszek Koltunski
    pB.setMargins(margin, margin, margin, 2*margin);
633
634
    mPlayLayout.removeAllViews();
635
636 d7e539d0 Leszek Koltunski
    RubikScores scores = RubikScores.getInstance();
637
638 00af5060 Leszek Koltunski
    for(int i=0; i<numLevel; i++)
639 011fcfe0 Leszek Koltunski
      {
640 0a7aa15b Leszek Koltunski
      final int level     = i<numLevel-1 ? i+1 : dbLevel;
641
      final int scrambles = i<numLevel-1 ? i+1 : numScrambles;
642 0254cfd7 Leszek Koltunski
      Button button = new Button(act);
643 00af5060 Leszek Koltunski
      button.setLayoutParams(i==0 ? pT : (i==numLevel-1 ? pB : pM));
644 0254cfd7 Leszek Koltunski
      button.setText(levels[i]);
645
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
646
647 400ff34d Leszek Koltunski
      int icon = scores.isSolved(currObject, level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
648 d7e539d0 Leszek Koltunski
      button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
649
650 0254cfd7 Leszek Koltunski
      button.setOnClickListener( new View.OnClickListener()
651 011fcfe0 Leszek Koltunski
        {
652 0254cfd7 Leszek Koltunski
        @Override
653
        public void onClick(View v)
654
          {
655 2afc6754 Leszek Koltunski
          ObjectControl control = act.getControl();
656 6fad862b Leszek Koltunski
657 2afc6754 Leszek Koltunski
          if(control.isUINotBlocked())
658 6fad862b Leszek Koltunski
            {
659 598de3ee Leszek Koltunski
            if( mPlayPopup!=null ) mPlayPopup.dismiss();
660 0a7aa15b Leszek Koltunski
            mLevelValue = level;
661 dd874ae8 Leszek Koltunski
            mShouldReactToEndOfScrambling = true;
662 2afc6754 Leszek Koltunski
            control.scrambleObject(scrambles);
663 6fad862b Leszek Koltunski
            }
664 0254cfd7 Leszek Koltunski
          }
665
        });
666 011fcfe0 Leszek Koltunski
667 0254cfd7 Leszek Koltunski
      mPlayLayout.addView(button);
668
      }
669 53f23b64 Leszek Koltunski
    }
670
671 211b48f2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
672
673 dca3888a Leszek Koltunski
  public int getLevel()
674 211b48f2 Leszek Koltunski
    {
675 85b09df4 Leszek Koltunski
    return mLevelValue;
676 211b48f2 Leszek Koltunski
    }
677
678 dd874ae8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
679
680
  public boolean shouldReactToEndOfScrambling()
681
    {
682
    return mShouldReactToEndOfScrambling;
683
    }
684 63dd19c4 Leszek Koltunski
685
///////////////////////////////////////////////////////////////////////////////////////////////////
686
687
  public void receiveUpdate(RubikUpdates updates)
688
    {
689
    updates.showDebug();
690
    }
691
692
///////////////////////////////////////////////////////////////////////////////////////////////////
693
694
  public void errorUpdate()
695
    {
696
    android.util.Log.e("D", "Error receiving update");
697
    }
698 211b48f2 Leszek Koltunski
  }