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>
This commit is contained in:
2012-02-11 12:30:12 -05:00
parent 3ee566c488
commit 3102d485db
27 changed files with 958 additions and 125 deletions

View File

@@ -5,7 +5,7 @@
android:versionCode="15"
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.INTERNET" />

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View 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>

View File

@@ -4,19 +4,17 @@
android:layout_height="wrap_content"
android:orientation="horizontal" >
<NumberPicker
<com.TwentyCode.android.ExaltedDice.NumberPicker
android:id="@+id/number_Picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dip" />
android:layout_height="wrap_content" />
<NumberPicker
<com.TwentyCode.android.ExaltedDice.NumberPicker
android:id="@+id/d_Picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dip" />
android:layout_height="wrap_content" />
<NumberPicker
<com.TwentyCode.android.ExaltedDice.NumberPicker
android:id="@+id/mod_Picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

View File

@@ -16,7 +16,7 @@
<RelativeLayout
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="2" >
android:layout_weight="2.5" >
<include
android:id="@+id/die_selector"

View 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>

View File

@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="com.admob.android.ads.AdView">
<attr name="backgroundColor" format="color" />
<attr name="primaryTextColor" format="color" />
<attr name="secondaryTextColor" format="color" />
<attr name="keywords" format="string" />
<attr name="refreshInterval" format="integer" />
</declare-styleable>
</resources>
<resources>
<declare-styleable name="com.admob.android.ads.AdView">
<attr name="backgroundColor" format="color" />
<attr name="primaryTextColor" format="color" />
<attr name="secondaryTextColor" format="color" />
<attr name="keywords" format="string" />
<attr name="refreshInterval" format="integer" />
</declare-styleable>
<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>

View File

@@ -44,16 +44,20 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
private ListView mListView;
private NumberPicker mNumberPicker;
private NumberPicker mDPicker;
private NumberPicker mModPicker;
private Database mDb;
private String mGameName;
private long mGameId;
private RollHistoryDatabaseAdapter mListAdapter;
private SharedPreferences mSettings;
private String[] mModValues;
private NumberPicker mModPicker;
private ProgressBar mRollProgress;
private View mRollButton;
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
@@ -63,14 +67,66 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
private void applyRollPresets(long id) {
ContentValues roll = mDb.getGameHistoryInfo(mGameName, (int) (id));
try{
mNumberPicker.setValue(roll.getAsInteger(Database.KEY_NUMBER));
mDPicker.setValue(parseD(roll.getAsString(Database.KEY_D_TYPE)));
mModPicker.setValue(parseMod(roll.getAsString(Database.KEY_MOD).replace("'", "")));
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));
mDPicker.setValue(parseD(roll.getAsString(Database.KEY_D_TYPE)));
mModPicker.setValue(parseMod(roll.getAsString(Database.KEY_MOD).replace("'", "")));
}
} catch(NullPointerException e){
mModPicker.setValue(parseMod("+0"));
if(isCompat)
mCompatModPicker.setValue(parseMod("+0"));
else
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
*
@@ -113,13 +169,21 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
Log.i(TAG, "onCreate()");
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
* else use compat methods
*/
if(Integer.valueOf(android.os.Build.VERSION.SDK) > 11){
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
initPickers();
} else
initCompatPickers();
Intent i = this.getIntent();
if(i != null)
@@ -129,32 +193,10 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
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.setOnItemClickListener(this);
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);
mRollButton = findViewById(R.id.roll_button);
@@ -183,6 +225,40 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
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
* @author ricky barrette
@@ -220,29 +296,31 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
return super.onOptionsItemSelected(item);
}
}
/**
* (non-Javadoc)
* @see android.app.Activity#onPause()
*/
@Override
protected void onStop() {
mDb.close();
super.onStop();
@Override
public void onRestoreComplete() {
// do nothing
}
/**
* resorts application state after rotation
* @author ricky barrette
*/
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mDPicker.setValue(savedInstanceState.getInt("d"));
mNumberPicker.setValue(savedInstanceState.getInt("number"));
mModPicker.setValue(savedInstanceState.getInt("mod"));
}
* resorts application state after rotation
* @author ricky barrette
*/
@Override
public void onRestoreInstanceState(Bundle 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"));
mNumberPicker.setValue(savedInstanceState.getInt("number"));
mModPicker.setValue(savedInstanceState.getInt("mod"));
}
}
/**
/**
* (non-Javadoc)
* @see android.app.Activity#onResume()
*/
@@ -252,15 +330,41 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
applyRollPresets(mDb.getGameRollCount(mGameId));
if(mSettings.getBoolean(Settings.KEY_ROLL_MOD, true)){
mModPicker.setVisibility(View.VISIBLE);
if(isCompat)
mCompatModPicker.setVisibility(View.VISIBLE);
else
mModPicker.setVisibility(View.VISIBLE);
} else {
mModPicker.setVisibility(View.GONE);
mModPicker.setValue(parseMod("+0"));
if(isCompat){
mCompatModPicker.setVisibility(View.GONE);
mCompatModPicker.setValue(parseMod("+0"));
} else {
mModPicker.setVisibility(View.GONE);
mModPicker.setValue(parseMod("+0"));
}
}
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)
* @see android.app.Activity#onStart()
*/
@@ -273,15 +377,13 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
}
/**
* saves application state before rotation
* @author ricky barrette
* (non-Javadoc)
* @see android.app.Activity#onPause()
*/
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("d", mDPicker.getValue());
savedInstanceState.putInt("number", mNumberPicker.getValue());
savedInstanceState.putInt("mod", mModPicker.getValue());
super.onSaveInstanceState(savedInstanceState);
protected void onStop() {
mDb.close();
super.onStop();
}
/**
@@ -296,8 +398,8 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
return i;
return 0;
}
/**
/**
* Parses the string mod to the appropriate value
* @param mod
* @return value for d picker
@@ -332,7 +434,7 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
});
builder.show();
}
/**
* Refreshes the list view
* @author ricky barrette
@@ -366,7 +468,10 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
resultsString.append(getString(R.string.total)+ total);
if(mSettings.getBoolean(Settings.KEY_ROLL_MOD, true))
resultsString.append(getString(R.string.total_plus_mod)+ (total + Integer.parseInt(mModValues[mModPicker.getValue()].replace("+", ""))));
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("+", ""))));
if(mSettings.getBoolean(Settings.KEY_CALC_SUCCESSES, true))
resultsString.append(getString(R.string.sucesses)+ successes(roll));
@@ -399,11 +504,20 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
int rollId = mDb.getGameRollCount(mGameId) +1;
ContentValues roll = new ContentValues();
roll.put(Database.KEY_D_TYPE, mDiceValues[mDPicker.getValue()]);
roll.put(Database.KEY_NUMBER, mNumberPicker.getValue());
roll.putAll(results(mNumberPicker.getValue()));
roll.put(Database.KEY_MOD, DatabaseUtils.sqlEscapeString(mModValues[mModPicker.getValue()]));
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_NUMBER, mNumberPicker.getValue());
roll.putAll(results(mNumberPicker.getValue()));
roll.put(Database.KEY_MOD, DatabaseUtils.sqlEscapeString(mModValues[mModPicker.getValue()]));
}
mDb.updateGame(mGameId, mGameName, roll, rollId);
}
@@ -422,7 +536,10 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
int[] roll = new int[times];
Random random = new Random();
for (int i = 0; i < times; i++) {
roll[i] = random.nextInt(Integer.parseInt(mDiceValues[mDPicker.getValue()].substring(1))) + 1;
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;
}
return roll;
}
@@ -470,43 +587,4 @@ public class ExaltedDice extends Activity implements OnClickListener, OnItemClic
Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
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();
}
});
}
}

View 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);
}
}
}

View 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
View 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