Project

General

Profile

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

magiccube / src / main / java / org / distorted / config / ConfigScreen.java @ 8bf8fe70

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
import android.content.res.Resources;
23
import android.graphics.drawable.BitmapDrawable;
24
import android.os.Build;
25
import android.util.TypedValue;
26
import android.view.Gravity;
27
import android.view.View;
28
import android.widget.GridLayout;
29
import android.widget.ImageButton;
30
import android.widget.LinearLayout;
31
import android.widget.PopupWindow;
32
import android.widget.ScrollView;
33
import android.widget.TextView;
34

    
35
import org.distorted.objectlib.main.ObjectControl;
36
import org.distorted.objectlib.main.ObjectType;
37

    
38
import org.distorted.helpers.TransparentImageButton;
39
import org.distorted.main.R;
40
import org.distorted.main.RubikActivity;
41

    
42
import static android.view.View.inflate;
43
import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
44

    
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46

    
47
public class ConfigScreen
48
{
49
  private static final int NUM_COLUMNS = 4;
50
  private static final int[] mLocation = new int[2];
51

    
52
  private TransparentImageButton mBackButton, mObjectButton, mPrevButton, mNextButton;
53
  private TextView mMovesText;
54
  private PopupWindow mObjectPopup;
55
  private LinearLayout mDetailsLayout, mComplexLayout, mMeshLayout;
56
  private int mObjectOrdinal;
57
  private int mColCount, mRowCount, mMaxRowCount;
58
  private int mObjectSize;
59
  private int mBarHeight;
60
  private float mButtonSize;
61

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

    
64
  private void setupObjectWindow(final ConfigActivity act, final float width, final float height)
65
    {
66
    int icon = RubikActivity.getDrawable(R.drawable.cube_2s,R.drawable.cube_2m, R.drawable.cube_2b, R.drawable.cube_2h);
67

    
68
    Resources res = act.getResources();
69
    BitmapDrawable bd = (BitmapDrawable)res.getDrawable(icon);
70
    int cubeWidth = bd.getIntrinsicWidth();
71
    int margin = (int)(width*RubikActivity.LARGE_MARGIN);
72
    mObjectSize = (int)(cubeWidth + 2*margin + 0.5f);
73
    mMaxRowCount = (int)((height-mBarHeight)/mObjectSize);
74

    
75
    ScrollView view = (ScrollView)inflate( act, R.layout.popup_object_simple, null);
76
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
77

    
78
    GridLayout.Spec[] rowSpecs = new GridLayout.Spec[mRowCount];
79
    GridLayout.Spec[] colSpecs = new GridLayout.Spec[mColCount];
80

    
81
    objectGrid.setColumnCount(mColCount);
82
    objectGrid.setRowCount(mRowCount);
83

    
84
    mObjectPopup = new PopupWindow(act);
85
    mObjectPopup.setFocusable(true);
86
    mObjectPopup.setContentView(view);
87

    
88
    int[] nextInRow = new int[mRowCount];
89

    
90
    for(int row=0; row<mRowCount; row++)
91
      {
92
      rowSpecs[row] = GridLayout.spec(row);
93
      nextInRow[row]= 0;
94
      }
95
    for(int col=0; col<mColCount; col++)
96
      {
97
      colSpecs[col] = GridLayout.spec(col);
98
      }
99

    
100
    for(int object = 0; object< NUM_OBJECTS; object++)
101
      {
102
      final int ordinal = object;
103
      ObjectType type = ObjectType.getObject(ordinal);
104
      int iconSize = RubikActivity.getDrawableSize();
105
      int icons = type.getIconID(iconSize);
106
      int row = object/NUM_COLUMNS;
107

    
108
      ImageButton button = new ImageButton(act);
109
      button.setBackgroundResource(icons);
110
      button.setOnClickListener( new View.OnClickListener()
111
        {
112
        @Override
113
        public void onClick(View v)
114
          {
115
          if( act.getControl().isUINotBlocked() && mObjectOrdinal!=ordinal )
116
            {
117
            mObjectOrdinal = ordinal;
118
            act.changeObject(type);
119
            mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,NUM_OBJECTS));
120
            setupInfo(act);
121
            }
122

    
123
          mObjectPopup.dismiss();
124
          }
125
        });
126

    
127
      GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpecs[row],colSpecs[nextInRow[row]]);
128
      params.bottomMargin = margin;
129
      params.topMargin    = margin;
130
      params.leftMargin   = margin;
131
      params.rightMargin  = margin;
132

    
133
      nextInRow[row]++;
134

    
135
      objectGrid.addView(button, params);
136
      }
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  private void setupBackButton(final ConfigActivity act)
142
    {
143
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_smallback,R.drawable.ui_medium_smallback, R.drawable.ui_big_smallback, R.drawable.ui_huge_smallback);
144
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
145
    mBackButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
146

    
147
    mBackButton.setOnClickListener( new View.OnClickListener()
148
      {
149
      @Override
150
      public void onClick(View v)
151
        {
152
        ObjectControl control = act.getControl();
153
        if( control!=null ) control.unblockEverything();
154
        act.finish();
155
        }
156
      });
157
    }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
  private void setupObjectButton(final ConfigActivity act, final int width)
162
    {
163
    final int margin= (int)(width*RubikActivity.MARGIN);
164
    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);
165
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
166
    mObjectButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
167

    
168
    mObjectButton.setOnClickListener( new View.OnClickListener()
169
      {
170
      @Override
171
      public void onClick(View view)
172
        {
173
        if( mObjectPopup==null )
174
          {
175
          float height= act.getScreenHeightInPixels();
176
          setupObjectWindow(act,width,height);
177
          }
178

    
179
        if( act.getControl().isUINotBlocked())
180
          {
181
          int rowCount = Math.min(mMaxRowCount,mRowCount);
182
          View popupView = mObjectPopup.getContentView();
183
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
184
          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount,margin,margin);
185
          }
186
        }
187
      });
188
    }
189

    
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
192

    
193
  private void displayPopup(ConfigActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
194
    {
195
    View topLayout = act.findViewById(R.id.mainLayout);
196
    boolean isFullScreen;
197

    
198
    if( topLayout!=null )
199
      {
200
      topLayout.getLocationOnScreen(mLocation);
201
      isFullScreen = (mLocation[1]==0);
202
      }
203
    else
204
      {
205
      isFullScreen = true;
206
      }
207

    
208
    try
209
      {
210
      // if on Android 11 or we are fullscreen
211
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
212
        {
213
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
214
        window.update(view, w, h);
215
        }
216
      else  // Android 10 or below in pop-up mode or split-screen mode
217
        {
218
        view.getLocationOnScreen(mLocation);
219
        int width  = view.getWidth();
220
        int height = view.getHeight();
221
        int x = mLocation[0]+(width-w)/2;
222
        int y = mLocation[1]+height+yoff;
223

    
224
        window.showAsDropDown(view);
225
        window.update(x,y,w,h);
226
        }
227
      }
228
    catch( IllegalArgumentException iae )
229
      {
230
      // ignore, this means window is 'not attached to window manager' -
231
      // which most probably is because we are already exiting the app.
232
      }
233
    }
234

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

    
237
  private void prevObject(ConfigActivity act)
238
    {
239
    mObjectOrdinal--;
240
    if( mObjectOrdinal<0 ) mObjectOrdinal=NUM_OBJECTS-1;
241

    
242
    ObjectType type = ObjectType.getObject(mObjectOrdinal);
243
    act.changeObject(type);
244

    
245
    setupInfo(act);
246
    }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

    
250
  private void nextObject(ConfigActivity act)
251
    {
252
    mObjectOrdinal++;
253
    if( mObjectOrdinal>=NUM_OBJECTS ) mObjectOrdinal=0;
254

    
255
    ObjectType type = ObjectType.getObject(mObjectOrdinal);
256
    act.changeObject(type);
257

    
258
    setupInfo(act);
259
    }
260

    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

    
263
  private void setupPrevButton(final ConfigActivity act)
264
    {
265
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_left,R.drawable.ui_medium_left, R.drawable.ui_big_left, R.drawable.ui_huge_left);
266
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
267
    mPrevButton = new TransparentImageButton(act,icon,TransparentImageButton.GRAVITY_MIDDLE,params);
268

    
269
    mPrevButton.setOnClickListener( new View.OnClickListener()
270
      {
271
      @Override
272
      public void onClick(View v)
273
        {
274
        prevObject(act);
275
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,NUM_OBJECTS));
276
        }
277
      });
278
    }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  private void setupNextButton(final ConfigActivity act)
283
    {
284
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_right,R.drawable.ui_medium_right, R.drawable.ui_big_right, R.drawable.ui_huge_right);
285
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
286
    mNextButton = new TransparentImageButton(act,icon,TransparentImageButton.GRAVITY_MIDDLE,params);
287

    
288
    mNextButton.setOnClickListener( new View.OnClickListener()
289
      {
290
      @Override
291
      public void onClick(View v)
292
        {
293
        nextObject(act);
294
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,NUM_OBJECTS));
295
        }
296
      });
297
    }
298

    
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

    
301
  private void setupTextView(final ConfigActivity act, final float width)
302
    {
303
    int padding = (int)(width*RubikActivity.PADDING);
304
    int margin  = (int)(width*RubikActivity.MARGIN);
305
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,2.0f);
306
    params.topMargin    = margin;
307
    params.bottomMargin = margin;
308
    params.leftMargin   = margin;
309
    params.rightMargin  = margin;
310

    
311
    mMovesText = new TextView(act);
312
    mMovesText.setTextSize(20);
313
    mMovesText.setLayoutParams(params);
314
    mMovesText.setPadding(padding,0,padding,0);
315
    mMovesText.setGravity(Gravity.CENTER);
316
    mMovesText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
317
    mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,NUM_OBJECTS));
318
    }
319

    
320

    
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322

    
323
  private LinearLayout createLayout(ConfigActivity act, final int marginT, final int marginB, final int marginS, final int color)
324
    {
325
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,200);//LinearLayout.LayoutParams.WRAP_CONTENT);
326
    params.bottomMargin = marginB;
327
    params.topMargin    = marginT;
328
    params.leftMargin   = marginS;
329
    params.rightMargin  = marginS;
330

    
331
    LinearLayout layout = new LinearLayout(act);
332
    layout.setLayoutParams(params);
333
    layout.setBackgroundColor(color);
334

    
335
    return layout;
336
    }
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

    
340
  private void setupDetailsLayout(ConfigActivity act, final float width)
341
    {
342

    
343
    }
344

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

    
347
  private void setupComplexLayout(ConfigActivity act, final float width)
348
    {
349

    
350

    
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

    
355
  private void setupMeshLayout(ConfigActivity act, final float width)
356
    {
357

    
358

    
359
    }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

    
363
  private void setupInfo(ConfigActivity act)
364
    {
365
    int width = act.getScreenWidthInPixels();
366

    
367
    setupDetailsLayout(act,width);
368
    setupComplexLayout(act,width);
369
    setupMeshLayout(act,width);
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  void enterScreen(final ConfigActivity act, final int objectOrdinal)
375
    {
376
    int width = act.getScreenWidthInPixels();
377
    mBarHeight = act.getHeightBar();
378
    mButtonSize = width*RubikActivity.BUTTON_TEXT_SIZE;
379

    
380
    mRowCount = (NUM_OBJECTS + NUM_COLUMNS-1) / NUM_COLUMNS;
381
    mColCount = NUM_COLUMNS;
382

    
383
    mObjectOrdinal = objectOrdinal;
384

    
385
    LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams((int)(width/4),LinearLayout.LayoutParams.MATCH_PARENT);
386
    LinearLayout.LayoutParams paramsM = new LinearLayout.LayoutParams((int)(width/2),LinearLayout.LayoutParams.MATCH_PARENT);
387
    LinearLayout.LayoutParams paramsR = new LinearLayout.LayoutParams((int)(width/4),LinearLayout.LayoutParams.MATCH_PARENT);
388

    
389
    LinearLayout layoutLeft = new LinearLayout(act);
390
    layoutLeft.setLayoutParams(paramsL);
391
    LinearLayout layoutMid  = new LinearLayout(act);
392
    layoutMid.setLayoutParams(paramsM);
393
    LinearLayout layoutRight= new LinearLayout(act);
394
    layoutRight.setLayoutParams(paramsR);
395

    
396
    setupObjectButton(act,width);
397
    setupPrevButton(act);
398
    setupNextButton(act);
399
    setupTextView(act,width);
400
    setupBackButton(act);
401

    
402
    layoutLeft.addView(mObjectButton);
403
    layoutMid.addView(mPrevButton);
404
    layoutMid.addView(mMovesText);
405
    layoutMid.addView(mNextButton);
406
    layoutRight.addView(mBackButton);
407

    
408
    LinearLayout layout = act.findViewById(R.id.lowerBar);
409
    layout.removeAllViews();
410
    layout.addView(layoutLeft);
411
    layout.addView(layoutMid);
412
    layout.addView(layoutRight);
413

    
414
    int color = act.getResources().getColor(R.color.light_grey);
415
    int margin = (int)(1.5f*width*RubikActivity.PADDING);
416

    
417
    mDetailsLayout = createLayout(act,2*margin,  margin, 2*margin, color);
418
    mComplexLayout = createLayout(act,  margin,  margin, 2*margin, color);
419
    mMeshLayout    = createLayout(act,  margin,2*margin, 2*margin, color);
420

    
421
    LinearLayout configLayout = act.findViewById(R.id.configLayout);
422
    configLayout.removeAllViews();
423
    configLayout.addView(mDetailsLayout);
424
    configLayout.addView(mComplexLayout);
425
    configLayout.addView(mMeshLayout);
426
    }
427
}
(4-4/5)