Browse Source

Update FRC Scout for 2017 "Steamworks"

 - This adds a platform for adding new games easily
 - Users can still switch back to the old 2016 game "Stronghold"
Thomas Ross 3 years ago
parent
commit
312cad44b7

+ 7
- 1
app/build.gradle View File

@@ -10,6 +10,8 @@ android {
10 10
         targetSdkVersion 23
11 11
         versionCode 5
12 12
         versionName "1.1.3"
13
+
14
+        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
13 15
     }
14 16
     buildTypes {
15 17
         release {
@@ -27,7 +29,11 @@ android {
27 29
 dependencies {
28 30
     compile fileTree(dir: 'libs', include: ['*.jar'])
29 31
     testCompile 'junit:junit:4.12'
30
-    compile 'com.android.support:appcompat-v7:+'
32
+
33
+    compile 'com.android.support:appcompat-v7:23.2.0'
31 34
     compile 'com.google.code.gson:gson:2.4'
32 35
     compile 'com.android.support:design:23.2.0'
36
+
37
+    androidTestCompile 'com.android.support:support-annotations:23.2.0'
38
+    androidTestCompile 'com.android.support.test:runner:0.5'
33 39
 }

+ 1
- 13
app/src/main/java/io/thomasross/frcscout/EditTeam.java View File

@@ -159,19 +159,7 @@ public class EditTeam extends AppCompatActivity implements LoaderManager.LoaderC
159 159
             Gson gson = new GsonBuilder().create();
160 160
             HashMap<String, Boolean> tasksMap = gson.fromJson(tasksJSON, jsonType);
161 161
 
162
-            HashMap<String, String> taskDetails = new HashMap<>();
163
-            taskDetails.put("portcullis", "Portcullis");
164
-            taskDetails.put("cheval", "Cheval de Frise");
165
-            taskDetails.put("moat", "Moat");
166
-            taskDetails.put("ramparts", "Ramparts");
167
-            taskDetails.put("drawbridge", "Drawbridge");
168
-            taskDetails.put("sallyport", "Sally Port");
169
-            taskDetails.put("rockwall", "Rock Wall");
170
-            taskDetails.put("roughterrain", "Rough Terrain");
171
-            taskDetails.put("lowbar", "Low Bar");
172
-            taskDetails.put("lowgoal", "Low Goal");
173
-            taskDetails.put("highgoal", "High Goal");
174
-            taskDetails.put("scaletower", "Scale Tower");
162
+            HashMap<String, String> taskDetails = GamesManager.getTasks();
175 163
 
176 164
             ArrayList<Task> teamAbleTasks = new ArrayList<>();
177 165
             for (String key : taskDetails.keySet())

+ 7
- 0
app/src/main/java/io/thomasross/frcscout/Game.java View File

@@ -0,0 +1,7 @@
1
+package io.thomasross.frcscout;
2
+
3
+public enum Game
4
+{
5
+    STRONGHOLD_2016,
6
+    STEAMWORKS_2017
7
+}

+ 60
- 0
app/src/main/java/io/thomasross/frcscout/GamesManager.java View File

@@ -0,0 +1,60 @@
1
+package io.thomasross.frcscout;
2
+
3
+import java.util.HashMap;
4
+
5
+public class GamesManager
6
+{
7
+    public static final String GAME_2016_TABLE_NAME = "Teams2016";
8
+    public static final String GAME_2017_TABLE_NAME = "Teams2017";
9
+
10
+    private static Game selectedGame = Game.STEAMWORKS_2017;
11
+
12
+    public static void setSelectedGame(Game game)
13
+    {
14
+        GamesManager.selectedGame = game;
15
+    }
16
+
17
+    public static String getCurrentTableName()
18
+    {
19
+        switch (GamesManager.selectedGame)
20
+        {
21
+            case STRONGHOLD_2016:
22
+                return GAME_2016_TABLE_NAME;
23
+            case STEAMWORKS_2017:
24
+            default:
25
+                return GAME_2017_TABLE_NAME;
26
+        }
27
+    }
28
+
29
+    public static HashMap<String, String> getTasks()
30
+    {
31
+        HashMap<String, String> tasks = new HashMap<>();
32
+        switch (GamesManager.selectedGame)
33
+        {
34
+            case STRONGHOLD_2016:
35
+                tasks.put("portcullis", "Portcullis");
36
+                tasks.put("cheval", "Cheval de Frise");
37
+                tasks.put("moat", "Moat");
38
+                tasks.put("ramparts", "Ramparts");
39
+                tasks.put("drawbridge", "Drawbridge");
40
+                tasks.put("sallyport", "Sally Port");
41
+                tasks.put("rockwall", "Rock Wall");
42
+                tasks.put("roughterrain", "Rough Terrain");
43
+                tasks.put("lowbar", "Low Bar");
44
+                tasks.put("lowgoal", "Low Goal");
45
+                tasks.put("highgoal", "High Goal");
46
+                tasks.put("scaletower", "Scale Tower");
47
+                break;
48
+            case STEAMWORKS_2017:
49
+            default:
50
+                tasks.put("highgoal", "High Goal");
51
+                tasks.put("lowgoal", "Low Goal");
52
+                tasks.put("gears", "Gears");
53
+                tasks.put("pickup-hopper", "Hopper Fuel Pick up");
54
+                tasks.put("pickup-ground", "Ground Fuel Pick up");
55
+                tasks.put("hang", "Hang");
56
+                // Doesn't get moved easily?
57
+        }
58
+        return tasks;
59
+    }
60
+}

+ 57
- 13
app/src/main/java/io/thomasross/frcscout/Main.java View File

@@ -8,6 +8,8 @@ import android.database.Cursor;
8 8
 import android.os.Bundle;
9 9
 import android.support.design.widget.FloatingActionButton;
10 10
 import android.support.v7.app.AppCompatActivity;
11
+import android.view.Menu;
12
+import android.view.MenuItem;
11 13
 import android.view.View;
12 14
 import android.widget.*;
13 15
 import com.google.gson.Gson;
@@ -20,6 +22,7 @@ import io.thomasross.frcscout.models.Team;
20 22
 import java.lang.reflect.Type;
21 23
 import java.util.ArrayList;
22 24
 import java.util.HashMap;
25
+import java.util.Set;
23 26
 
24 27
 public class Main extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>
25 28
 {
@@ -44,10 +47,63 @@ public class Main extends AppCompatActivity implements LoaderManager.LoaderCallb
44 47
     }
45 48
 
46 49
     @Override
50
+    public boolean onCreateOptionsMenu(Menu menu)
51
+    {
52
+        final Main us = this;
53
+        getMenuInflater().inflate(R.menu.menu_main, menu);
54
+
55
+        final MenuItem doneBtn = menu.findItem(R.id.action_selectgame_M);
56
+        doneBtn.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener()
57
+        {
58
+            @Override
59
+            public boolean onMenuItemClick(MenuItem item)
60
+            {
61
+                PopupMenu popupMenu = new PopupMenu(us, us.findViewById(R.id.action_selectgame_M));
62
+                popupMenu.getMenuInflater().inflate(R.menu.menu_selectgame, popupMenu.getMenu());
63
+
64
+                // TODO: There has to be a better way to do this
65
+                MenuItem stronghold2016 = popupMenu.getMenu().findItem(R.id.menu_stronghold_2016);
66
+                stronghold2016.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener()
67
+                {
68
+                    @Override
69
+                    public boolean onMenuItemClick(MenuItem item)
70
+                    {
71
+                        GamesManager.setSelectedGame(Game.STRONGHOLD_2016);
72
+                        us.refreshTeams();
73
+                        return false;
74
+                    }
75
+                });
76
+
77
+                MenuItem steamworks2017 = popupMenu.getMenu().findItem(R.id.menu_steamworks_2017);
78
+                steamworks2017.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener()
79
+                {
80
+                    @Override
81
+                    public boolean onMenuItemClick(MenuItem item)
82
+                    {
83
+                        GamesManager.setSelectedGame(Game.STEAMWORKS_2017);
84
+                        us.refreshTeams();
85
+                        return false;
86
+                    }
87
+                });
88
+
89
+                popupMenu.show();
90
+                return false;
91
+            }
92
+        });
93
+
94
+        return super.onCreateOptionsMenu(menu);
95
+    }
96
+
97
+    @Override
47 98
     protected void onStart()
48 99
     {
49 100
         super.onStart();
50 101
 
102
+        refreshTeams();
103
+    }
104
+
105
+    private void refreshTeams()
106
+    {
51 107
         getLoaderManager().initLoader(0, null, this).forceLoad();
52 108
     }
53 109
 
@@ -72,19 +128,7 @@ public class Main extends AppCompatActivity implements LoaderManager.LoaderCallb
72 128
             Gson gson = new GsonBuilder().create();
73 129
             HashMap<String, Boolean> tasksMap = gson.fromJson(tasksJSON, jsonType);
74 130
 
75
-            ArrayList<String> tasks = new ArrayList<>();
76
-            tasks.add("portcullis");
77
-            tasks.add("cheval");
78
-            tasks.add("moat");
79
-            tasks.add("ramparts");
80
-            tasks.add("drawbridge");
81
-            tasks.add("sallyport");
82
-            tasks.add("rockwall");
83
-            tasks.add("roughterrain");
84
-            tasks.add("lowbar");
85
-            tasks.add("lowgoal");
86
-            tasks.add("highgoal");
87
-            tasks.add("scaletower");
131
+            Set<String> tasks = GamesManager.getTasks().keySet();
88 132
 
89 133
             int numTasksAble = 0;
90 134
             for (String key : tasks)

+ 26
- 5
app/src/main/java/io/thomasross/frcscout/TeamsOpenHelper.java View File

@@ -6,9 +6,8 @@ import android.database.sqlite.SQLiteOpenHelper;
6 6
 
7 7
 public class TeamsOpenHelper extends SQLiteOpenHelper
8 8
 {
9
-    private static final int DATABASE_VERSION = 4;
9
+    private static final int DATABASE_VERSION = 5;
10 10
     private static final String DATABASE_NAME = "Teams";
11
-    private static final String DATABASE_TABLE_NAME = "Teams";
12 11
 
13 12
     public TeamsOpenHelper(Context context)
14 13
     {
@@ -18,7 +17,14 @@ public class TeamsOpenHelper extends SQLiteOpenHelper
18 17
     @Override
19 18
     public void onCreate(SQLiteDatabase db)
20 19
     {
21
-        db.execSQL("CREATE TABLE " + DATABASE_TABLE_NAME + " (" +
20
+        db.execSQL("CREATE TABLE " + GamesManager.GAME_2016_TABLE_NAME + " (" +
21
+                "TEAMNUMBER INT NOT NULL, " +
22
+                "TEAMNAME TEXT, " +
23
+                "TASKS TEXT, " +
24
+                "AUTOPTS INT" +
25
+                ");");
26
+
27
+        db.execSQL("CREATE TABLE " + GamesManager.GAME_2017_TABLE_NAME + " (" +
22 28
                 "TEAMNUMBER INT NOT NULL, " +
23 29
                 "TEAMNAME TEXT, " +
24 30
                 "TASKS TEXT, " +
@@ -29,7 +35,22 @@ public class TeamsOpenHelper extends SQLiteOpenHelper
29 35
     @Override
30 36
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
31 37
     {
32
-        db.execSQL("ALTER TABLE " + DATABASE_TABLE_NAME + " " +
33
-                "ADD COLUMN AUTOPTS INT;");
38
+        if (oldVersion < 4)
39
+        {
40
+            db.execSQL("ALTER TABLE Teams " +
41
+                    "ADD COLUMN AUTOPTS INT;");
42
+        }
43
+
44
+        if (oldVersion == 4 && newVersion == 5)
45
+        {
46
+            db.execSQL("ALTER TABLE Teams RENAME TO " + GamesManager.GAME_2016_TABLE_NAME);
47
+
48
+            db.execSQL("CREATE TABLE " + GamesManager.GAME_2017_TABLE_NAME + " (" +
49
+                    "TEAMNUMBER INT NOT NULL, " +
50
+                    "TEAMNAME TEXT, " +
51
+                    "TASKS TEXT, " +
52
+                    "AUTOPTS INT" +
53
+                    ");");
54
+        }
34 55
     }
35 56
 }

+ 13
- 14
app/src/main/java/io/thomasross/frcscout/loaders/TeamLoader.java View File

@@ -4,21 +4,22 @@ import android.content.AsyncTaskLoader;
4 4
 import android.content.Context;
5 5
 import android.database.Cursor;
6 6
 import android.database.sqlite.SQLiteDatabase;
7
+import io.thomasross.frcscout.GamesManager;
7 8
 import io.thomasross.frcscout.TeamsOpenHelper;
8 9
 
9 10
 public class TeamLoader extends AsyncTaskLoader<Cursor>
10 11
 {
11
-    TeamsOpenHelper teamsDatabase;
12
+    private TeamsOpenHelper teamsDatabase;
12 13
 
13
-    String[] columns;
14
-    String where;
15
-    String[] whereArgs;
14
+    private String[] columns;
15
+    private String where;
16
+    private String[] whereArgs;
16 17
 
17 18
     public TeamLoader(Context context, String[] columns, String where, String[] whereArgs)
18 19
     {
19 20
         super(context);
20 21
 
21
-        teamsDatabase = new TeamsOpenHelper(context);
22
+        this.teamsDatabase = new TeamsOpenHelper(context);
22 23
 
23 24
         this.columns = columns;
24 25
         this.where = where;
@@ -30,14 +31,12 @@ public class TeamLoader extends AsyncTaskLoader<Cursor>
30 31
     {
31 32
         SQLiteDatabase readableDB = teamsDatabase.getReadableDatabase();
32 33
 
33
-        Cursor results = readableDB.query("Teams",
34
-                columns,
35
-                where,
36
-                whereArgs,
37
-                null,
38
-                null,
39
-                null);
40
-
41
-        return results;
34
+        return readableDB.query(GamesManager.getCurrentTableName(),
35
+                                columns,
36
+                                where,
37
+                                whereArgs,
38
+                                null,
39
+                                null,
40
+                                null);
42 41
     }
43 42
 }

+ 4
- 3
app/src/main/java/io/thomasross/frcscout/tasks/DeleteTeamTask.java View File

@@ -4,14 +4,15 @@ import android.content.Context;
4 4
 import android.database.sqlite.SQLiteDatabase;
5 5
 import android.os.AsyncTask;
6 6
 import io.thomasross.frcscout.FinishedCallback;
7
+import io.thomasross.frcscout.GamesManager;
7 8
 import io.thomasross.frcscout.TeamsOpenHelper;
8 9
 
9 10
 import java.util.ArrayList;
10 11
 
11 12
 public class DeleteTeamTask extends AsyncTask<Integer, Void, Void>
12 13
 {
13
-    Context context;
14
-    ArrayList<FinishedCallback> finishedCallbacks = new ArrayList<>();
14
+    private Context context;
15
+    private ArrayList<FinishedCallback> finishedCallbacks = new ArrayList<>();
15 16
 
16 17
     public DeleteTeamTask(Context context)
17 18
     {
@@ -45,7 +46,7 @@ public class DeleteTeamTask extends AsyncTask<Integer, Void, Void>
45 46
         {
46 47
             String where = "TEAMNUMBER = ?";
47 48
             String[] whereArgs = {"" + teamNumber};
48
-            writeableDB.delete("Teams", where, whereArgs);
49
+            writeableDB.delete(GamesManager.getCurrentTableName(), where, whereArgs);
49 50
         }
50 51
 
51 52
         writeableDB.close();

+ 4
- 3
app/src/main/java/io/thomasross/frcscout/tasks/InsertTeamTask.java View File

@@ -5,6 +5,7 @@ import android.content.Context;
5 5
 import android.database.sqlite.SQLiteDatabase;
6 6
 import android.os.AsyncTask;
7 7
 import io.thomasross.frcscout.FinishedCallback;
8
+import io.thomasross.frcscout.GamesManager;
8 9
 import io.thomasross.frcscout.models.Team;
9 10
 import io.thomasross.frcscout.TeamsOpenHelper;
10 11
 
@@ -12,8 +13,8 @@ import java.util.ArrayList;
12 13
 
13 14
 public class InsertTeamTask extends AsyncTask<Team, Void, Void>
14 15
 {
15
-    Context context;
16
-    ArrayList<FinishedCallback> finishedCallbacks = new ArrayList<>();
16
+    private Context context;
17
+    private ArrayList<FinishedCallback> finishedCallbacks = new ArrayList<>();
17 18
 
18 19
     public InsertTeamTask(Context context)
19 20
     {
@@ -50,7 +51,7 @@ public class InsertTeamTask extends AsyncTask<Team, Void, Void>
50 51
             values.put("TEAMNAME", team.name);
51 52
             values.put("TASKS", team.tasks);
52 53
             values.put("AUTOPTS", team.autoPoints);
53
-            writeableDB.insert("Teams", null, values);
54
+            writeableDB.insert(GamesManager.getCurrentTableName(), null, values);
54 55
         }
55 56
 
56 57
         writeableDB.close();

+ 4
- 3
app/src/main/java/io/thomasross/frcscout/tasks/UpdateTeamTask.java View File

@@ -5,6 +5,7 @@ import android.content.Context;
5 5
 import android.database.sqlite.SQLiteDatabase;
6 6
 import android.os.AsyncTask;
7 7
 import io.thomasross.frcscout.FinishedCallback;
8
+import io.thomasross.frcscout.GamesManager;
8 9
 import io.thomasross.frcscout.models.Team;
9 10
 import io.thomasross.frcscout.TeamsOpenHelper;
10 11
 
@@ -12,8 +13,8 @@ import java.util.ArrayList;
12 13
 
13 14
 public class UpdateTeamTask extends AsyncTask<Team, Void, Void>
14 15
 {
15
-    Context context;
16
-    ArrayList<FinishedCallback> finishedCallbacks = new ArrayList<>();
16
+    private Context context;
17
+    private ArrayList<FinishedCallback> finishedCallbacks = new ArrayList<>();
17 18
 
18 19
     public UpdateTeamTask(Context context)
19 20
     {
@@ -50,7 +51,7 @@ public class UpdateTeamTask extends AsyncTask<Team, Void, Void>
50 51
             values.put("TASKS", team.tasks);
51 52
             values.put("AUTOPTS", team.autoPoints);
52 53
             String[] whereArgs = {"" + team.number};
53
-            writeableDB.update("Teams", values, "TEAMNUMBER = ?", whereArgs);
54
+            writeableDB.update(GamesManager.getCurrentTableName(), values, "TEAMNUMBER = ?", whereArgs);
54 55
         }
55 56
 
56 57
         writeableDB.close();

+ 9
- 0
app/src/main/res/drawable/ic_more_vert_white.xml View File

@@ -0,0 +1,9 @@
1
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+        android:width="24dp"
3
+        android:height="24dp"
4
+        android:viewportWidth="24.0"
5
+        android:viewportHeight="24.0">
6
+    <path
7
+        android:fillColor="#FFFFFF"
8
+        android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
9
+</vector>

+ 9
- 0
app/src/main/res/menu/menu_main.xml View File

@@ -0,0 +1,9 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
3
+      xmlns:app="http://schemas.android.com/apk/res-auto">
4
+
5
+    <item android:id="@+id/action_selectgame_M"
6
+          android:icon="@drawable/ic_more_vert_white"
7
+          android:title="@string/selectgame_btn"
8
+          app:showAsAction="ifRoom"/>
9
+</menu>

+ 10
- 0
app/src/main/res/menu/menu_selectgame.xml View File

@@ -0,0 +1,10 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
3
+    <item
4
+            android:id="@+id/menu_stronghold_2016"
5
+            android:title="@string/stronghold_2016_btn"/>
6
+
7
+    <item
8
+            android:id="@+id/menu_steamworks_2017"
9
+            android:title="@string/steamworks_2017_btn"/>
10
+</menu>

+ 17
- 2
app/src/main/res/values/strings.xml View File

@@ -1,11 +1,26 @@
1 1
 <?xml version="1.0" encoding="utf-8"?>
2 2
 <resources>
3 3
     <string name="app_name">FRC Scout</string>
4
-    <string name="teamnumber_lbl">Team Number</string>
5
-    <string name="teamname_lbl">Team Name</string>
4
+
5
+    <!-- Shared Activities -->
6 6
     <string name="done_btn">Done</string>
7 7
     <string name="delete_btn">Delete</string>
8
+
9
+    <!-- Activity: Main -->
10
+    <string name="teamnumber_lbl">Team Number</string>
11
+    <string name="teamname_lbl">Team Name</string>
12
+    <string name="selectgame_btn">Select Game</string>
13
+
14
+    <!-- Activity: EditTeam -->
8 15
     <string name="autonomouspoints_lbl">Autonomous Points</string>
16
+
17
+    <!-- Layout: teamlistitem -->
9 18
     <string name="more">More</string>
19
+
20
+    <!-- Menu: teampopup -->
10 21
     <string name="tbalink">The Blue Alliance</string>
22
+
23
+    <!-- Menu: selectgame -->
24
+    <string name="stronghold_2016_btn">Stronghold 2016</string>
25
+    <string name="steamworks_2017_btn">Steamworks 2017</string>
11 26
 </resources>

+ 1
- 1
build.gradle View File

@@ -5,7 +5,7 @@ buildscript {
5 5
         jcenter()
6 6
     }
7 7
     dependencies {
8
-        classpath 'com.android.tools.build:gradle:2.0.0'
8
+        classpath 'com.android.tools.build:gradle:2.2.3'
9 9
 
10 10
         // NOTE: Do not place your application dependencies here; they belong
11 11
         // in the individual module build.gradle files

+ 2
- 2
gradle/wrapper/gradle-wrapper.properties View File

@@ -1,6 +1,6 @@
1
-#Mon Dec 28 10:00:20 PST 2015
1
+#Sun Jan 29 18:08:03 EST 2017
2 2
 distributionBase=GRADLE_USER_HOME
3 3
 distributionPath=wrapper/dists
4 4
 zipStoreBase=GRADLE_USER_HOME
5 5
 zipStorePath=wrapper/dists
6
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
6
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip