Added custom number picker for api < 11 compatibility
Extracted number picker (non public) from older android source and included it into this project to remain compatible with devices api level < 11. Devices api level > 11 will use native number pickers as the are public facing in the sdk Change-Id: I7cf7cba066b25516e90bd9951f4de7964b7fd613 Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
@@ -5,7 +5,7 @@
|
|||||||
android:versionCode="15"
|
android:versionCode="15"
|
||||||
android:versionName="2.0" >
|
android:versionName="2.0" >
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="4" />
|
<uses-sdk android:minSdkVersion="7" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|||||||
30
ExaltedDice/res/drawable/timepicker_down_btn.xml
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2008 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:state_pressed="false" android:state_enabled="true"
|
||||||
|
android:state_focused="false" android:drawable="@drawable/timepicker_down_normal" />
|
||||||
|
<item android:state_pressed="true" android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/timepicker_down_pressed" />
|
||||||
|
<item android:state_pressed="false" android:state_enabled="true"
|
||||||
|
android:state_focused="true" android:drawable="@drawable/timepicker_down_selected" />
|
||||||
|
<item android:state_pressed="false" android:state_enabled="false"
|
||||||
|
android:state_focused="false" android:drawable="@drawable/timepicker_down_disabled" />
|
||||||
|
<item android:state_pressed="false" android:state_enabled="false"
|
||||||
|
android:state_focused="true" android:drawable="@drawable/timepicker_down_disabled_focused" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
BIN
ExaltedDice/res/drawable/timepicker_down_disabled.9.png
Executable file
|
After Width: | Height: | Size: 422 B |
BIN
ExaltedDice/res/drawable/timepicker_down_disabled_focused.9.png
Executable file
|
After Width: | Height: | Size: 580 B |
BIN
ExaltedDice/res/drawable/timepicker_down_normal.9.png
Executable file
|
After Width: | Height: | Size: 795 B |
BIN
ExaltedDice/res/drawable/timepicker_down_pressed.9.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
ExaltedDice/res/drawable/timepicker_down_selected.9.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
30
ExaltedDice/res/drawable/timepicker_input.xml
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2008 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:state_pressed="false" android:state_enabled="true"
|
||||||
|
android:state_focused="false" android:drawable="@drawable/timepicker_input_normal" />
|
||||||
|
<item android:state_pressed="true" android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/timepicker_input_pressed" />
|
||||||
|
<item android:state_pressed="false" android:state_enabled="true"
|
||||||
|
android:state_focused="true" android:drawable="@drawable/timepicker_input_selected" />
|
||||||
|
<item android:state_pressed="false" android:state_enabled="false"
|
||||||
|
android:state_focused="false" android:drawable="@drawable/timepicker_input_disabled" />
|
||||||
|
<item android:state_pressed="false" android:state_enabled="false"
|
||||||
|
android:state_focused="true" android:drawable="@drawable/timepicker_input_normal" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
BIN
ExaltedDice/res/drawable/timepicker_input_disabled.9.png
Executable file
|
After Width: | Height: | Size: 280 B |
BIN
ExaltedDice/res/drawable/timepicker_input_normal.9.png
Executable file
|
After Width: | Height: | Size: 582 B |
BIN
ExaltedDice/res/drawable/timepicker_input_pressed.9.png
Executable file
|
After Width: | Height: | Size: 604 B |
BIN
ExaltedDice/res/drawable/timepicker_input_selected.9.png
Executable file
|
After Width: | Height: | Size: 517 B |
30
ExaltedDice/res/drawable/timepicker_up_btn.xml
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2008 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:state_pressed="false" android:state_enabled="true"
|
||||||
|
android:state_focused="false" android:drawable="@drawable/timepicker_up_normal" />
|
||||||
|
<item android:state_pressed="true" android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/timepicker_up_pressed" />
|
||||||
|
<item android:state_pressed="false" android:state_enabled="true"
|
||||||
|
android:state_focused="true" android:drawable="@drawable/timepicker_up_selected" />
|
||||||
|
<item android:state_pressed="false" android:state_enabled="false"
|
||||||
|
android:state_focused="false" android:drawable="@drawable/timepicker_up_disabled" />
|
||||||
|
<item android:state_pressed="false" android:state_enabled="false"
|
||||||
|
android:state_focused="true" android:drawable="@drawable/timepicker_up_disabled_focused" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
BIN
ExaltedDice/res/drawable/timepicker_up_disabled.9.png
Executable file
|
After Width: | Height: | Size: 491 B |
BIN
ExaltedDice/res/drawable/timepicker_up_disabled_focused.9.png
Executable file
|
After Width: | Height: | Size: 728 B |
BIN
ExaltedDice/res/drawable/timepicker_up_normal.9.png
Executable file
|
After Width: | Height: | Size: 989 B |
BIN
ExaltedDice/res/drawable/timepicker_up_pressed.9.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
ExaltedDice/res/drawable/timepicker_up_selected.9.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
24
ExaltedDice/res/layout-v11/dice_selector.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/number_Picker"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="20dip" />
|
||||||
|
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/d_Picker"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="20dip" />
|
||||||
|
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/mod_Picker"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -4,19 +4,17 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal" >
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
<NumberPicker
|
<com.TwentyCode.android.ExaltedDice.NumberPicker
|
||||||
android:id="@+id/number_Picker"
|
android:id="@+id/number_Picker"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content" />
|
||||||
android:layout_marginRight="20dip" />
|
|
||||||
|
|
||||||
<NumberPicker
|
<com.TwentyCode.android.ExaltedDice.NumberPicker
|
||||||
android:id="@+id/d_Picker"
|
android:id="@+id/d_Picker"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content" />
|
||||||
android:layout_marginRight="20dip" />
|
|
||||||
|
|
||||||
<NumberPicker
|
<com.TwentyCode.android.ExaltedDice.NumberPicker
|
||||||
android:id="@+id/mod_Picker"
|
android:id="@+id/mod_Picker"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="0px"
|
android:layout_width="0px"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="2" >
|
android:layout_weight="2.5" >
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/die_selector"
|
android:id="@+id/die_selector"
|
||||||
|
|||||||
49
ExaltedDice/res/layout/number_picker.xml
Executable file
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
* Copyright 2010-2011, Mike Novak <michael.novakjr@gmail.com>
|
||||||
|
* Copyright 2012, Richard Barrette <rickbarrette@gmail.com>
|
||||||
|
* Copyright 2012, Twenty Codes <twentycodes@gmail.com>
|
||||||
|
* Copyright 2008, The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
|
||||||
|
<com.TwentyCode.android.ExaltedDice.NumberPickerButton
|
||||||
|
android:id="@+id/increment"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/timepicker_up_btn" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/timepicker_input"
|
||||||
|
style="?android:attr/textAppearanceLargeInverse"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/timepicker_input"
|
||||||
|
android:gravity="center"
|
||||||
|
android:inputType="number"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="@android:color/primary_text_light"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
|
||||||
|
<com.TwentyCode.android.ExaltedDice.NumberPickerButton
|
||||||
|
android:id="@+id/decrement"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/timepicker_down_btn" />
|
||||||
|
|
||||||
|
</merge>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<declare-styleable name="com.admob.android.ads.AdView">
|
<declare-styleable name="com.admob.android.ads.AdView">
|
||||||
<attr name="backgroundColor" format="color" />
|
<attr name="backgroundColor" format="color" />
|
||||||
<attr name="primaryTextColor" format="color" />
|
<attr name="primaryTextColor" format="color" />
|
||||||
@@ -7,4 +8,12 @@
|
|||||||
<attr name="keywords" format="string" />
|
<attr name="keywords" format="string" />
|
||||||
<attr name="refreshInterval" format="integer" />
|
<attr name="refreshInterval" format="integer" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
</resources>
|
<declare-styleable name="numberpicker">
|
||||||
|
<attr name="startRange" format="integer" />
|
||||||
|
<attr name="endRange" format="integer" />
|
||||||
|
<attr name="defaultValue" format="integer" />
|
||||||
|
<attr name="maxValue" format="integer" />
|
||||||
|
<attr name="wrap" format="boolean" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -44,16 +44,20 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
private ListView mListView;
|
private ListView mListView;
|
||||||
private NumberPicker mNumberPicker;
|
private NumberPicker mNumberPicker;
|
||||||
private NumberPicker mDPicker;
|
private NumberPicker mDPicker;
|
||||||
|
private NumberPicker mModPicker;
|
||||||
private Database mDb;
|
private Database mDb;
|
||||||
private String mGameName;
|
private String mGameName;
|
||||||
private long mGameId;
|
private long mGameId;
|
||||||
private RollHistoryDatabaseAdapter mListAdapter;
|
private RollHistoryDatabaseAdapter mListAdapter;
|
||||||
private SharedPreferences mSettings;
|
private SharedPreferences mSettings;
|
||||||
private String[] mModValues;
|
private String[] mModValues;
|
||||||
private NumberPicker mModPicker;
|
|
||||||
private ProgressBar mRollProgress;
|
private ProgressBar mRollProgress;
|
||||||
private View mRollButton;
|
private View mRollButton;
|
||||||
private boolean isRolling = false;
|
private boolean isRolling = false;
|
||||||
|
private com.TwentyCode.android.ExaltedDice.NumberPicker mCompatDPicker;
|
||||||
|
private com.TwentyCode.android.ExaltedDice.NumberPicker mCompatNumberPicker;
|
||||||
|
private com.TwentyCode.android.ExaltedDice.NumberPicker mCompatModPicker;
|
||||||
|
private boolean isCompat = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the presets from the provided roll
|
* Applies the presets from the provided roll
|
||||||
@@ -63,14 +67,66 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
private void applyRollPresets(long id) {
|
private void applyRollPresets(long id) {
|
||||||
ContentValues roll = mDb.getGameHistoryInfo(mGameName, (int) (id));
|
ContentValues roll = mDb.getGameHistoryInfo(mGameName, (int) (id));
|
||||||
try{
|
try{
|
||||||
|
if(isCompat){
|
||||||
|
mCompatNumberPicker.setValue(roll.getAsInteger(Database.KEY_NUMBER));
|
||||||
|
mCompatDPicker.setValue(parseD(roll.getAsString(Database.KEY_D_TYPE)));
|
||||||
|
mCompatModPicker.setValue(parseMod(roll.getAsString(Database.KEY_MOD).replace("'", "")));
|
||||||
|
} else {
|
||||||
mNumberPicker.setValue(roll.getAsInteger(Database.KEY_NUMBER));
|
mNumberPicker.setValue(roll.getAsInteger(Database.KEY_NUMBER));
|
||||||
mDPicker.setValue(parseD(roll.getAsString(Database.KEY_D_TYPE)));
|
mDPicker.setValue(parseD(roll.getAsString(Database.KEY_D_TYPE)));
|
||||||
mModPicker.setValue(parseMod(roll.getAsString(Database.KEY_MOD).replace("'", "")));
|
mModPicker.setValue(parseMod(roll.getAsString(Database.KEY_MOD).replace("'", "")));
|
||||||
|
}
|
||||||
} catch(NullPointerException e){
|
} catch(NullPointerException e){
|
||||||
|
if(isCompat)
|
||||||
|
mCompatModPicker.setValue(parseMod("+0"));
|
||||||
|
else
|
||||||
mModPicker.setValue(parseMod("+0"));
|
mModPicker.setValue(parseMod("+0"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes compat pickers for api < 11
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
private void initCompatPickers() {
|
||||||
|
isCompat = true;
|
||||||
|
|
||||||
|
mCompatDPicker = (com.TwentyCode.android.ExaltedDice.NumberPicker) findViewById(R.id.d_Picker);
|
||||||
|
mCompatDPicker.setDisplayedValues(mDiceValues);
|
||||||
|
mCompatDPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
||||||
|
|
||||||
|
mCompatNumberPicker = (com.TwentyCode.android.ExaltedDice.NumberPicker) findViewById(R.id.number_Picker);
|
||||||
|
mCompatNumberPicker.setRange(1, 999);
|
||||||
|
mCompatNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
||||||
|
|
||||||
|
mCompatModPicker = (com.TwentyCode.android.ExaltedDice.NumberPicker) findViewById(R.id.mod_Picker);
|
||||||
|
mCompatModPicker.setDisplayedValues(mModValues);
|
||||||
|
mCompatModPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes native number pickers api > 11
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
private void initPickers() {
|
||||||
|
mDPicker = (NumberPicker) findViewById(R.id.d_Picker);
|
||||||
|
mDPicker.setMinValue(0);
|
||||||
|
mDPicker.setMaxValue(mDiceValues.length -1);
|
||||||
|
mDPicker.setDisplayedValues(mDiceValues);
|
||||||
|
mDPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
||||||
|
|
||||||
|
mNumberPicker = (NumberPicker) findViewById(R.id.number_Picker);
|
||||||
|
mNumberPicker.setMaxValue(999);
|
||||||
|
mNumberPicker.setMinValue(1);
|
||||||
|
mNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
||||||
|
|
||||||
|
mModPicker = (NumberPicker) findViewById(R.id.mod_Picker);
|
||||||
|
mModPicker.setMinValue(0);
|
||||||
|
mModPicker.setMaxValue(mModValues.length -1);
|
||||||
|
mModPicker.setDisplayedValues(mModValues);
|
||||||
|
mModPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* also implemented OnClickListener
|
* also implemented OnClickListener
|
||||||
*
|
*
|
||||||
@@ -113,13 +169,21 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
Log.i(TAG, "onCreate()");
|
Log.i(TAG, "onCreate()");
|
||||||
setContentView(R.layout.main);
|
setContentView(R.layout.main);
|
||||||
|
|
||||||
|
mSettings = getSharedPreferences(Settings.SETTINGS, Context.MODE_WORLD_WRITEABLE);
|
||||||
|
|
||||||
|
mDiceValues = getResources().getStringArray(R.array.dice_types);
|
||||||
|
mModValues = getResources().getStringArray(R.array.mods);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following is for api 11 and up
|
* The following is for api 11 and up
|
||||||
|
* else use compat methods
|
||||||
*/
|
*/
|
||||||
if(Integer.valueOf(android.os.Build.VERSION.SDK) > 11){
|
if(Integer.valueOf(android.os.Build.VERSION.SDK) > 11){
|
||||||
ActionBar actionBar = getActionBar();
|
ActionBar actionBar = getActionBar();
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
initPickers();
|
||||||
|
} else
|
||||||
|
initCompatPickers();
|
||||||
|
|
||||||
Intent i = this.getIntent();
|
Intent i = this.getIntent();
|
||||||
if(i != null)
|
if(i != null)
|
||||||
@@ -129,32 +193,10 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
this.setTitle(mGameName);
|
this.setTitle(mGameName);
|
||||||
}
|
}
|
||||||
|
|
||||||
mSettings = getSharedPreferences(Settings.SETTINGS, Context.MODE_WORLD_WRITEABLE);
|
|
||||||
|
|
||||||
mDiceValues = getResources().getStringArray(R.array.dice_types);
|
|
||||||
mModValues = getResources().getStringArray(R.array.mods);
|
|
||||||
|
|
||||||
mListView = (ListView) findViewById(R.id.list);
|
mListView = (ListView) findViewById(R.id.list);
|
||||||
mListView.setOnItemClickListener(this);
|
mListView.setOnItemClickListener(this);
|
||||||
mListView.setStackFromBottom(true);
|
mListView.setStackFromBottom(true);
|
||||||
|
|
||||||
mDPicker = (NumberPicker) findViewById(R.id.d_Picker);
|
|
||||||
mDPicker.setMinValue(0);
|
|
||||||
mDPicker.setMaxValue(mDiceValues.length -1);
|
|
||||||
mDPicker.setDisplayedValues(mDiceValues);
|
|
||||||
mDPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
|
||||||
|
|
||||||
mNumberPicker = (NumberPicker) findViewById(R.id.number_Picker);
|
|
||||||
mNumberPicker.setMaxValue(999);
|
|
||||||
mNumberPicker.setMinValue(1);
|
|
||||||
mNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
|
||||||
|
|
||||||
mModPicker = (NumberPicker) findViewById(R.id.mod_Picker);
|
|
||||||
mModPicker.setMinValue(0);
|
|
||||||
mModPicker.setMaxValue(mModValues.length -1);
|
|
||||||
mModPicker.setDisplayedValues(mModValues);
|
|
||||||
mModPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
|
||||||
|
|
||||||
mRollProgress = (ProgressBar) findViewById(R.id.roll_progress);
|
mRollProgress = (ProgressBar) findViewById(R.id.roll_progress);
|
||||||
|
|
||||||
mRollButton = findViewById(R.id.roll_button);
|
mRollButton = findViewById(R.id.roll_button);
|
||||||
@@ -183,6 +225,40 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDatabaseInsertComplete() {
|
||||||
|
isRolling = false;
|
||||||
|
this.runOnUiThread(new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
mRollProgress.setVisibility(View.GONE);
|
||||||
|
mRollButton.setEnabled(true);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDatabaseUpgrade() {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDatabaseUpgradeComplete() {
|
||||||
|
// do nothing
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeletionComplete() {
|
||||||
|
this.runOnUiThread(new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rolls same amount of dice as previous roll
|
* rolls same amount of dice as previous roll
|
||||||
* @author ricky barrette
|
* @author ricky barrette
|
||||||
@@ -221,15 +297,11 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see android.app.Activity#onPause()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
public void onRestoreComplete() {
|
||||||
mDb.close();
|
// do nothing
|
||||||
super.onStop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* resorts application state after rotation
|
* resorts application state after rotation
|
||||||
* @author ricky barrette
|
* @author ricky barrette
|
||||||
@@ -237,10 +309,16 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
@Override
|
@Override
|
||||||
public void onRestoreInstanceState(Bundle savedInstanceState) {
|
public void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||||
super.onRestoreInstanceState(savedInstanceState);
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
if(isCompat){
|
||||||
|
mCompatDPicker.setCurrent(savedInstanceState.getInt("d"));
|
||||||
|
mCompatNumberPicker.setCurrent(savedInstanceState.getInt("number"));
|
||||||
|
mCompatModPicker.setCurrent(savedInstanceState.getInt("mod"));
|
||||||
|
} else {
|
||||||
mDPicker.setValue(savedInstanceState.getInt("d"));
|
mDPicker.setValue(savedInstanceState.getInt("d"));
|
||||||
mNumberPicker.setValue(savedInstanceState.getInt("number"));
|
mNumberPicker.setValue(savedInstanceState.getInt("number"));
|
||||||
mModPicker.setValue(savedInstanceState.getInt("mod"));
|
mModPicker.setValue(savedInstanceState.getInt("mod"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
@@ -252,14 +330,40 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
applyRollPresets(mDb.getGameRollCount(mGameId));
|
applyRollPresets(mDb.getGameRollCount(mGameId));
|
||||||
|
|
||||||
if(mSettings.getBoolean(Settings.KEY_ROLL_MOD, true)){
|
if(mSettings.getBoolean(Settings.KEY_ROLL_MOD, true)){
|
||||||
|
if(isCompat)
|
||||||
|
mCompatModPicker.setVisibility(View.VISIBLE);
|
||||||
|
else
|
||||||
mModPicker.setVisibility(View.VISIBLE);
|
mModPicker.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
if(isCompat){
|
||||||
|
mCompatModPicker.setVisibility(View.GONE);
|
||||||
|
mCompatModPicker.setValue(parseMod("+0"));
|
||||||
} else {
|
} else {
|
||||||
mModPicker.setVisibility(View.GONE);
|
mModPicker.setVisibility(View.GONE);
|
||||||
mModPicker.setValue(parseMod("+0"));
|
mModPicker.setValue(parseMod("+0"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
super.onResume();
|
super.onResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* saves application state before rotation
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||||
|
if(isCompat){
|
||||||
|
savedInstanceState.putInt("d", mCompatDPicker.getCurrent());
|
||||||
|
savedInstanceState.putInt("number", mCompatNumberPicker.getCurrent());
|
||||||
|
savedInstanceState.putInt("mod", mCompatModPicker.getCurrent());
|
||||||
|
} else {
|
||||||
|
savedInstanceState.putInt("d", mDPicker.getValue());
|
||||||
|
savedInstanceState.putInt("number", mNumberPicker.getValue());
|
||||||
|
savedInstanceState.putInt("mod", mModPicker.getValue());
|
||||||
|
}
|
||||||
|
super.onSaveInstanceState(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see android.app.Activity#onStart()
|
* @see android.app.Activity#onStart()
|
||||||
@@ -273,15 +377,13 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* saves application state before rotation
|
* (non-Javadoc)
|
||||||
* @author ricky barrette
|
* @see android.app.Activity#onPause()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle savedInstanceState) {
|
protected void onStop() {
|
||||||
savedInstanceState.putInt("d", mDPicker.getValue());
|
mDb.close();
|
||||||
savedInstanceState.putInt("number", mNumberPicker.getValue());
|
super.onStop();
|
||||||
savedInstanceState.putInt("mod", mModPicker.getValue());
|
|
||||||
super.onSaveInstanceState(savedInstanceState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -366,6 +468,9 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
resultsString.append(getString(R.string.total)+ total);
|
resultsString.append(getString(R.string.total)+ total);
|
||||||
|
|
||||||
if(mSettings.getBoolean(Settings.KEY_ROLL_MOD, true))
|
if(mSettings.getBoolean(Settings.KEY_ROLL_MOD, true))
|
||||||
|
if(isCompat)
|
||||||
|
resultsString.append(getString(R.string.total_plus_mod)+ (total + Integer.parseInt(mCompatModPicker.getValue().replace("+", ""))));
|
||||||
|
else
|
||||||
resultsString.append(getString(R.string.total_plus_mod)+ (total + Integer.parseInt(mModValues[mModPicker.getValue()].replace("+", ""))));
|
resultsString.append(getString(R.string.total_plus_mod)+ (total + Integer.parseInt(mModValues[mModPicker.getValue()].replace("+", ""))));
|
||||||
|
|
||||||
if(mSettings.getBoolean(Settings.KEY_CALC_SUCCESSES, true))
|
if(mSettings.getBoolean(Settings.KEY_CALC_SUCCESSES, true))
|
||||||
@@ -399,11 +504,20 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
int rollId = mDb.getGameRollCount(mGameId) +1;
|
int rollId = mDb.getGameRollCount(mGameId) +1;
|
||||||
|
|
||||||
ContentValues roll = new ContentValues();
|
ContentValues roll = new ContentValues();
|
||||||
|
|
||||||
|
if(isCompat){
|
||||||
|
roll.put(Database.KEY_D_TYPE, mCompatDPicker.getValue());
|
||||||
|
roll.put(Database.KEY_NUMBER, mCompatNumberPicker.getCurrent());
|
||||||
|
roll.putAll(results(mCompatNumberPicker.getCurrent()));
|
||||||
|
roll.put(Database.KEY_MOD, DatabaseUtils.sqlEscapeString(mCompatModPicker.getValue()));
|
||||||
|
} else{
|
||||||
roll.put(Database.KEY_D_TYPE, mDiceValues[mDPicker.getValue()]);
|
roll.put(Database.KEY_D_TYPE, mDiceValues[mDPicker.getValue()]);
|
||||||
roll.put(Database.KEY_NUMBER, mNumberPicker.getValue());
|
roll.put(Database.KEY_NUMBER, mNumberPicker.getValue());
|
||||||
roll.putAll(results(mNumberPicker.getValue()));
|
roll.putAll(results(mNumberPicker.getValue()));
|
||||||
|
|
||||||
roll.put(Database.KEY_MOD, DatabaseUtils.sqlEscapeString(mModValues[mModPicker.getValue()]));
|
roll.put(Database.KEY_MOD, DatabaseUtils.sqlEscapeString(mModValues[mModPicker.getValue()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mDb.updateGame(mGameId, mGameName, roll, rollId);
|
mDb.updateGame(mGameId, mGameName, roll, rollId);
|
||||||
}
|
}
|
||||||
@@ -422,6 +536,9 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
int[] roll = new int[times];
|
int[] roll = new int[times];
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
for (int i = 0; i < times; i++) {
|
for (int i = 0; i < times; i++) {
|
||||||
|
if(isCompat)
|
||||||
|
roll[i] = random.nextInt(Integer.parseInt(mCompatDPicker.getValue().substring(1))) + 1;
|
||||||
|
else
|
||||||
roll[i] = random.nextInt(Integer.parseInt(mDiceValues[mDPicker.getValue()].substring(1))) + 1;
|
roll[i] = random.nextInt(Integer.parseInt(mDiceValues[mDPicker.getValue()].substring(1))) + 1;
|
||||||
}
|
}
|
||||||
return roll;
|
return roll;
|
||||||
@@ -470,43 +587,4 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
|
|||||||
Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
vib.vibrate(milliseconds);
|
vib.vibrate(milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDatabaseUpgradeComplete() {
|
|
||||||
// do nothing
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDeletionComplete() {
|
|
||||||
this.runOnUiThread(new Runnable(){
|
|
||||||
@Override
|
|
||||||
public void run(){
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRestoreComplete() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDatabaseUpgrade() {
|
|
||||||
//do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDatabaseInsertComplete() {
|
|
||||||
isRolling = false;
|
|
||||||
this.runOnUiThread(new Runnable(){
|
|
||||||
@Override
|
|
||||||
public void run(){
|
|
||||||
mRollProgress.setVisibility(View.GONE);
|
|
||||||
mRollButton.setEnabled(true);
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
488
ExaltedDice/src/com/TwentyCode/android/ExaltedDice/NumberPicker.java
Executable file
@@ -0,0 +1,488 @@
|
|||||||
|
/**
|
||||||
|
* Number Picker.java
|
||||||
|
*
|
||||||
|
* @author Google
|
||||||
|
* @author ricky barrette
|
||||||
|
* @author Twenty Codes
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Rick barrette <rickbarrette@gmail.com>
|
||||||
|
* Copyright (C) 2012 Twenty Codes <twentycodes@gmail.com>
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.TwentyCode.android.ExaltedDice;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.text.InputFilter;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.text.Spanned;
|
||||||
|
import android.text.method.NumberKeyListener;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.view.View.OnFocusChangeListener;
|
||||||
|
import android.view.View.OnLongClickListener;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class has been pulled from the Android platform source code, its an internal widget that hasn't been
|
||||||
|
* made public so its included in the project in this fashion for use with the preferences screen; I have made
|
||||||
|
* a few slight modifications to the code here, I simply put a MAX and MIN default in the code but these values
|
||||||
|
* can still be set publicly by calling code.
|
||||||
|
*
|
||||||
|
* @author Google
|
||||||
|
*/
|
||||||
|
public class NumberPicker extends LinearLayout implements OnClickListener, OnFocusChangeListener, OnLongClickListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to filter the input from a keyboard
|
||||||
|
*/
|
||||||
|
private class NumberPickerInputFilter implements InputFilter {
|
||||||
|
public CharSequence filter(CharSequence source, int start, int end,
|
||||||
|
Spanned dest, int dstart, int dend) {
|
||||||
|
if (mDisplayedValues == null) {
|
||||||
|
return mNumberInputFilter.filter(source, start, end, dest, dstart, dend);
|
||||||
|
}
|
||||||
|
CharSequence filtered = String.valueOf(source.subSequence(start, end));
|
||||||
|
String result = String.valueOf(dest.subSequence(0, dstart))
|
||||||
|
+ filtered
|
||||||
|
+ dest.subSequence(dend, dest.length());
|
||||||
|
String str = String.valueOf(result).toLowerCase();
|
||||||
|
for (String val : mDisplayedValues) {
|
||||||
|
val = val.toLowerCase();
|
||||||
|
if (val.startsWith(str)) {
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class
|
||||||
|
*/
|
||||||
|
private class NumberRangeKeyListener extends NumberKeyListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence filter(CharSequence source, int start, int end,
|
||||||
|
Spanned dest, int dstart, int dend) {
|
||||||
|
|
||||||
|
CharSequence filtered = super.filter(source, start, end, dest, dstart, dend);
|
||||||
|
if (filtered == null) {
|
||||||
|
filtered = source.subSequence(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
String result = String.valueOf(dest.subSequence(0, dstart))
|
||||||
|
+ filtered
|
||||||
|
+ dest.subSequence(dend, dest.length());
|
||||||
|
|
||||||
|
if ("".equals(result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
int val = getSelectedPos(result);
|
||||||
|
|
||||||
|
/* Ensure the user can't type in a value greater
|
||||||
|
* than the max allowed. We have to allow less than min
|
||||||
|
* as the user might want to delete some numbers
|
||||||
|
* and then type a new number.
|
||||||
|
*/
|
||||||
|
if (val > mEnd) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected char[] getAcceptedChars() {
|
||||||
|
return DIGIT_CHARACTERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX This doesn't allow for range limits when controlled by a
|
||||||
|
// soft input method!
|
||||||
|
public int getInputType() {
|
||||||
|
return InputType.TYPE_CLASS_NUMBER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple interface to notify a change has been made
|
||||||
|
*/
|
||||||
|
public interface OnChangedListener {
|
||||||
|
/**
|
||||||
|
* Called when a change has been made
|
||||||
|
* @param picker
|
||||||
|
* @param oldVal
|
||||||
|
* @param newVal
|
||||||
|
*/
|
||||||
|
void onChanged(NumberPicker picker, int oldVal, int newVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int DEFAULT_MAX = 200;
|
||||||
|
private static final int DEFAULT_MIN = 0;
|
||||||
|
private static final int DEFAULT_VALUE = 0;
|
||||||
|
private static final boolean DEFAULT_WRAP = true;
|
||||||
|
private final Handler mHandler;
|
||||||
|
private final EditText mText;
|
||||||
|
private final InputFilter mNumberInputFilter;
|
||||||
|
|
||||||
|
private final Runnable mRunnable = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (mIncrement) {
|
||||||
|
changeCurrent(mCurrent + 1);
|
||||||
|
mHandler.postDelayed(this, mSpeed);
|
||||||
|
} else if (mDecrement) {
|
||||||
|
changeCurrent(mCurrent - 1);
|
||||||
|
mHandler.postDelayed(this, mSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private String[] mDisplayedValues;
|
||||||
|
protected int mStart;
|
||||||
|
protected int mEnd;
|
||||||
|
protected int mCurrent;
|
||||||
|
protected int mPrevious;
|
||||||
|
private OnChangedListener mListener;
|
||||||
|
private long mSpeed = 300;
|
||||||
|
private boolean mIncrement;
|
||||||
|
private boolean mDecrement;
|
||||||
|
private NumberPickerButton mIncrementButton;
|
||||||
|
private NumberPickerButton mDecrementButton;
|
||||||
|
private boolean mWrap;
|
||||||
|
private static final char[] DIGIT_CHARACTERS = new char[] {
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new NumberPicker
|
||||||
|
* @param context
|
||||||
|
*/
|
||||||
|
public NumberPicker(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new NumberPicker
|
||||||
|
* @param context
|
||||||
|
* @param attrs
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public NumberPicker(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new NumberPicker
|
||||||
|
* @param context
|
||||||
|
* @param attrs
|
||||||
|
* @param defStyle
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public NumberPicker(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs);
|
||||||
|
|
||||||
|
setOrientation(VERTICAL);
|
||||||
|
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
inflater.inflate(R.layout.number_picker, this, true);
|
||||||
|
mHandler = new Handler();
|
||||||
|
InputFilter inputFilter = new NumberPickerInputFilter();
|
||||||
|
mNumberInputFilter = new NumberRangeKeyListener();
|
||||||
|
mIncrementButton = (NumberPickerButton) findViewById(R.id.increment);
|
||||||
|
mIncrementButton.setOnClickListener(this);
|
||||||
|
mIncrementButton.setOnLongClickListener(this);
|
||||||
|
mIncrementButton.setNumberPicker(this);
|
||||||
|
mDecrementButton = (NumberPickerButton) findViewById(R.id.decrement);
|
||||||
|
mDecrementButton.setOnClickListener(this);
|
||||||
|
mDecrementButton.setOnLongClickListener(this);
|
||||||
|
mDecrementButton.setNumberPicker(this);
|
||||||
|
|
||||||
|
mText = (EditText) findViewById(R.id.timepicker_input);
|
||||||
|
mText.setOnFocusChangeListener(this);
|
||||||
|
mText.setFilters(new InputFilter[] {inputFilter});
|
||||||
|
mText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
|
||||||
|
|
||||||
|
if (!isEnabled()) {
|
||||||
|
setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.numberpicker );
|
||||||
|
mStart = a.getInt( R.styleable.numberpicker_startRange, DEFAULT_MIN );
|
||||||
|
mEnd = a.getInt( R.styleable.numberpicker_endRange, DEFAULT_MAX );
|
||||||
|
mWrap = a.getBoolean( R.styleable.numberpicker_wrap, DEFAULT_WRAP );
|
||||||
|
mCurrent = a.getInt( R.styleable.numberpicker_defaultValue, DEFAULT_VALUE );
|
||||||
|
mCurrent = Math.max( mStart, Math.min( mCurrent, mEnd ) );
|
||||||
|
mText.setText( "" + mCurrent );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelDecrement() {
|
||||||
|
mDecrement = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelIncrement() {
|
||||||
|
mIncrement = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void changeCurrent(int current) {
|
||||||
|
// Wrap around the values if we go past the start or end
|
||||||
|
if (current > mEnd) {
|
||||||
|
current = mWrap ? mStart : mEnd;
|
||||||
|
} else if (current < mStart) {
|
||||||
|
current = mWrap ? mEnd : mStart;
|
||||||
|
}
|
||||||
|
mPrevious = mCurrent;
|
||||||
|
mCurrent = current;
|
||||||
|
|
||||||
|
notifyChange();
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current value.
|
||||||
|
*/
|
||||||
|
public int getCurrent() {
|
||||||
|
return mCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSelectedPos(String str) {
|
||||||
|
if (mDisplayedValues == null) {
|
||||||
|
return Integer.parseInt(str);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < mDisplayedValues.length; i++) {
|
||||||
|
|
||||||
|
/* Don't force the user to type in jan when ja will do */
|
||||||
|
str = str.toLowerCase();
|
||||||
|
if (mDisplayedValues[i].toLowerCase().startsWith(str)) {
|
||||||
|
return mStart + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The user might have typed in a number into the month field i.e.
|
||||||
|
* 10 instead of OCT so support that too.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(str);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
|
||||||
|
/* Ignore as if it's not a number we don't care */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return this.mDisplayedValues[mCurrent];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyChange() {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onChanged(this, mPrevious, mCurrent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClick(View v) {
|
||||||
|
validateInput(mText);
|
||||||
|
if (!mText.hasFocus()) mText.requestFocus();
|
||||||
|
|
||||||
|
// now perform the increment/decrement
|
||||||
|
if (R.id.increment == v.getId()) {
|
||||||
|
changeCurrent(mCurrent + 1);
|
||||||
|
} else if (R.id.decrement == v.getId()) {
|
||||||
|
changeCurrent(mCurrent - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onFocusChange(View v, boolean hasFocus) {
|
||||||
|
|
||||||
|
/* When focus is lost check that the text field
|
||||||
|
* has valid values.
|
||||||
|
*/
|
||||||
|
if (!hasFocus) {
|
||||||
|
validateInput(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We start the long click here but rely on the {@link NumberPickerButton}
|
||||||
|
* to inform us when the long click has ended.
|
||||||
|
*/
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
|
||||||
|
/* The text view may still have focus so clear it's focus which will
|
||||||
|
* trigger the on focus changed and any typed values to be pulled.
|
||||||
|
*/
|
||||||
|
mText.clearFocus();
|
||||||
|
mText.requestFocus();
|
||||||
|
if (R.id.increment == v.getId()) {
|
||||||
|
mIncrement = true;
|
||||||
|
mHandler.post(mRunnable);
|
||||||
|
} else if (R.id.decrement == v.getId()) {
|
||||||
|
mDecrement = true;
|
||||||
|
mHandler.post(mRunnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current index
|
||||||
|
* @param index
|
||||||
|
*/
|
||||||
|
public void setCurrent(int index) {
|
||||||
|
mCurrent = index;
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current index and notifies listeners
|
||||||
|
* @param index
|
||||||
|
*/
|
||||||
|
public void setCurrentAndNotify(int index) {
|
||||||
|
mCurrent = index;
|
||||||
|
notifyChange();
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the values to display
|
||||||
|
* @param values
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public void setDisplayedValues(String[] values) {
|
||||||
|
this.mDisplayedValues = values;
|
||||||
|
this.mStart = 0;
|
||||||
|
this.mEnd = values.length -1;
|
||||||
|
notifyChange();
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
super.setEnabled(enabled);
|
||||||
|
mIncrementButton.setEnabled(enabled);
|
||||||
|
mDecrementButton.setEnabled(enabled);
|
||||||
|
mText.setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnChangeListener(OnChangedListener listener) {
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the range of numbers allowed for the number picker. The current
|
||||||
|
* value will be automatically set to the start.
|
||||||
|
*
|
||||||
|
* @param start the start of the range (inclusive)
|
||||||
|
* @param end the end of the range (inclusive)
|
||||||
|
*/
|
||||||
|
public void setRange(int start, int end) {
|
||||||
|
mStart = start;
|
||||||
|
mEnd = end;
|
||||||
|
mCurrent = start;
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the range of numbers allowed for the number picker. The current
|
||||||
|
* value will be automatically set to the start. Also provide a mapping
|
||||||
|
* for values used to display to the user.
|
||||||
|
*
|
||||||
|
* @param start the start of the range (inclusive)
|
||||||
|
* @param end the end of the range (inclusive)
|
||||||
|
* @param displayedValues the values displayed to the user.
|
||||||
|
*/
|
||||||
|
public void setRange(int start, int end, String[] displayedValues) {
|
||||||
|
mDisplayedValues = displayedValues;
|
||||||
|
mStart = start;
|
||||||
|
mEnd = end;
|
||||||
|
mCurrent = start;
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The speed (in milliseconds) at which the numbers will scroll
|
||||||
|
* when the the +/- buttons are longpressed. Default is 300ms.
|
||||||
|
*/
|
||||||
|
public void setSpeed(long speed) {
|
||||||
|
mSpeed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current displayed value by it's index
|
||||||
|
* @param index
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public void setValue(int index) {
|
||||||
|
mCurrent = index;
|
||||||
|
notifyChange();
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify if numbers should wrap after the edge has been reached.
|
||||||
|
*
|
||||||
|
* @param wrap values
|
||||||
|
*/
|
||||||
|
public void setWrap( boolean wrap ) {
|
||||||
|
mWrap = wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateView() {
|
||||||
|
|
||||||
|
/* If we don't have displayed values then use the
|
||||||
|
* current number else find the correct value in the
|
||||||
|
* displayed values for the current number.
|
||||||
|
*/
|
||||||
|
if (mDisplayedValues == null) {
|
||||||
|
mText.setText(mCurrent+"");
|
||||||
|
} else {
|
||||||
|
mText.setText(mDisplayedValues[mCurrent]);
|
||||||
|
}
|
||||||
|
mText.setSelection(mText.getText().length());
|
||||||
|
|
||||||
|
// mText.resizeText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateCurrentView(CharSequence str) {
|
||||||
|
int val = getSelectedPos(str.toString());
|
||||||
|
if ((val >= mStart) && (val <= mEnd)) {
|
||||||
|
if (mCurrent != val) {
|
||||||
|
mPrevious = mCurrent;
|
||||||
|
mCurrent = val;
|
||||||
|
notifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateInput(View v) {
|
||||||
|
String str = String.valueOf(((TextView) v).getText());
|
||||||
|
if ("".equals(str)) {
|
||||||
|
|
||||||
|
// Restore to the old value as we don't allow empty values
|
||||||
|
updateView();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Check the new value and ensure it's in range
|
||||||
|
validateCurrentView(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
84
ExaltedDice/src/com/TwentyCode/android/ExaltedDice/NumberPickerButton.java
Executable file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.TwentyCode.android.ExaltedDice;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class exists purely to cancel long click events.
|
||||||
|
*/
|
||||||
|
public class NumberPickerButton extends ImageButton {
|
||||||
|
|
||||||
|
private NumberPicker mNumberPicker;
|
||||||
|
|
||||||
|
public NumberPickerButton(Context context, AttributeSet attrs,
|
||||||
|
int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberPickerButton(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberPickerButton(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumberPicker(NumberPicker picker) {
|
||||||
|
mNumberPicker = picker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
cancelLongpressIfRequired(event);
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTrackballEvent(MotionEvent event) {
|
||||||
|
cancelLongpressIfRequired(event);
|
||||||
|
return super.onTrackballEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||||
|
if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER)
|
||||||
|
|| (keyCode == KeyEvent.KEYCODE_ENTER)) {
|
||||||
|
cancelLongpress();
|
||||||
|
}
|
||||||
|
return super.onKeyUp(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelLongpressIfRequired(MotionEvent event) {
|
||||||
|
if ((event.getAction() == MotionEvent.ACTION_CANCEL)
|
||||||
|
|| (event.getAction() == MotionEvent.ACTION_UP)) {
|
||||||
|
cancelLongpress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelLongpress() {
|
||||||
|
if (R.id.increment == getId()) {
|
||||||
|
mNumberPicker.cancelIncrement();
|
||||||
|
} else if (R.id.decrement == getId()) {
|
||||||
|
mNumberPicker.cancelDecrement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
project.properties
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# This file is automatically generated by Android Tools.
|
||||||
|
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||||
|
#
|
||||||
|
# This file must be checked in Version Control Systems.
|
||||||
|
#
|
||||||
|
# To customize properties used by the Ant build system use,
|
||||||
|
# "ant.properties", and override values to adapt the script to your
|
||||||
|
# project structure.
|
||||||
|
|
||||||
|
# Indicates whether an apk should be generated for each density.
|
||||||
|
split.density=false
|
||||||
|
# Project target.
|
||||||
|
target=android-15
|
||||||