Project

General

Profile

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

magiccube / src / main / java / org / distorted / config / ConfigScreen.java @ 8375250f

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// 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
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.config;
11

    
12
import android.os.Build;
13
import android.util.TypedValue;
14
import android.view.Gravity;
15
import android.view.View;
16
import android.widget.GridLayout;
17
import android.widget.ImageButton;
18
import android.widget.LinearLayout;
19
import android.widget.PopupWindow;
20
import android.widget.ScrollView;
21
import android.widget.TextView;
22

    
23
import org.distorted.objectlib.main.ObjectControl;
24

    
25
import org.distorted.helpers.TransparentImageButton;
26
import org.distorted.main.R;
27
import org.distorted.main.RubikActivity;
28
import org.distorted.objects.RubikObject;
29
import org.distorted.objects.RubikObjectList;
30

    
31
import static android.view.View.inflate;
32

    
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

    
35
public class ConfigScreen
36
{
37
  private static final int NUM_COLUMNS = 5;
38
  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
  private ConfigScreenPane mPane;
44
  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
    int cubeWidth = (int)(width/9);
55
    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
    int numObjects = RubikObjectList.getNumObjects();
85

    
86
    for(int object=0; object<numObjects; object++)
87
      {
88
      final int ordinal = object;
89
      RubikObject rObject = RubikObjectList.getObject(ordinal);
90
      int row = object/NUM_COLUMNS;
91
      ImageButton button = new ImageButton(act);
92
      if( rObject!=null ) rObject.setIconTo(act,button);
93

    
94
      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
            act.changeObject(mObjectOrdinal);
103
            mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
104
            mPane.updatePane(act,mObjectOrdinal);
105
            }
106

    
107
          mObjectPopup.dismiss();
108
          }
109
        });
110

    
111
      GridLayout.Spec rowS = rowSpecs[row];
112
      GridLayout.Spec colS = colSpecs[nextInRow[row]];
113
      GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowS,colS);
114
      params.bottomMargin = margin;
115
      params.topMargin    = margin;
116
      params.leftMargin   = margin;
117
      params.rightMargin  = margin;
118

    
119
      params.width = cubeWidth;
120
      params.height= cubeWidth;
121

    
122
      nextInRow[row]++;
123

    
124
      objectGrid.addView(button, params);
125
      }
126
    }
127

    
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
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
134
    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
  private void setupObjectButton(final ConfigActivity act, final int width)
151
    {
152
    final int margin= (int)(width*RubikActivity.SMALL_MARGIN);
153
    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
          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount+5*margin,margin,margin);
174
          }
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
    }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
  private void prevObject(ConfigActivity act, int numObjects)
227
    {
228
    mObjectOrdinal--;
229
    if( mObjectOrdinal<0 ) mObjectOrdinal=numObjects-1;
230

    
231
    act.changeObject(mObjectOrdinal);
232
    mPane.updatePane(act,mObjectOrdinal);
233
    }
234

    
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

    
237
  private void nextObject(ConfigActivity act, int numObjects)
238
    {
239
    mObjectOrdinal++;
240
    if( mObjectOrdinal>=numObjects ) mObjectOrdinal=0;
241

    
242
    act.changeObject(mObjectOrdinal);
243
    mPane.updatePane(act,mObjectOrdinal);
244
    }
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
        int numObjects = RubikObjectList.getNumObjects();
260
        prevObject(act,numObjects);
261
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
262
        }
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
        int numObjects = RubikObjectList.getNumObjects();
280
        nextObject(act,numObjects);
281
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
282
        }
283
      });
284
    }
285

    
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287

    
288
  private void setupTextView(final ConfigActivity act, final float width, int numObjects)
289
    {
290
    int padding = (int)(width*RubikActivity.PADDING);
291
    int margin  = (int)(width*RubikActivity.SMALL_MARGIN);
292
    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
    mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
305
    }
306

    
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308

    
309
  void onAttachedToWindow(final ConfigActivity act, final int objectOrdinal)
310
    {
311
    int numObjects = RubikObjectList.getNumObjects();
312
    int width = act.getScreenWidthInPixels();
313
    mBarHeight = act.getHeightBar();
314
    mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
315

    
316
    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
317
    mColCount = NUM_COLUMNS;
318

    
319
    mObjectOrdinal = objectOrdinal;
320

    
321
    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

    
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
    setupTextView(act,width,numObjects);
336
    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

    
350
    mPane = new ConfigScreenPane(act,mObjectOrdinal);
351
    }
352
}
(4-4/6)