Project

General

Profile

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

magiccube / src / main / java / org / distorted / config / ConfigScreen.java @ 306aa049

1 1237d25d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6 9d51b9d6 Leszek Koltunski
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8 1237d25d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.config;
11
12 97a4ae23 Leszek Koltunski
import android.os.Build;
13
import android.util.TypedValue;
14
import android.view.Gravity;
15 1237d25d Leszek Koltunski
import android.view.View;
16 97a4ae23 Leszek Koltunski
import android.widget.GridLayout;
17
import android.widget.ImageButton;
18 1237d25d Leszek Koltunski
import android.widget.LinearLayout;
19 97a4ae23 Leszek Koltunski
import android.widget.PopupWindow;
20
import android.widget.ScrollView;
21
import android.widget.TextView;
22
23
import org.distorted.objectlib.main.ObjectControl;
24 1237d25d Leszek Koltunski
25
import org.distorted.helpers.TransparentImageButton;
26
import org.distorted.main.R;
27
import org.distorted.main.RubikActivity;
28 a7d8c3cd Leszek Koltunski
import org.distorted.objects.RubikObject;
29
import org.distorted.objects.RubikObjectList;
30 97a4ae23 Leszek Koltunski
31
import static android.view.View.inflate;
32 1237d25d Leszek Koltunski
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34
35
public class ConfigScreen
36
{
37 6e3fcb91 Leszek Koltunski
  private static final int NUM_COLUMNS = 5;
38 97a4ae23 Leszek Koltunski
  private static final int[] mLocation = new int[2];
39
40
  private TransparentImageButton mBackButton, mObjectButton, mPrevButton, mNextButton;
41
  private TextView mMovesText;
42
  private PopupWindow mObjectPopup;
43 74d088c3 Leszek Koltunski
  private ConfigScreenPane mPane;
44 97a4ae23 Leszek Koltunski
  private int mObjectOrdinal;
45
  private int mColCount, mRowCount, mMaxRowCount;
46
  private int mObjectSize;
47
  private int mBarHeight;
48
  private float mButtonSize;
49
50
///////////////////////////////////////////////////////////////////////////////////////////////////
51
52
  private void setupObjectWindow(final ConfigActivity act, final float width, final float height)
53
    {
54 6e3fcb91 Leszek Koltunski
    int cubeWidth = (int)(width/9);
55 97a4ae23 Leszek Koltunski
    int margin = (int)(width*RubikActivity.LARGE_MARGIN);
56
    mObjectSize = (int)(cubeWidth + 2*margin + 0.5f);
57
    mMaxRowCount = (int)((height-mBarHeight)/mObjectSize);
58
59
    ScrollView view = (ScrollView)inflate( act, R.layout.popup_object_simple, null);
60
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
61
62
    GridLayout.Spec[] rowSpecs = new GridLayout.Spec[mRowCount];
63
    GridLayout.Spec[] colSpecs = new GridLayout.Spec[mColCount];
64
65
    objectGrid.setColumnCount(mColCount);
66
    objectGrid.setRowCount(mRowCount);
67
68
    mObjectPopup = new PopupWindow(act);
69
    mObjectPopup.setFocusable(true);
70
    mObjectPopup.setContentView(view);
71
72
    int[] nextInRow = new int[mRowCount];
73
74
    for(int row=0; row<mRowCount; row++)
75
      {
76
      rowSpecs[row] = GridLayout.spec(row);
77
      nextInRow[row]= 0;
78
      }
79
    for(int col=0; col<mColCount; col++)
80
      {
81
      colSpecs[col] = GridLayout.spec(col);
82
      }
83
84 a7d8c3cd Leszek Koltunski
    int numObjects = RubikObjectList.getNumObjects();
85
86
    for(int object=0; object<numObjects; object++)
87 97a4ae23 Leszek Koltunski
      {
88
      final int ordinal = object;
89 314e9ff0 Leszek Koltunski
      RubikObject rObject = RubikObjectList.getObject(ordinal);
90 97a4ae23 Leszek Koltunski
      int row = object/NUM_COLUMNS;
91
      ImageButton button = new ImageButton(act);
92 eb985085 Leszek Koltunski
      if( rObject!=null ) rObject.setIconTo(act,button);
93 314e9ff0 Leszek Koltunski
94 97a4ae23 Leszek Koltunski
      button.setOnClickListener( new View.OnClickListener()
95
        {
96
        @Override
97
        public void onClick(View v)
98
          {
99
          if( act.getControl().isUINotBlocked() && mObjectOrdinal!=ordinal )
100
            {
101
            mObjectOrdinal = ordinal;
102 280dc794 Leszek Koltunski
            act.changeObject(mObjectOrdinal);
103 a7d8c3cd Leszek Koltunski
            mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
104 74d088c3 Leszek Koltunski
            mPane.updatePane(act,mObjectOrdinal);
105 97a4ae23 Leszek Koltunski
            }
106
107
          mObjectPopup.dismiss();
108
          }
109
        });
110
111 01e57154 Leszek Koltunski
      GridLayout.Spec rowS = rowSpecs[row];
112
      GridLayout.Spec colS = colSpecs[nextInRow[row]];
113
      GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowS,colS);
114 97a4ae23 Leszek Koltunski
      params.bottomMargin = margin;
115
      params.topMargin    = margin;
116
      params.leftMargin   = margin;
117
      params.rightMargin  = margin;
118
119 6e3fcb91 Leszek Koltunski
      params.width = cubeWidth;
120
      params.height= cubeWidth;
121
122 97a4ae23 Leszek Koltunski
      nextInRow[row]++;
123
124
      objectGrid.addView(button, params);
125
      }
126
    }
127 1237d25d Leszek Koltunski
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129
130
  private void setupBackButton(final ConfigActivity act)
131
    {
132
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_smallback,R.drawable.ui_medium_smallback, R.drawable.ui_big_smallback, R.drawable.ui_huge_smallback);
133 97a4ae23 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
134 1237d25d Leszek Koltunski
    mBackButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
135
136
    mBackButton.setOnClickListener( new View.OnClickListener()
137
      {
138
      @Override
139
      public void onClick(View v)
140
        {
141
        ObjectControl control = act.getControl();
142
        if( control!=null ) control.unblockEverything();
143
        act.finish();
144
        }
145
      });
146
    }
147
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
150 97a4ae23 Leszek Koltunski
  private void setupObjectButton(final ConfigActivity act, final int width)
151 1237d25d Leszek Koltunski
    {
152 c651024f Leszek Koltunski
    final int margin= (int)(width*RubikActivity.SMALL_MARGIN);
153 97a4ae23 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);
154
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
155
    mObjectButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
156
157
    mObjectButton.setOnClickListener( new View.OnClickListener()
158
      {
159
      @Override
160
      public void onClick(View view)
161
        {
162
        if( mObjectPopup==null )
163
          {
164
          float height= act.getScreenHeightInPixels();
165
          setupObjectWindow(act,width,height);
166
          }
167
168
        if( act.getControl().isUINotBlocked())
169
          {
170
          int rowCount = Math.min(mMaxRowCount,mRowCount);
171
          View popupView = mObjectPopup.getContentView();
172
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
173 1071fb69 Leszek Koltunski
          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount+5*margin,margin,margin);
174 97a4ae23 Leszek Koltunski
          }
175
        }
176
      });
177
    }
178
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
181
182
  private void displayPopup(ConfigActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
183
    {
184
    View topLayout = act.findViewById(R.id.mainLayout);
185
    boolean isFullScreen;
186
187
    if( topLayout!=null )
188
      {
189
      topLayout.getLocationOnScreen(mLocation);
190
      isFullScreen = (mLocation[1]==0);
191
      }
192
    else
193
      {
194
      isFullScreen = true;
195
      }
196
197
    try
198
      {
199
      // if on Android 11 or we are fullscreen
200
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
201
        {
202
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
203
        window.update(view, w, h);
204
        }
205
      else  // Android 10 or below in pop-up mode or split-screen mode
206
        {
207
        view.getLocationOnScreen(mLocation);
208
        int width  = view.getWidth();
209
        int height = view.getHeight();
210
        int x = mLocation[0]+(width-w)/2;
211
        int y = mLocation[1]+height+yoff;
212
213
        window.showAsDropDown(view);
214
        window.update(x,y,w,h);
215
        }
216
      }
217
    catch( IllegalArgumentException iae )
218
      {
219
      // ignore, this means window is 'not attached to window manager' -
220
      // which most probably is because we are already exiting the app.
221
      }
222 1237d25d Leszek Koltunski
    }
223
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225
226 a7d8c3cd Leszek Koltunski
  private void prevObject(ConfigActivity act, int numObjects)
227 1237d25d Leszek Koltunski
    {
228 97a4ae23 Leszek Koltunski
    mObjectOrdinal--;
229 a7d8c3cd Leszek Koltunski
    if( mObjectOrdinal<0 ) mObjectOrdinal=numObjects-1;
230 97a4ae23 Leszek Koltunski
231 280dc794 Leszek Koltunski
    act.changeObject(mObjectOrdinal);
232 74d088c3 Leszek Koltunski
    mPane.updatePane(act,mObjectOrdinal);
233 97a4ae23 Leszek Koltunski
    }
234
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236
237 a7d8c3cd Leszek Koltunski
  private void nextObject(ConfigActivity act, int numObjects)
238 97a4ae23 Leszek Koltunski
    {
239
    mObjectOrdinal++;
240 a7d8c3cd Leszek Koltunski
    if( mObjectOrdinal>=numObjects ) mObjectOrdinal=0;
241 97a4ae23 Leszek Koltunski
242 280dc794 Leszek Koltunski
    act.changeObject(mObjectOrdinal);
243 74d088c3 Leszek Koltunski
    mPane.updatePane(act,mObjectOrdinal);
244 97a4ae23 Leszek Koltunski
    }
245
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247
248
  private void setupPrevButton(final ConfigActivity act)
249
    {
250
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_left,R.drawable.ui_medium_left, R.drawable.ui_big_left, R.drawable.ui_huge_left);
251
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
252
    mPrevButton = new TransparentImageButton(act,icon,TransparentImageButton.GRAVITY_MIDDLE,params);
253
254
    mPrevButton.setOnClickListener( new View.OnClickListener()
255
      {
256
      @Override
257
      public void onClick(View v)
258
        {
259 a7d8c3cd Leszek Koltunski
        int numObjects = RubikObjectList.getNumObjects();
260
        prevObject(act,numObjects);
261
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
262 97a4ae23 Leszek Koltunski
        }
263
      });
264
    }
265
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267
268
  private void setupNextButton(final ConfigActivity act)
269
    {
270
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_right,R.drawable.ui_medium_right, R.drawable.ui_big_right, R.drawable.ui_huge_right);
271
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
272
    mNextButton = new TransparentImageButton(act,icon,TransparentImageButton.GRAVITY_MIDDLE,params);
273
274
    mNextButton.setOnClickListener( new View.OnClickListener()
275
      {
276
      @Override
277
      public void onClick(View v)
278
        {
279 a7d8c3cd Leszek Koltunski
        int numObjects = RubikObjectList.getNumObjects();
280
        nextObject(act,numObjects);
281
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
282 97a4ae23 Leszek Koltunski
        }
283
      });
284
    }
285
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287
288 a7d8c3cd Leszek Koltunski
  private void setupTextView(final ConfigActivity act, final float width, int numObjects)
289 97a4ae23 Leszek Koltunski
    {
290
    int padding = (int)(width*RubikActivity.PADDING);
291 c651024f Leszek Koltunski
    int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
292 97a4ae23 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,2.0f);
293
    params.topMargin    = margin;
294
    params.bottomMargin = margin;
295
    params.leftMargin   = margin;
296
    params.rightMargin  = margin;
297
298
    mMovesText = new TextView(act);
299
    mMovesText.setTextSize(20);
300
    mMovesText.setLayoutParams(params);
301
    mMovesText.setPadding(padding,0,padding,0);
302
    mMovesText.setGravity(Gravity.CENTER);
303
    mMovesText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
304 a7d8c3cd Leszek Koltunski
    mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
305 97a4ae23 Leszek Koltunski
    }
306
307 8bf8fe70 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
308
309 74d088c3 Leszek Koltunski
  void onAttachedToWindow(final ConfigActivity act, final int objectOrdinal)
310 97a4ae23 Leszek Koltunski
    {
311 a7d8c3cd Leszek Koltunski
    int numObjects = RubikObjectList.getNumObjects();
312 97a4ae23 Leszek Koltunski
    int width = act.getScreenWidthInPixels();
313
    mBarHeight = act.getHeightBar();
314
    mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
315
316 a7d8c3cd Leszek Koltunski
    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
317 97a4ae23 Leszek Koltunski
    mColCount = NUM_COLUMNS;
318
319
    mObjectOrdinal = objectOrdinal;
320
321 74d088c3 Leszek Koltunski
    LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
322
    LinearLayout.LayoutParams paramsM = new LinearLayout.LayoutParams(width/2, LinearLayout.LayoutParams.MATCH_PARENT);
323
    LinearLayout.LayoutParams paramsR = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
324 97a4ae23 Leszek Koltunski
325
    LinearLayout layoutLeft = new LinearLayout(act);
326
    layoutLeft.setLayoutParams(paramsL);
327
    LinearLayout layoutMid  = new LinearLayout(act);
328
    layoutMid.setLayoutParams(paramsM);
329
    LinearLayout layoutRight= new LinearLayout(act);
330
    layoutRight.setLayoutParams(paramsR);
331
332
    setupObjectButton(act,width);
333
    setupPrevButton(act);
334
    setupNextButton(act);
335 a7d8c3cd Leszek Koltunski
    setupTextView(act,width,numObjects);
336 97a4ae23 Leszek Koltunski
    setupBackButton(act);
337
338
    layoutLeft.addView(mObjectButton);
339
    layoutMid.addView(mPrevButton);
340
    layoutMid.addView(mMovesText);
341
    layoutMid.addView(mNextButton);
342
    layoutRight.addView(mBackButton);
343
344
    LinearLayout layout = act.findViewById(R.id.lowerBar);
345
    layout.removeAllViews();
346
    layout.addView(layoutLeft);
347
    layout.addView(layoutMid);
348
    layout.addView(layoutRight);
349 1237d25d Leszek Koltunski
350 74d088c3 Leszek Koltunski
    mPane = new ConfigScreenPane(act,mObjectOrdinal);
351 1237d25d Leszek Koltunski
    }
352
}