Project

General

Profile

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

magiccube / src / main / java / org / distorted / config / ConfigScreen.java @ eb985085

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