Merge pull request #1 from adrienmalin/V2

V2 Text to speech and voice recognition
This commit is contained in:
adrienmalin 2018-12-10 00:18:10 +01:00 committed by GitHub
commit 464cda09b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 1675 additions and 872 deletions

8
.gitignore vendored
View File

@ -1,7 +1,7 @@
*.iml
.gradle
app/release
/local.properties
/.idea/caches/build_file_checksums.ser
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
@ -9,3 +9,9 @@ app/release
/build
/captures
.externalNativeBuild
*.ser
*.ser
*.apk
*.apk
*.ser
*.ser

View File

@ -13,46 +13,6 @@
<PersistentState>
<option name="children">
<map>
<entry key="actionbar">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_info_outline_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="textAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="text" value="" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="assetType" value="TEXT" />
<entry key="imageAsset" value="C:\Users\adima\Downloads\ping-pong (2).png" />
<entry key="outputName" value="not_server" />
<entry key="theme" value="HOLO_DARK" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="launcher">
<value>
<PersistentState>
@ -64,7 +24,6 @@
<option name="values">
<map>
<entry key="scalingPercent" value="90" />
<entry key="trimmed" value="true" />
</map>
</option>
</PersistentState>
@ -75,21 +34,7 @@
<option name="values">
<map>
<entry key="backgroundAssetType" value="COLOR" />
<entry key="backgroundColor" value="3c3a41" />
<entry key="foregroundImage" value="C:\Users\adima\AndroidStudioProjects\PingPoints\app\src\main\res\drawable\ic_ping_pong_table.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="launcherLegacy">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="assetType" value="IMAGE" />
<entry key="iconShape" value="NONE" />
<entry key="imageAsset" value="C:\Users\adima\Downloads\ping-pong (1).png" />
<entry key="foregroundImage" value="C:\Users\adrien.malingrey\Documents\GitHub\PingPoints.V1\app\src\main\res\drawable\ic_launcher_foreground.xml" />
</map>
</option>
</PersistentState>
@ -120,7 +65,7 @@
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/content/ic_redo_black_24dp.xml" />
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/hardware/ic_keyboard_voice_black_24dp.xml" />
</map>
</option>
</PersistentState>
@ -130,10 +75,9 @@
</option>
<option name="values">
<map>
<entry key="autoMirrored" value="true" />
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_redo" />
<entry key="sourceFile" value="C:\Users\adima\Downloads\ping-pong (3).svg" />
<entry key="outputName" value="ic_stt" />
<entry key="sourceFile" value="C:\Users\adima" />
</map>
</option>
</PersistentState>

Binary file not shown.

View File

@ -1,5 +1,8 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
@ -25,5 +28,8 @@
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

6
.idea/kotlinc.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Kotlin2JsCompilerArguments">
<option name="sourceMapEmbedSources" />
</component>
</project>

8
.idea/misc.xml generated
View File

@ -5,22 +5,26 @@
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="5">
<list size="7">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<list size="6">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
</list>
</value>
</option>

2
.idea/vcs.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -10,9 +10,8 @@ android {
applicationId "adrienmalin.pingpoints"
minSdkVersion 15
targetSdkVersion 28
versionCode 2
versionName "1.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
versionCode 4
versionName "2.0"
vectorDrawables.useSupportLibrary true
}
buildTypes {
@ -24,13 +23,13 @@ android {
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:support-v4:28.0.0-rc01'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:design:28.0.0-rc01'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'android.arch.lifecycle:extensions:1.1.1'
annotationProcessor 'android.arch.lifecycle:compiler:1.1.1'
implementation 'com.android.support:design:28.0.0'
}

BIN
app/release/app-release.apk Normal file

Binary file not shown.

View File

@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":2,"versionName":"1.1","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":4,"versionName":"2.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

View File

@ -1,24 +0,0 @@
package adrienmalin.pingpoints
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
assertEquals("adrienmalin.pingpoints", appContext.packageName)
}
}

View File

@ -1,30 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="adrienmalin.pingpoints">
package="adrienmalin.pingpoints">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar">
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:logo="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/PingPointsTheme">
<activity
android:name=".MainActivity"
android:screenOrientation="sensorLandscape"
android:theme="@style/Theme.AppCompat.NoActionBar">
android:name=".StarterNameActivity"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".CreditsActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
android:name=".MatchActivity">
</activity>
<activity android:name=".VictoryActivity">
</activity>
</application>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,23 +0,0 @@
package adrienmalin.pingpoints
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.text.method.LinkMovementMethod
import android.view.MenuItem
import android.widget.TextView
class CreditsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_credits)
setSupportActionBar(findViewById(R.id.toolbar))
supportActionBar?.setDisplayHomeAsUpEnabled(true)
findViewById<TextView>(R.id.iconsCredit)?.movementMethod = LinkMovementMethod.getInstance()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
finish()
return true
}
}

View File

@ -1,59 +0,0 @@
package adrienmalin.pingpoints
import android.app.AlertDialog
import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
import android.support.v4.app.DialogFragment
class EndOfMatchDialog: DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?)=
AlertDialog.Builder(activity).apply{
val players = (activity as MainActivity).players
val names = players.map { it.name }
val winnerName = players.maxBy { it.score }?.name ?: ""
val score = players.map { it.score }.sortedDescending()
setTitle(getString(R.string.end_match_dialog_title, winnerName))
setMessage(getString(R.string.score, score[0], score[1]))
setPositiveButton(
R.string.new_match,
DialogInterface.OnClickListener { dialog, id ->
startActivity(
Intent(context, MainActivity::class.java).apply {
putExtra("names", names.toTypedArray())
}
)
}
)
setNeutralButton(
R.string.share_button,
DialogInterface.OnClickListener { dialog, id ->
val newMatchIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_SUBJECT,
getString(
R.string.share_subject,
names[Side.LEFT.value],
names[Side.RIGHT.value]
)
)
putExtra(
Intent.EXTRA_TEXT,
getString(R.string.share_message,
names[Side.LEFT.value],
names[Side.RIGHT.value],
winnerName,
score[0],
score[1]
)
)
type = "text/plain"
}
startActivity(newMatchIntent)
}
)
}.create()
}

View File

@ -0,0 +1,12 @@
package adrienmalin.pingpoints
import android.os.Build
import android.text.Html
import android.text.Spanned
@Suppress("DEPRECATION")
fun fromHtml(source: String): Spanned = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> Html.fromHtml(source, Html.FROM_HTML_MODE_COMPACT)
else -> Html.fromHtml(source)
}

View File

@ -1,181 +0,0 @@
package adrienmalin.pingpoints
import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Build
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.app.AppCompatDelegate
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
class MainActivity : AppCompatActivity() {
var players: Array<Player> = emptyArray()
var serviceSide: Side = Side.LEFT
var relaunchSide: Side = Side.RIGHT
var textScore: android.widget.TextView? = null
var textService: android.widget.TextView? = null
var buttons: Array<Button> = emptyArray()
var imageViews: Array<ImageView?> = emptyArray()
var history: MutableList<State> = ArrayList()
var step: Int = 0
var undo: MenuItem? = null
var redo: MenuItem? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
}
var names: Array<String> = intent.getStringArrayExtra("names") ?: resources.getStringArray(R.array.default_players_names)
players = arrayOf(
Player(names[Side.LEFT.value]),
Player(names[Side.RIGHT.value])
)
textScore = findViewById(R.id.textScore)
textService = findViewById(R.id.textService)
buttons = arrayOf(
findViewById(R.id.buttonLeftPlayer),
findViewById(R.id.buttonRightPlayer)
)
imageViews = arrayOf(
findViewById(R.id.imgLeftService),
findViewById(R.id.imgRightService)
)
updateUI()
StarterNameDialog().show( supportFragmentManager, "StarterNameDialog")
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main, menu)
undo = menu.findItem(R.id.action_undo)
redo = menu.findItem(R.id.action_redo)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.action_undo -> {
step--
reloadState()
redo?.isVisible = true
true
}
R.id.action_redo -> {
step++
reloadState()
undo?.isVisible = true
true
}
R.id.action_new_match -> {
startActivity(
Intent(this, MainActivity::class.java).apply {
putExtra("names", players.map{ it.name }.toTypedArray())
}
)
true
}
R.id.action_about -> {
startActivity(Intent(this, CreditsActivity::class.java))
true
}
else -> {
super.onOptionsItemSelected(item)
}
}
fun saveState() {
val state = State(players.map { it.score }, serviceSide)
if (step == history.size) {
history.add(state)
} else {
history[step] = state
history = history.subList(0, step+1).toMutableList()
}
if (step > 0) {
undo?.isVisible = true
}
redo?.isVisible = false
}
fun reloadState() {
history[step].let{
players.zip(it.score).forEach{(player, score) -> player.score = score}
serviceSide = it.serviceSide
relaunchSide = when(serviceSide) {
Side.LEFT -> Side.RIGHT
Side.RIGHT -> Side.LEFT
}
}
when(step){
0 -> undo?.isVisible = false
history.size - 1 -> redo?.isVisible = false
}
this.step = step
updateUI()
}
fun setStarterName(serviceSide: Side, names: Collection<String>) {
players.zip(names).forEach { (player, name) -> player.name = name}
this.serviceSide = serviceSide
relaunchSide = when(serviceSide) {
Side.LEFT -> Side.RIGHT
Side.RIGHT -> Side.LEFT
}
saveState()
updateUI()
Toast.makeText(applicationContext, R.string.info, Toast.LENGTH_LONG).show()
}
fun updateUI() {
textScore?.text = getString(R.string.score, players[serviceSide.value].score, players[relaunchSide.value].score)
textService?.text = getString(R.string.service, players[serviceSide.value].name)
for ((button, player) in buttons.zip(players)) {
button.text = fromHtml(getString(R.string.button_text, player.name, player.score))
}
when (serviceSide) {
Side.LEFT -> {
imageViews[Side.LEFT.value]?.setImageResource(R.drawable.ic_left_service)
imageViews[Side.RIGHT.value]?.setImageResource(0)
}
Side.RIGHT -> {
imageViews[Side.LEFT.value]?.setImageResource(0)
imageViews[Side.RIGHT.value]?.setImageResource(R.drawable.ic_right_service)
}
}
}
fun updateScore(view: View) {
for (side in enumValues<Side>()) {
if (view == buttons[side.value]) {
if (!matchIsFinished()) {
step++
players[side.value].score++
if ((players.sumBy { it.score } % 2 == 0) or (players.all { it.score >= 10 })) {
serviceSide = relaunchSide.also { relaunchSide = serviceSide }
}
saveState()
updateUI()
}
if (matchIsFinished()) {
EndOfMatchDialog().show(supportFragmentManager, "EndOfMatchDialog")
}
}
}
}
fun matchIsFinished(): Boolean {
val (minScore, maxScore) = players.map { it.score }.sorted()
return (maxScore >= 11) and (maxScore - minScore >= 2)
}
}

View File

@ -0,0 +1,216 @@
package adrienmalin.pingpoints
import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.os.Bundle
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.support.v7.app.AppCompatDelegate
import android.text.method.LinkMovementMethod
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import java.util.regex.Pattern
class MatchActivity : AppCompatActivity() {
var matchModel: MatchModel? = null
var textScore: android.widget.TextView? = null
var textService: android.widget.TextView? = null
var buttons: Array<Button> = emptyArray()
var imageViews: Array<ImageView> = emptyArray()
var tts: TextToSpeech? = null
inner class WaitForTtsInit : TextToSpeech.OnInitListener {
override fun onInit(status: Int) {
updateUI()
}
}
inner class SttAfterTts : UtteranceProgressListener() {
override fun onDone(id: String) {
SttDialog().show( supportFragmentManager, "SttDialog")
}
override fun onStart(id: String) {}
@Suppress("OverridingDeprecatedMember")
override fun onError(id: String) {}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
setContentView(R.layout.activity_match)
initMatchModel()
findViews()
updateUI()
}
fun initMatchModel() {
matchModel = ViewModelProviders.of(this).get(MatchModel::class.java).apply {
if (!matchStarted) {
intent.apply {
matchStarted = true
val player1Name = getStringExtra("player1Name")
val player2Name = getStringExtra("player2Name")
players = listOf(
Player(player1Name, 0, Pattern.compile(getString(R.string.pattern, player1Name))),
Player(player2Name, 0, Pattern.compile(getString(R.string.pattern, player2Name)))
)
serviceSide = getIntExtra("starterId", 0)
relaunchSide = when(serviceSide) {
0 -> 1
else -> 0
}
ttsEnabled = getBooleanExtra("enableTTS", false)
sttEnabled = getBooleanExtra("enableSTT", false)
saveState()
if (ttsEnabled) tts = TextToSpeech(this@MatchActivity, WaitForTtsInit())
if (!sttEnabled) showPopUp(getString(R.string.button_hint))
}
}
}
}
fun findViews() {
textScore = findViewById(R.id.textScore)
textService = findViewById(R.id.textService)
buttons = arrayOf(
findViewById(R.id.buttonPlayer0),
findViewById(R.id.buttonPlayer1)
)
imageViews = arrayOf(
findViewById(R.id.imgService0),
findViewById(R.id.imgService1)
)
// Set HTML text for icons credits
findViewById<TextView>(R.id.iconsCredit).apply {
setText(fromHtml(getString(R.string.iconCredits)))
movementMethod = LinkMovementMethod.getInstance()
}
}
fun updateUI() {
matchModel?.apply {
textScore?.text = getString(
R.string.score_score,
players[serviceSide].score,
players[relaunchSide].score
)
textService?.text = getString(R.string.service, players[serviceSide].name)
for ((button, player) in buttons.zip(players))
button.text = fromHtml(getString(R.string.button_text, player.name, player.score))
imageViews[0].setImageResource(
when(serviceSide) {
0 -> R.drawable.ic_service_0
else -> 0
}
)
imageViews[1].setImageResource(
when(serviceSide) {
0 -> 0
else -> R.drawable.ic_service_1
}
)
if (matchFinished)
proclaimVictory()
else {
if (ttsEnabled) {
var scoreSpeech: String = getString(
R.string.update_score_speech,
players[serviceSide].score,
players[relaunchSide].score,
players[serviceSide].name
)
if (matchPoint) scoreSpeech += getString(R.string.match_point)
say(scoreSpeech)
}
if (sttEnabled) {
if (ttsEnabled) tts?.setOnUtteranceProgressListener(SttAfterTts())
else SttDialog().show(supportFragmentManager, "SttDialog")
}
}
}
}
fun proclaimVictory() {
matchModel?.apply {
val (loser, winner) = players.sortedBy { it.score }
if (ttsEnabled) {
say(
getString(
R.string.victory_speech,
winner.name,
winner.score,
loser.score
)
)
}
startActivity(
Intent(this@MatchActivity, VictoryActivity::class.java).apply {
putExtra("winnerName", winner.name)
putExtra("player1Name", players[0].name)
putExtra("player2Name", players[1].name)
putExtra("player1Score", players[0].score)
putExtra("player2Score", players[1].score)
}
)
}
}
fun updateScore(view: View) {
matchModel?.apply {
if (!matchFinished) {
when(view) {
buttons[0] -> updateScore(players[0])
buttons[1] -> updateScore(players[1])
}
}
updateUI()
}
}
override fun onBackPressed() {
if (matchModel?.pointId == 0)
super.onBackPressed()
else {
matchModel?.undo()
updateUI()
}
}
fun showPopUp(text: String, duration: Int = Snackbar.LENGTH_SHORT) {
Snackbar.make(
findViewById(R.id.coordinatorLayout),
text,
duration
).show()
}
fun showPopUp(textId: Int, duration: Int = Snackbar.LENGTH_SHORT) {
Snackbar.make(
findViewById(R.id.coordinatorLayout),
textId,
duration
).show()
}
@Suppress("DEPRECATION")
fun say(text: String, queueMode: Int = TextToSpeech.QUEUE_FLUSH) {
tts?.speak(
text,
queueMode,
hashMapOf(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID to "TTS")
)
}
}

View File

@ -0,0 +1,53 @@
package adrienmalin.pingpoints
import android.arch.lifecycle.ViewModel
class MatchModel : ViewModel() {
var matchStarted: Boolean = false
var matchFinished: Boolean = false
var matchPoint: Boolean = false
var players: List<Player> = emptyList()
var serviceSide: Int = 0
var relaunchSide: Int = 1
var ttsEnabled: Boolean = false
var sttEnabled: Boolean = false
var pointId: Int = -1
var history: MutableList<Point> = ArrayList()
fun updateScore(scorer: Player) {
scorer.score++
if ((players.sumBy { it.score } % 2 == 0) or (players.all { it.score >= 10 })) {
serviceSide = relaunchSide.also { relaunchSide = serviceSide }
}
saveState()
updateMatch()
}
fun updateMatch() {
val (minScore, maxScore) = players.map { it.score }.sorted()
matchFinished = (maxScore >= 11) and (maxScore - minScore >= 2)
matchPoint = (maxScore >= 10) and (maxScore - minScore >= 1)
}
fun saveState() {
val point = Point(players.map { it.score }, serviceSide)
if (++pointId == history.size) {
history.add(point)
} else {
history[pointId] = point
}
}
fun undo() {
history[--pointId].let {
players.zip(it.score).forEach{(player, score) -> player.score = score}
serviceSide = it.serviceSide
relaunchSide = when(serviceSide) {
0 -> 1
else -> 0
}
}
updateMatch()
}
}

View File

@ -0,0 +1,9 @@
package adrienmalin.pingpoints
import java.util.regex.Pattern
data class Player (
var name: String,
var score: Int,
var pattern: Pattern? = null
)

View File

@ -0,0 +1,6 @@
package adrienmalin.pingpoints
data class Point (
val score: List<Int>,
val serviceSide: Int
)

View File

@ -0,0 +1,197 @@
package adrienmalin.pingpoints
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.os.Bundle
import android.speech.SpeechRecognizer
import android.speech.tts.TextToSpeech
import android.support.design.widget.Snackbar
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.view.MotionEvent
import android.view.View
import android.widget.*
class StarterNameActivity : AppCompatActivity() {
val CHECK_TTS = 1
val ASK_PERMISSIONS_RECORD_AUDIO = 2
var player1NameInput: AutoCompleteTextView? = null
var player2NameInput: AutoCompleteTextView? = null
var starterRadioGroup: RadioGroup? = null
var enableTtsSwitch: Switch? = null
var enableSttSwitch: Switch? = null
var previousMatch: SharedPreferences? = null
var previousPlayers: Set<String> = emptySet()
@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_starter_name)
findViews()
checkTtsAvailable()
checkSttAvailable()
restorePreviousSettings()
}
fun findViews() {
player1NameInput = findViewById(R.id.player1Name)
player2NameInput = findViewById(R.id.player2Name)
starterRadioGroup = findViewById(R.id.starterRadioGroup)
enableTtsSwitch = findViewById(R.id.enableTtsSwitch)
enableSttSwitch = findViewById(R.id.enableSttSwitch)
}
fun restorePreviousSettings() {
previousMatch = getPreferences(Context.MODE_PRIVATE).apply {
getStringSet("previousPlayers", emptySet())?.let { previousPlayers = it.toSet() }
val adapter = ArrayAdapter<String>(
this@StarterNameActivity,
android.R.layout.simple_list_item_1,
previousPlayers.toList())
player1NameInput?.apply {
setText(
getString("previousPlayer2", getString(R.string.player_1_default_name)),
TextView.BufferType.EDITABLE
)
setAdapter(adapter)
}
player2NameInput?.apply{
setText(
getString("previousPlayer1", getString(R.string.player_2_default_name)),
TextView.BufferType.EDITABLE
)
setAdapter(adapter)
}
starterRadioGroup?.check(
when(getInt("previousStarterId", 0)) {
1 -> R.id.radioPlayer2Starts
else -> R.id.radioPlayer1Starts
}
)
enableTtsSwitch?.isChecked = getBoolean("enableTTS", false)
enableSttSwitch?.isChecked = getBoolean("enableSTT", false)
}
}
fun checkTtsAvailable() {
enableTtsSwitch?.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
Intent().apply {
action = TextToSpeech.Engine.ACTION_CHECK_TTS_DATA
startActivityForResult(this, CHECK_TTS)
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
CHECK_TTS -> {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
enableTtsSwitch?.isChecked = true
} else {
enableTtsSwitch?.isChecked = false
showText(R.string.TTS_unavailable)
Intent().apply {
action = TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA
startActivity(this)
}
}
} else -> {}
}
}
fun checkSttAvailable() {
enableSttSwitch?.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
if (SpeechRecognizer.isRecognitionAvailable(this@StarterNameActivity)) {
// Ask for record audio permission
if (ContextCompat.checkSelfPermission(
this@StarterNameActivity,
Manifest.permission.RECORD_AUDIO
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this@StarterNameActivity,
arrayOf(Manifest.permission.RECORD_AUDIO),
ASK_PERMISSIONS_RECORD_AUDIO
)
}
} else {
enableSttSwitch?.isChecked = false
showText(R.string.STT_unavailable)
}
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
ASK_PERMISSIONS_RECORD_AUDIO -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
enableSttSwitch?.isChecked = true
} else {
enableSttSwitch?.isChecked = false
showText(R.string.audio_record_permission_denied)
}
} else -> {}
}
}
fun swapNames(view: View) {
player1NameInput?.text = player2NameInput?.text.also {
player2NameInput?.text = player1NameInput?.text
}
}
fun startMatch(view: View) {
val player1Name = player1NameInput?.text.toString()
val player2Name = player2NameInput?.text.toString()
val radioStarterId = starterRadioGroup?.checkedRadioButtonId
val starterId = when(radioStarterId) {
R.id.radioPlayer2Starts -> 1
else -> 0
}
val enableTTS = enableTtsSwitch?.isChecked
val enableSTT = enableSttSwitch?.isChecked
// Save settings
previousMatch?.edit()?.apply{
player1Name.let { putString("previousPlayer1", it) }
player2Name.let { putString("previousPlayer2", it) }
putInt("previousStarterId", starterId)
putStringSet("previousPlayers", previousPlayers.plus(player1Name).plus(player2Name))
enableTTS?.let { putBoolean("enableTTS", it) }
enableSTT?.let { putBoolean("enableSTT", it) }
commit()
}
startActivity(
Intent(this, MatchActivity::class.java).apply {
putExtra("player1Name", player1Name)
putExtra("player2Name", player2Name)
putExtra("starterId", starterId)
putExtra("enableTTS", enableTTS)
putExtra("enableSTT", enableSTT)
}
)
}
fun showText(textId: Int, duration: Int = Snackbar.LENGTH_SHORT) {
Snackbar.make(
findViewById(R.id.coordinatorLayout),
textId,
duration
).show()
}
}

View File

@ -1,42 +0,0 @@
package adrienmalin.pingpoints
import android.app.AlertDialog
import android.content.Context
import android.os.Bundle
import android.support.v4.app.DialogFragment
import android.view.LayoutInflater
import android.view.View
import android.widget.EditText
import android.widget.RadioGroup
import android.widget.TextView
class StarterNameDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?) =
AlertDialog.Builder(activity).apply {
val mainActivity = activity as MainActivity
val inflater:LayoutInflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val namesView: View = inflater.inflate(R.layout.starter_name_dialog, null)
val inputsPlayersNames: Array<EditText?> = arrayOf(
namesView.findViewById(R.id.inputLeftPlayerName),
namesView.findViewById(R.id.inputRightPlayerName)
)
inputsPlayersNames.zip(mainActivity.players.map{ it.name }).forEach { (inputPlayerName, name) ->
inputPlayerName?.setText(name, TextView.BufferType.EDITABLE)
}
setTitle(R.string.starter_name_dialog_message)
setView(namesView)
setPositiveButton(R.string.go_button) { dialog, id ->
dismiss()
mainActivity.setStarterName(
when (namesView.findViewById<RadioGroup>(R.id.radioGroup)?.checkedRadioButtonId) {
R.id.radioLeftPlayer -> Side.LEFT
else -> Side.RIGHT
},
inputsPlayersNames.map{ it?.text.toString() }
)
}
}.create()
}

View File

@ -0,0 +1,174 @@
package adrienmalin.pingpoints
import android.app.AlertDialog
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.os.Build
import android.os.Bundle
import android.speech.RecognitionListener
import android.speech.RecognizerIntent
import android.speech.SpeechRecognizer
import android.support.v4.app.DialogFragment
import android.view.LayoutInflater
import android.widget.ImageView
import android.widget.TextView
import java.util.*
import kotlin.math.max
import kotlin.math.min
class SttDialog : DialogFragment() {
var matchActivity: MatchActivity? = null
var partialResultsTextView: TextView? = null
var icStt: ImageView? = null
var stt: SpeechRecognizer? = null
var sttIntent: Intent? = null
inner class SttListener : RecognitionListener {
val ERROR_NOT_UNDERSTOOD = 1
var minRms: Float = 0f
var maxRms: Float = 0f
override fun onReadyForSpeech(arg0: Bundle?) {}
override fun onBeginningOfSpeech() {}
override fun onBufferReceived(buffer: ByteArray?) {}
override fun onRmsChanged(rmsdB: Float) {
minRms = min(rmsdB, minRms)
maxRms = max(rmsdB, maxRms)
if (minRms != maxRms)
icStt?.alpha = 0.5f + (rmsdB - minRms) / (2 * (maxRms - minRms))
}
override fun onPartialResults(data: Bundle) {
data.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)?.let { results ->
if (results.isNotEmpty())
partialResultsTextView?.text = results[0]
}
}
override fun onResults(data: Bundle) {
data.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)?.let { results ->
matchActivity?.apply {
matchModel?.apply {
for (result in results) {
for (player in players) {
if (player.pattern?.matcher(result)?.find() == true) {
dismiss()
updateScore(player)
updateUI()
return
}
}
}
partialResultsTextView?.text = getString(R.string.not_understood)
onError(ERROR_NOT_UNDERSTOOD)
}
}
}
}
override fun onEndOfSpeech() {}
override fun onError(errorCode: Int) {
muteAudio()
stt?.destroy()
stt = SpeechRecognizer.createSpeechRecognizer(activity).apply {
setRecognitionListener(SttListener())
startListening(sttIntent)
}
}
override fun onEvent(arg0: Int, arg1: Bundle?) {}
}
override fun onCreateDialog(savedInstanceState: Bundle?) = AlertDialog.Builder(activity).apply {
(context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater).inflate(R.layout.dialog_stt, null).let { view ->
partialResultsTextView = view.findViewById(R.id.partialResultTextView)
icStt = view.findViewById(R.id.icStt)
setView(view)
matchActivity = (activity as MatchActivity).apply {
matchModel?.apply {
view.findViewById<TextView>(R.id.sttHintTextView).text = getString(
R.string.STT_hint,
players[0].name,
players[1].name
)
sttIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 10)
putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true)
putExtra(RecognizerIntent.EXTRA_PREFER_OFFLINE, true)
}
stt = SpeechRecognizer.createSpeechRecognizer(activity).apply {
setRecognitionListener(SttListener())
try {
startListening(sttIntent)
} catch (e: ActivityNotFoundException) {
sttEnabled = false
dismiss()
showPopUp(R.string.STT_unavailable)
}
}
muteAudio()
}
}
}
}.create()!!
override fun onStop() {
super.onStop()
stt?.stopListening()
stt?.destroy()
unMuteAudio()
}
@Suppress("DEPRECATION")
fun muteAudio() {
activity?.apply {
(getSystemService(Context.AUDIO_SERVICE) as AudioManager).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
adjustStreamVolume(AudioManager.STREAM_NOTIFICATION, AudioManager.ADJUST_MUTE, 0)
adjustStreamVolume(AudioManager.STREAM_ALARM, AudioManager.ADJUST_MUTE, 0)
adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_MUTE, 0)
adjustStreamVolume(AudioManager.STREAM_RING, AudioManager.ADJUST_MUTE, 0)
adjustStreamVolume(AudioManager.STREAM_SYSTEM, AudioManager.ADJUST_MUTE, 0)
} else {
setStreamMute(AudioManager.STREAM_NOTIFICATION, true)
setStreamMute(AudioManager.STREAM_ALARM, true)
setStreamMute(AudioManager.STREAM_MUSIC, true)
setStreamMute(AudioManager.STREAM_RING, true)
setStreamMute(AudioManager.STREAM_SYSTEM, true)
}
}
}
}
@Suppress("DEPRECATION")
fun unMuteAudio() {
activity?.apply {
(getSystemService(Context.AUDIO_SERVICE) as AudioManager).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
adjustStreamVolume(AudioManager.STREAM_NOTIFICATION, AudioManager.ADJUST_UNMUTE, 0)
adjustStreamVolume(AudioManager.STREAM_ALARM, AudioManager.ADJUST_UNMUTE, 0)
adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_UNMUTE, 0)
adjustStreamVolume(AudioManager.STREAM_RING, AudioManager.ADJUST_UNMUTE, 0)
adjustStreamVolume(AudioManager.STREAM_SYSTEM, AudioManager.ADJUST_UNMUTE, 0)
} else {
setStreamMute(AudioManager.STREAM_NOTIFICATION, false)
setStreamMute(AudioManager.STREAM_ALARM, false)
setStreamMute(AudioManager.STREAM_MUSIC, false)
setStreamMute(AudioManager.STREAM_RING, false)
setStreamMute(AudioManager.STREAM_SYSTEM, false)
}
}
}
}
}

View File

@ -0,0 +1,124 @@
package adrienmalin.pingpoints
import android.arch.lifecycle.ViewModelProviders
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.app.AppCompatDelegate
import android.view.View
import android.widget.ArrayAdapter
import android.widget.GridView
import android.widget.TextView
import kotlin.math.max
import kotlin.math.min
class VictoryActivity : AppCompatActivity() {
var victoryModel: VictoryModel? = null
var previousMatch: SharedPreferences? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
setContentView(R.layout.activity_victory)
initVictoryModel()
previousMatch = getPreferences(Context.MODE_PRIVATE)
updateUI()
saveScore()
}
fun initVictoryModel() {
victoryModel = ViewModelProviders.of(this).get(VictoryModel::class.java).apply {
if (!matchFinished) {
matchFinished = true
winnerName = intent.getStringExtra("winnerName")
players = listOf(
Player(
intent.getStringExtra("player1Name"),
intent.getIntExtra("player1Score", 0)
),
Player(
intent.getStringExtra("player2Name"),
intent.getIntExtra("player2Score", 0)
)
)
}
}
}
fun updateUI() {
victoryModel?.apply {
findViewById<TextView>(R.id.congrats).text = getString(R.string.congrats, winnerName)
findViewById<TextView>(R.id.player1NameTextView).text = players[0].name
findViewById<TextView>(R.id.scoreTextView).text = getString(
R.string.score,
players[0].score,
players[1].score
)
findViewById<TextView>(R.id.player2NameTextView).text = players[1].name
findViewById<GridView>(R.id.previousMatchesGrid).adapter = ArrayAdapter<String>(
this@VictoryActivity,
R.layout.grid_item,
R.id.grid_item_text,
previousMatch?.getString("previousMatches", "")?.split("\t|\n".toRegex())?.toMutableList()
)
}
}
fun saveScore() {
victoryModel?.apply {
previousMatch?.edit()?.apply {
putString(
"previousMatches",
getString(
R.string.results,
players[0].name,
"%2d - %2d".format(players[0].score, players[1].score),
players[1].name,
previousMatches
)
)
commit()
}
}
}
fun newMatch(view: View) {
startActivity(
Intent(this, StarterNameActivity::class.java)
)
}
fun share(view: View) {
victoryModel?.apply {
startActivity(
Intent().apply {
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_SUBJECT,
getString(
R.string.share_subject,
players[0].name,
players[1].name
)
)
putExtra(
Intent.EXTRA_TEXT,
getString(
R.string.share_message,
players[0].name,
players[1].name,
winnerName,
max(players[0].score, players[1].score),
min(players[0].score, players[1].score)
)
)
type = "text/plain"
}
)
}
}
}

View File

@ -0,0 +1,10 @@
package adrienmalin.pingpoints
import android.arch.lifecycle.ViewModel
class VictoryModel : ViewModel() {
var matchFinished: Boolean = false
var winnerName:String = ""
var players: List<Player> = emptyList()
var previousMatches: String = ""
}

View File

@ -1,33 +0,0 @@
package adrienmalin.pingpoints
import android.os.Build
import android.text.Html
import android.text.Spanned
data class Player(
var name: String,
var score: Int = 0
)
enum class Side(val value:Int) {
LEFT(0),
RIGHT(1)
}
data class State(
val score: List<Int>,
val serviceSide: Side
)
@SuppressWarnings("deprecation")
fun fromHtml(html: String): Spanned {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY)
} else {
Html.fromHtml(html)
}
}

View File

@ -1,34 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>

View File

@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFFFF" android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
</vector>

View File

@ -1,15 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="930.9091"
android:viewportHeight="930.9091"
android:viewportWidth="1034.3434"
android:viewportHeight="1034.3434"
android:autoMirrored="true">
<group android:translateX="209.45454"
android:translateY="205.14478">
<path android:fillColor="#A1D8F6" android:pathData="M8.348,89.733h495.304v331.386h-495.304z"/>
<path android:fillColor="#0088FF" android:pathData="M43.542,117.136h424.504v276.58h-424.504z"/>
<path android:fillColor="#016DF5" android:pathData="M255.8,117.136h212.257v276.58h-212.257z"/>
<path android:fillColor="#FFFFFF" android:pathData="M235.976,69.398h41.06v373.203h-41.06z"/>
<path android:fillColor="#3C3A41" android:pathData="M503.652,81.386H285.38V69.399c0,-4.611 -3.736,-8.348 -8.348,-8.348h-41.06c-4.61,0 -8.348,3.736 -8.348,8.348v11.989H99.981c-4.61,0 -8.348,3.736 -8.348,8.348s3.738,8.348 8.348,8.348h127.644v10.704h-77.956H43.542c-4.61,0 -8.348,3.736 -8.348,8.348v138.864v137.719c0,4.611 3.738,8.348 8.348,8.348h106.126h77.956v10.704H16.696V98.082h26.852c4.61,0 8.348,-3.736 8.348,-8.348s-3.738,-8.348 -8.348,-8.348h-35.2C3.738,81.386 0,85.123 0,89.734v331.385c0,4.611 3.738,8.348 8.348,8.348h219.276v13.134c0,4.611 3.738,8.348 8.348,8.348h41.06c4.611,0 8.348,-3.736 8.348,-8.348v-13.134h130.937c4.611,0 8.348,-3.736 8.348,-8.348c0,-4.611 -3.736,-8.348 -8.348,-8.348H285.38v-10.704h76.542h106.126c4.611,0 8.348,-3.736 8.348,-8.348v-137.72V117.134c0,-4.611 -3.736,-8.348 -8.348,-8.348H361.922H285.38V98.082h209.924v314.69h-27.248c-4.611,0 -8.348,3.736 -8.348,8.348c0,4.611 3.736,8.348 8.348,8.348h35.596c4.611,0 8.348,-3.736 8.348,-8.348V89.734C512,85.124 508.263,81.386 503.652,81.386zM51.89,125.482h89.431v122.17H51.89V125.482zM51.89,385.371V264.347h89.431v121.023H51.89zM158.015,385.371V255.999V125.482h69.609v259.889H158.015zM268.684,434.252H244.32v-13.134v-27.4V117.134v-27.4V77.747h24.365v11.989v27.4V393.72v27.4V434.252zM370.269,385.371V264.347H459.7v121.023H370.269zM459.7,125.482v122.17h-89.431v-122.17H459.7zM353.574,125.482v130.518v129.371H285.38V125.482H353.574z"/>
<group android:translateX="51.71717"
android:translateY="51.71717">
<group android:translateX="209.45454"
android:translateY="205.14478">
<path android:fillColor="#A1D8F6" android:pathData="M8.348,89.733h495.304v331.386h-495.304z"/>
<path android:fillColor="#0088FF" android:pathData="M43.542,117.136h424.504v276.58h-424.504z"/>
<path android:fillColor="#016DF5" android:pathData="M255.8,117.136h212.257v276.58h-212.257z"/>
<path android:fillColor="#FFFFFF" android:pathData="M235.976,69.398h41.06v373.203h-41.06z"/>
<path android:fillColor="#3C3A41" android:pathData="M503.652,81.386H285.38V69.399c0,-4.611 -3.736,-8.348 -8.348,-8.348h-41.06c-4.61,0 -8.348,3.736 -8.348,8.348v11.989H99.981c-4.61,0 -8.348,3.736 -8.348,8.348s3.738,8.348 8.348,8.348h127.644v10.704h-77.956H43.542c-4.61,0 -8.348,3.736 -8.348,8.348v138.864v137.719c0,4.611 3.738,8.348 8.348,8.348h106.126h77.956v10.704H16.696V98.082h26.852c4.61,0 8.348,-3.736 8.348,-8.348s-3.738,-8.348 -8.348,-8.348h-35.2C3.738,81.386 0,85.123 0,89.734v331.385c0,4.611 3.738,8.348 8.348,8.348h219.276v13.134c0,4.611 3.738,8.348 8.348,8.348h41.06c4.611,0 8.348,-3.736 8.348,-8.348v-13.134h130.937c4.611,0 8.348,-3.736 8.348,-8.348c0,-4.611 -3.736,-8.348 -8.348,-8.348H285.38v-10.704h76.542h106.126c4.611,0 8.348,-3.736 8.348,-8.348v-137.72V117.134c0,-4.611 -3.736,-8.348 -8.348,-8.348H361.922H285.38V98.082h209.924v314.69h-27.248c-4.611,0 -8.348,3.736 -8.348,8.348c0,4.611 3.736,8.348 8.348,8.348h35.596c4.611,0 8.348,-3.736 8.348,-8.348V89.734C512,85.124 508.263,81.386 503.652,81.386zM51.89,125.482h89.431v122.17H51.89V125.482zM51.89,385.371V264.347h89.431v121.023H51.89zM158.015,385.371V255.999V125.482h69.609v259.889H158.015zM268.684,434.252H244.32v-13.134v-27.4V117.134v-27.4V77.747h24.365v11.989v27.4V393.72v27.4V434.252zM370.269,385.371V264.347H459.7v121.023H370.269zM459.7,125.482v122.17h-89.431v-122.17H459.7zM353.574,125.482v130.518v129.371H285.38V125.482H353.574z"/>
</group>
</group>
</vector>

View File

@ -1,5 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="430.556" android:viewportWidth="430.556"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
android:viewportHeight="430.556" android:viewportWidth="430.556"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFF" android:pathData="M139.689,93.625c0.552,-4.94 5.006,-8.496 9.944,-7.945c4.94,0.552 8.497,5.004 7.945,9.943c-0.398,3.566 3.715,14.81 21.66,34.326c16.172,17.59 39.202,37.165 64.845,55.121c17.287,12.104 35.165,23.035 51.702,31.609c4.413,2.288 6.135,7.721 3.847,12.133c-1.602,3.089 -4.743,4.859 -7.997,4.859c-1.396,0 -2.811,-0.325 -4.135,-1.012c-17.231,-8.935 -35.814,-20.293 -53.741,-32.846C184.855,165.572 136.803,119.458 139.689,93.625zM52.83,91.751c-4.802,-1.301 -9.739,1.543 -11.036,6.341c-5.789,21.428 -4.187,44.349 4.51,64.541c2.622,6.087 5.887,11.938 9.705,17.391l25.55,36.492c11.818,16.878 28.379,29.397 47.893,36.205c0.981,0.342 1.981,0.505 2.964,0.505c3.721,0 7.203,-2.326 8.498,-6.038c1.637,-4.693 -0.84,-9.825 -5.533,-11.463c-15.926,-5.556 -29.438,-15.768 -39.076,-29.533l-25.551,-36.493c-3.116,-4.45 -5.78,-9.223 -7.917,-14.186c-7.098,-16.478 -8.399,-35.203 -3.666,-52.727C60.468,97.988 57.629,93.047 52.83,91.751zM306.703,198.433c3.112,0 6.139,-1.616 7.805,-4.507c2.483,-4.306 1.005,-9.81 -3.301,-12.292c-11.505,-6.634 -23.224,-14.118 -34.83,-22.244c-21.658,-15.165 -41.119,-31.282 -56.278,-46.611c-3.495,-3.532 -9.192,-3.565 -12.728,-0.07c-3.534,3.495 -3.566,9.193 -0.07,12.728c15.907,16.085 36.223,32.925 58.752,48.698c12.036,8.428 24.203,16.197 36.163,23.094C303.632,198.044 305.177,198.433 306.703,198.433zM179.468,105.23c4.071,2.851 9.683,1.86 12.535,-2.21l27.736,-39.611c16.175,-23.102 40.497,-38.542 68.484,-43.477c27.986,-4.938 56.124,1.255 79.227,17.431c42.257,29.588 57.098,86.902 34.521,133.317c-2.174,4.47 -0.313,9.855 4.157,12.03c1.268,0.616 2.609,0.908 3.93,0.908c3.336,0 6.542,-1.863 8.1,-5.065c12.747,-26.206 15.785,-56.35 8.555,-84.876c-7.311,-28.845 -24.69,-54.08 -48.939,-71.059C350.733,3.685 317.821,-3.568 285.097,2.205c-32.722,5.77 -61.17,23.839 -80.103,50.879l-27.736,39.611C174.406,96.767 175.396,102.379 179.468,105.23zM349.668,380.735c2.235,3.19 3.094,7.069 2.416,10.92c-0.679,3.851 -2.812,7.203 -6.006,9.439l-37.92,26.552c-2.546,1.781 -5.469,2.636 -8.363,2.637c-4.613,0 -9.154,-2.171 -11.994,-6.224l-23.765,-33.94c-0.015,-0.021 -0.03,-0.042 -0.045,-0.063c-0.015,-0.021 -0.029,-0.042 -0.044,-0.063l-26.687,-38.114c-0.039,-0.053 -0.077,-0.105 -0.114,-0.159c-0.037,-0.054 -0.074,-0.107 -0.11,-0.161l-10.572,-15.099c-2.851,-4.071 -1.861,-9.684 2.21,-12.534c4.072,-2.853 9.684,-1.862 12.535,2.21l5.521,7.886l39.754,-27.834c4.072,-2.852 9.684,-1.862 12.535,2.21l26.714,38.153c0.044,0.061 0.088,0.121 0.131,0.183s0.085,0.123 0.126,0.186L349.668,380.735zM273.574,372.358l32.381,-22.673l-16.519,-23.593l-32.381,22.673L273.574,372.358zM332.984,388.288l-16.705,-23.858l-32.381,22.673l16.706,23.859L332.984,388.288zM424.708,240.113c0,29.289 -23.828,53.117 -53.117,53.117c-15.028,0 -29.419,-6.41 -39.483,-17.587c-8.792,-9.765 -13.634,-22.383 -13.634,-35.53c0,-29.289 23.828,-53.117 53.117,-53.117S424.708,210.823 424.708,240.113zM406.708,240.113c0,-19.363 -15.753,-35.117 -35.117,-35.117s-35.117,15.754 -35.117,35.117c0,8.691 3.2,17.032 9.011,23.485c6.655,7.393 16.171,11.632 26.106,11.632C390.955,275.23 406.708,259.476 406.708,240.113zM118.872,288.815c3.721,0 7.203,-2.326 8.498,-6.038c1.637,-4.693 -0.841,-9.825 -5.534,-11.462c-21.089,-7.355 -38.982,-20.88 -51.746,-39.112L37.09,185.075c-16.176,-23.103 -22.366,-51.238 -17.431,-79.226c4.935,-27.988 20.377,-52.31 43.48,-68.486c36.03,-25.229 84.706,-25.36 121.124,-0.324c4.097,2.815 9.7,1.778 12.515,-2.318c2.816,-4.097 1.778,-9.699 -2.318,-12.516C151.887,-7.061 94.963,-6.895 52.815,22.619C25.774,41.552 7.703,70.001 1.933,102.724s1.479,65.635 20.413,92.676l32.998,47.126c14.943,21.346 35.886,37.178 60.564,45.785C116.889,288.653 117.888,288.815 118.872,288.815zM236.791,289.807l-16.505,23.571c-0.001,0.001 -0.001,0.002 -0.002,0.003c-0.001,0.002 -0.002,0.004 -0.003,0.005l-77.493,110.67c-2.839,4.056 -7.382,6.229 -11.995,6.229c-2.894,0 -5.815,-0.855 -8.361,-2.636l-37.924,-26.557c-3.194,-2.235 -5.327,-5.587 -6.006,-9.437c-0.679,-3.85 0.18,-7.729 2.417,-10.923l23.721,-33.877c0.028,-0.041 0.057,-0.083 0.085,-0.124c0.029,-0.042 0.059,-0.083 0.088,-0.123l26.655,-38.067c0.033,-0.049 0.066,-0.097 0.1,-0.146c0.034,-0.049 0.068,-0.097 0.103,-0.145l26.631,-38.032c0.036,-0.054 0.073,-0.107 0.111,-0.161c0.037,-0.054 0.076,-0.107 0.114,-0.16l16.389,-23.406c-17.779,-23.404 -26.645,-52.261 -25.064,-82.017c0.263,-4.964 4.5,-8.781 9.465,-8.51c4.963,0.264 8.773,4.501 8.51,9.465c-1.461,27.494 7.484,54.077 25.188,74.851c2.659,3.12 2.874,7.643 0.522,11l-15.216,21.73l32.381,22.674l15.216,-21.73c2.351,-3.357 6.672,-4.702 10.515,-3.271c20.884,7.781 44.326,8.711 66.005,2.615c4.785,-1.345 9.755,1.443 11.1,6.229s-1.443,9.754 -6.228,11.1C284.255,297.106 259.48,296.782 236.791,289.807zM146.689,387.102l-32.38,-22.673l-16.707,23.859l32.38,22.673L146.689,387.102zM173.533,348.767l-32.381,-22.674l-16.519,23.591l32.381,22.674L173.533,348.767zM200.377,310.429l-32.38,-22.673l-16.52,23.593l32.38,22.673L200.377,310.429z"/>
</vector>
</vector>

View File

@ -1,5 +0,0 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#FFFFFF" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M18.4,10.6C16.55,8.99 14.15,8 11.5,8c-4.65,0 -8.58,3.03 -9.96,7.22L3.9,16c1.05,-3.19 4.05,-5.5 7.6,-5.5 1.95,0 3.73,0.72 5.12,1.88L13,16h9V7l-3.6,3.6z"/>
</vector>

View File

@ -0,0 +1,7 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true"
android:height="48dp" android:width="48dp"
android:viewportHeight="285.876" android:viewportWidth="285.876">
<path android:fillColor="#FFFFFF" android:pathData="M261.207,76.226c-8.573,9.43 -20.236,13.134 -27.668,9.293c0.605,6.751 -3.436,13.287 -10.141,15.544c-18.231,6.139 -37.408,9.21 -56.583,9.21c-10.257,0 -20.512,-0.885 -30.624,-2.643c15.289,20.576 39.358,32.753 65.156,32.753c8.284,0 15,6.716 15,15s-6.716,15 -15,15c-32.82,0 -63.598,-14.394 -84.591,-39.029l-26.497,44.097c30.164,25.599 53.935,55.258 70.763,88.411c3.749,7.387 0.801,16.415 -6.587,20.165c-2.176,1.104 -4.494,1.627 -6.777,1.627c-5.47,0 -10.742,-3.002 -13.388,-8.214c-14.607,-28.78 -35.188,-54.695 -61.282,-77.281c-3.667,27.708 -13.553,54.145 -29.537,78.86c-2.871,4.438 -7.69,6.855 -12.609,6.855c-2.792,0 -5.614,-0.778 -8.132,-2.406c-6.957,-4.499 -8.935,-13.785 -4.436,-20.741c17.485,-27.035 26.365,-56.402 26.365,-87.284v-3.058c0,-4.645 0.568,-9.303 3.111,-13.535L92.94,83.63c6.162,-13.495 19.867,-12.797 26.78,-11.028l0.941,0.311c30.074,9.922 63.158,9.825 93.164,-0.28c4.559,-1.533 9.328,-0.743 13.052,1.715c-0.392,-6.599 2.662,-14.617 8.781,-21.348c9.621,-10.583 23.14,-13.963 30.195,-7.549C272.908,51.864 270.828,65.643 261.207,76.226zM244.508,138.119c-4.768,0 -8.632,3.865 -8.632,8.632s3.865,8.632 8.632,8.632c4.768,0 8.632,-3.865 8.632,-8.632S249.276,138.119 244.508,138.119zM121.3,62.781c17.337,0 31.391,-14.054 31.391,-31.391S138.636,0 121.3,0c-17.337,0 -31.391,14.054 -31.391,31.391S103.963,62.781 121.3,62.781z"/>
</vector>

View File

@ -0,0 +1,7 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true"
android:height="48dp" android:width="48dp"
android:viewportHeight="285.876" android:viewportWidth="285.876">
<path android:fillColor="#ffffff" android:pathData="m24.693,76.226c8.573,9.43 20.236,13.134 27.668,9.293 -0.605,6.751 3.436,13.287 10.141,15.544 18.231,6.139 37.408,9.21 56.583,9.21 10.257,0 20.512,-0.885 30.624,-2.643 -15.289,20.576 -39.358,32.753 -65.156,32.753 -8.284,0 -15,6.716 -15,15 -0,8.284 6.716,15 15,15 32.82,0 63.598,-14.394 84.591,-39.029l26.497,44.097c-30.164,25.599 -53.935,55.258 -70.763,88.411 -3.749,7.387 -0.801,16.415 6.587,20.165 2.176,1.104 4.494,1.627 6.777,1.627 5.47,0 10.742,-3.002 13.388,-8.214 14.607,-28.78 35.188,-54.695 61.282,-77.281 3.667,27.708 13.553,54.145 29.537,78.86 2.871,4.438 7.69,6.855 12.609,6.855 2.792,0 5.614,-0.778 8.132,-2.406 6.957,-4.499 8.935,-13.785 4.436,-20.741 -17.485,-27.035 -26.365,-56.402 -26.365,-87.284l-0,-3.058c-0,-4.645 -0.568,-9.303 -3.111,-13.535L192.96,83.63c-6.162,-13.495 -19.867,-12.797 -26.78,-11.028l-0.941,0.311c-30.074,9.922 -63.158,9.825 -93.164,-0.28 -4.559,-1.533 -9.328,-0.743 -13.052,1.715 0.392,-6.599 -2.662,-14.617 -8.781,-21.348 -9.621,-10.583 -23.14,-13.963 -30.195,-7.549 -7.055,6.413 -4.975,20.192 4.646,30.775zM41.392,138.119c4.768,0 8.632,3.865 8.632,8.632 -0,4.767 -3.865,8.632 -8.632,8.632 -4.768,0 -8.632,-3.865 -8.632,-8.632 -0,-4.767 3.864,-8.632 8.632,-8.632zM164.6,62.781c-17.337,0 -31.391,-14.054 -31.391,-31.391C133.209,14.053 147.264,0 164.6,0 181.937,0 195.991,14.054 195.991,31.391c-0,17.337 -14.054,31.39 -31.391,31.39z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,15c1.66,0 2.99,-1.34 2.99,-3L15,6c0,-1.66 -1.34,-3 -3,-3S9,4.34 9,6v6c0,1.66 1.34,3 3,3zM17.3,12c0,3 -2.54,5.1 -5.3,5.1S6.7,15 6.7,12L5,12c0,3.42 2.72,6.23 6,6.72L11,22h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M16,17.01V10h-2v7.01h-3L15,21l4,-3.99h-3zM9,3L5,6.99h3V14h2V6.99h3L9,3z"/>
</vector>

View File

@ -1,5 +0,0 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#FFFFFF" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12.5,8c-2.65,0 -5.05,0.99 -6.9,2.6L2,7v9h9l-3.62,-3.62c1.39,-1.16 3.16,-1.88 5.12,-1.88 3.54,0 6.55,2.31 7.6,5.5l2.37,-0.78C21.08,11.03 17.15,8 12.5,8z"/>
</vector>

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/coordinatorLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/linearLayoutText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteY="8dp" android:layout_weight="0">
<TextView
android:id="@+id/textScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:gravity="left"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="@string/score_score" android:layout_margin="8dp"/>
<TextView
android:id="@+id/textService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:gravity="right"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/textScore"
app:layout_constraintTop_toTopOf="parent"
android:text="@string/service" android:layout_margin="8dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" android:layout_weight="1">
<ImageView
android:id="@+id/imgService0"
android:layout_width="48dp"
android:layout_margin="8dp"
android:layout_weight="0"
android:contentDescription="@string/service_img_description"
app:srcCompat="@drawable/ic_service_1"
tools:layout_editor_absoluteY="120dp" android:layout_height="match_parent"/>
<Button
android:id="@+id/buttonPlayer0"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_weight="1"
android:bufferType="spannable"
android:onClick="updateScore"
android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppCompat.Button"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/imgService0"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/button_text" android:layout_marginRight="8dp"
android:theme="@style/ScoreButton"/>
<Button
android:id="@+id/buttonPlayer1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_weight="1"
android:bufferType="spannable"
android:onClick="updateScore"
android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppCompat.Button"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imgService1"
app:layout_constraintStart_toEndOf="@+id/buttonPlayer0"
tools:text="@string/button_text" android:theme="@style/ScoreButton"/>
<ImageView
android:id="@+id/imgService1"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:layout_weight="0"
android:contentDescription="@string/service_img_description"
tools:layout_editor_absoluteY="120dp"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_weight="0">
<TextView
android:id="@+id/pingPointsCredit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/PingPointsCredits"
app:layout_constraintTop_toBottomOf="@+id/enableSttSwitch"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_weight="1" android:layout_margin="8dp" android:gravity="left"/>
<TextView
android:id="@+id/iconsCredit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/iconCredits"
app:layout_constraintTop_toBottomOf="@+id/PingPointsCredit"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_weight="1" android:layout_margin="8dp" android:gravity="right"/>
</LinearLayout>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/myCoordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".StarterNameActivity">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/WhoStarts" android:text="@string/who_starts"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:layout_marginTop="8dp" app:layout_constraintTop_toTopOf="parent"/>
<RadioGroup
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/WhoStarts" android:id="@+id/starterRadioGroup"
android:layout_marginStart="8dp" app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
android:layout_marginRight="8dp" android:orientation="horizontal">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="93dp"
tools:layout_editor_absoluteX="16dp" android:id="@+id/radioPlayer1Starts" android:layout_weight="0"
android:checked="true"/>
<AutoCompleteTextView
android:text="@string/player_1_default_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="48dp"
android:id="@+id/player1Name"
tools:layout_editor_absoluteX="143dp" android:hint="@string/player_1_default_name"
android:layout_weight="1"
android:completionThreshold="1"
android:singleLine="true"
android:imeOptions="actionNext"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content" app:srcCompat="@drawable/ic_swap_horiz"
android:layout_weight="0" android:id="@+id/swapNamesButton"
android:contentDescription="@string/swap_names" android:onClick="swapNames"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="93dp"
tools:layout_editor_absoluteX="16dp" android:id="@+id/radioPlayer2Starts"
android:layout_weight="0" android:checked="true"/>
<AutoCompleteTextView
android:text="@string/player_2_default_name"
android:layout_width="match_parent"
tools:layout_editor_absoluteX="136dp" android:id="@+id/player2Name"
android:hint="@string/player_2_default_name" android:layout_height="wrap_content"
android:layout_weight="1"
android:completionThreshold="1"
android:singleLine="true"
android:imeOptions="actionNext"/>
</RadioGroup>
<Switch
android:text="@string/TTS"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/enableTtsSwitch"
android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="@+id/starterRadioGroup"
android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp" app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp"/>
<Switch
android:text="@string/STT"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/enableSttSwitch" android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/enableTtsSwitch" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"/>
<Button
android:text="@string/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/startMatchButton"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent" android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginRight="8dp"
style="@android:style/Widget.DeviceDefault.Button"
android:drawableStart="@drawable/ic_new_match"
android:drawableLeft="@drawable/ic_new_match"
android:onClick="startMatch"/>
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CreditsActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginBottom="8dp"
android:background="@color/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/PingPointsCredit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/PingPointsCredits"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
tools:layout_editor_absoluteX="136dp"
tools:layout_editor_absoluteY="111dp" />
<TextView
android:id="@+id/iconsCredit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/iconCredits"
app:layout_constraintTop_toBottomOf="@+id/PingPointsCredit"
tools:layout_editor_absoluteX="106dp" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>

View File

@ -1,143 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:layout_editor_absoluteY="73dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginBottom="8dp"
android:background="@color/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<LinearLayout
android:id="@+id/linearLayoutText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteY="8dp">
<TextView
android:id="@+id/textService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:gravity="left"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintBottom_toTopOf="@+id/linearLayoutButtons"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/textScore"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/service" />
<TextView
android:id="@+id/textScore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:gravity="right|center"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/score" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/imgLeftService"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:layout_weight="0"
android:contentDescription="@string/service_img_description"
app:srcCompat="@drawable/ic_left_service"
tools:layout_editor_absoluteY="120dp" />
<Button
android:id="@+id/buttonLeftPlayer"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_weight="1"
android:background="@color/colorAccent"
android:bufferType="spannable"
android:onClick="updateScore"
android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppCompat.Button"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/imgLeftService"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/button_text" />
<Button
android:id="@+id/buttonRightPlayer"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_weight="1"
android:background="@color/colorAccent"
android:bufferType="spannable"
android:onClick="updateScore"
android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppCompat.Button"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imgRightService"
app:layout_constraintStart_toEndOf="@+id/buttonLeftPlayer"
tools:text="@string/button_text" />
<ImageView
android:id="@+id/imgRightService"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:layout_weight="0"
android:contentDescription="@string/service_img_description"
tools:layout_editor_absoluteY="120dp" />
</LinearLayout>
</LinearLayout>
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/coordinatorLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/linearLayoutText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteY="8dp" android:layout_weight="0">
<TextView
android:id="@+id/textScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:gravity="left"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginRight="8dp" android:text="@string/score_score"
android:layout_weight="1" android:layout_margin="8dp"/>
<TextView
android:id="@+id/textService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/textScore"
app:layout_constraintTop_toTopOf="parent"
android:gravity="right" android:text="@string/service"
android:layout_weight="1" android:layout_margin="8dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" android:layout_weight="1">
<ImageView
android:id="@+id/imgService0"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_margin="8dp"
android:contentDescription="@string/service_img_description"
app:srcCompat="@drawable/ic_service_1"
tools:layout_editor_absoluteY="120dp"/>
<Button
android:id="@+id/buttonPlayer0"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:bufferType="spannable"
android:onClick="updateScore"
android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppCompat.Button"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/imgService0"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/button_text" android:layout_margin="8dp" android:layout_weight="1"
android:theme="@style/ScoreButton" android:layout_marginLeft="8dp"/>
<Button
android:id="@+id/buttonPlayer1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:bufferType="spannable"
android:onClick="updateScore"
android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppCompat.Button"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imgService1"
app:layout_constraintStart_toEndOf="@+id/buttonPlayer0"
tools:text="@string/button_text" android:layout_margin="8dp" android:layout_weight="1"
android:theme="@style/ScoreButton"/>
<ImageView
android:id="@+id/imgService1"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_margin="8dp"
android:contentDescription="@string/service_img_description"
tools:layout_editor_absoluteY="120dp"/>
</LinearLayout>
<TextView
android:id="@+id/pingPointsCredit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/PingPointsCredits"
app:layout_constraintTop_toBottomOf="@+id/enableSttSwitch"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" android:layout_marginTop="8dp"
android:layout_weight="0" android:layout_marginLeft="8dp" android:layout_marginRight="8dp"
/>
<TextView
android:id="@+id/iconsCredit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/iconCredits"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_weight="0" android:layout_marginLeft="8dp" android:layout_marginRight="8dp"
android:layout_marginBottom="8dp" android:maxLines="1"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/coordinatorLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".StarterNameActivity">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/WhoStarts" android:text="@string/who_starts"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:layout_marginTop="8dp" app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/WhoStarts"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp" android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:id="@+id/linearLayout"
android:layout_margin="8dp">
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/WhoStarts" android:id="@+id/starterRadioGroup"
android:layout_marginStart="8dp" app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp" android:layout_marginBottom="8dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="93dp"
tools:layout_editor_absoluteX="16dp" android:id="@+id/radioPlayer1Starts"
android:layout_weight="1" android:gravity="top" android:checked="true"/>
<RadioButton
android:layout_height="wrap_content" tools:layout_editor_absoluteY="93dp"
tools:layout_editor_absoluteX="16dp" android:id="@+id/radioPlayer2Starts"
android:layout_width="wrap_content" android:layout_weight="1"
android:gravity="bottom"
android:checked="false"/>
</RadioGroup>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:text="@string/player_1_default_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="48dp"
android:id="@+id/player1Name"
tools:layout_editor_absoluteX="143dp" android:hint="@string/player_1_default_name"
android:selectAllOnFocus="true"
android:completionThreshold="1"
android:singleLine="true"
android:imeOptions="actionNext"/>
<ImageButton
android:layout_width="match_parent"
android:layout_height="wrap_content" app:srcCompat="@drawable/ic_swap_vert"
android:id="@+id/swapNamesButton" android:contentDescription="@string/swap_names"
android:onClick="swapNames"/>
<AutoCompleteTextView
android:text="@string/player_2_default_name"
tools:layout_editor_absoluteX="136dp" android:id="@+id/player2Name"
android:hint="@string/player_2_default_name" android:layout_height="wrap_content"
android:layout_width="match_parent" android:selectAllOnFocus="true"
android:completionThreshold="1"
android:singleLine="true"
android:imeOptions="actionNext"/>
</LinearLayout>
</LinearLayout>
<Switch
android:text="@string/TTS"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/enableTtsSwitch"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp" android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="6dp" android:layout_marginRight="6dp" app:layout_constraintHorizontal_bias="0.0"
android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="@+id/linearLayout"/>
<Switch
android:text="@string/STT"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/enableSttSwitch"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/enableTtsSwitch" android:layout_marginStart="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp" android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginRight="8dp"/>
<Button
android:text="@string/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/startMatchButton"
style="@android:style/Widget.DeviceDefault.Button"
android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginRight="8dp"
android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent"
android:drawableStart="@drawable/ic_new_match"
android:drawableLeft="@drawable/ic_new_match" android:onClick="startMatch"/>
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/coordinatorLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".VictoryActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/congrats"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginRight="8dp" android:layout_marginStart="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
android:text="@string/congrats" android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/congrats"
android:id="@+id/resultLinearLayout" android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/previousMatchesTextView">
<TextView
android:text="@string/player_1_default_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/player1NameTextView"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:gravity="right" tools:layout_editor_absoluteX="8dp" android:layout_weight="1"/>
<TextView
android:text="@string/score"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/scoreTextView"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp" android:layout_weight="0" android:layout_marginRight="24dp"/>
<TextView
android:text="@string/player_2_default_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/player2NameTextView"
android:layout_marginLeft="24dp" android:layout_marginStart="24dp"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:layout_marginEnd="8dp"
android:layout_marginRight="8dp" android:gravity="left"
android:layout_weight="1"/>
</LinearLayout>
<TextView
android:text="@string/previous_matches"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:textAllCaps="true"
android:id="@+id/previousMatchesTextView"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp" android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/resultLinearLayout"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp" android:layout_marginTop="32dp"/>
<GridView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@id/previousMatchesTextView"
android:numColumns="3" android:id="@+id/previousMatchesGrid" android:clickable="false"
android:gravity="center"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginRight="16dp" android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/button3"/>
<Button
android:text="@string/new_match"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button3" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
android:layout_marginRight="8dp" android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent" android:drawableStart="@drawable/ic_new_match"
android:drawableLeft="@drawable/ic_new_match"
android:onClick="newMatch"/>
<Button
android:text="@string/share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button4" android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp" android:layout_marginStart="8dp"
android:drawableStart="@drawable/ic_share" android:onClick="share"/>
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SttDialog">
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
app:srcCompat="@drawable/ic_stt"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/icStt" android:layout_margin="8dp"
android:contentDescription="@string/STT"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/STT_hint" android:id="@+id/sttHintTextView"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:gravity="center"
android:layout_marginLeft="8dp" android:layout_marginRight="8dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/partialResultTextView"
android:layout_margin="8dp" android:gravity="center"/>
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/grid_item_text" android:gravity="center" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginTop="8dp" app:layout_constraintTop_toTopOf="parent"
android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

View File

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
tools:context=".NomsJoueursEtPremierServeurDialog">
<!-- TODO: Update blank fragment layout -->
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radioLeftPlayer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:checked="true"
android:inputType="text" />
<android.support.design.widget.TextInputEditText
android:id="@+id/inputLeftPlayerName"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/name"
android:selectAllOnFocus="true"
android:singleLine="true" />
<RadioButton
android:id="@+id/radioRightPlayer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:inputType="none" />
<android.support.design.widget.TextInputEditText
android:id="@+id/inputRightPlayerName"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/name"
android:selectAllOnFocus="true"
android:singleLine="true" />
</RadioGroup>
</FrameLayout>

View File

@ -1,16 +0,0 @@
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_new_match"
android:icon="@drawable/ic_new_match"
android:title="@string/new_match"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_about"
android:icon="@drawable/ic_about"
android:title="@string/about"
app:showAsAction="ifRoom" />
</menu>

View File

@ -1,30 +0,0 @@
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_undo"
android:icon="@drawable/ic_undo"
android:title="@string/undo"
app:showAsAction="ifRoom"
android:visible="false" />
<item
android:id="@+id/action_redo"
android:icon="@drawable/ic_redo"
android:title="@string/redo"
app:showAsAction="ifRoom"
android:visible="false" />
<item
android:id="@+id/action_new_match"
android:icon="@drawable/ic_new_match"
android:title="@string/new_match"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_about"
android:icon="@drawable/ic_about"
android:title="@string/about"
app:showAsAction="ifRoom" />
</menu>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -1,26 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Ping Points</string>
<string name="info">Cliquez sur le joueur qui a marqué</string>
<string name="service">Service : %s</string>
<string name="score">Score : %d - %d</string>
<string-array name="default_players_names">
<item>Joueur 1</item>
<item>Joueur 2</item>
</string-array>
<string name="end_match_dialog_title">Bravo %s !</string>
<string name="new_match">Nouveau match</string>
<string name="quit_button">Quitter</string>
<string name="name">Nom</string>
<string name="go_button">Allons-y !</string>
<string name="starter_name_dialog_message">Qui commence ?</string>
<string name="share_button">Partager</string>
<string name="share_subject">Match Ping Points : %s contre %s</string>
<string name="share_message">%s contre %s:\n%s a gagné par %d à %d\nPing Points est disponible sur Google Play</string>
<string name="who_starts">Qui commence ?</string>
<string name="player_1_default_name">Joueur 1</string>
<string name="player_2_default_name">Joueur 2</string>
<string name="TTS">Synthèse vocale</string>
<string name="STT">Reconnaissance vocale</string>
<string name="start">Allons-y !</string>
<string name="swap_names">Échanger les noms</string>
<string name="PingPointsCredits">Ping Points par Adrien Malin</string>
<string name="iconCredits"><div>Icônes par <a href="http://www.freepik.com" title="Freepik">Freepik</a> chez <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> Licence <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div></string>
<string name="about">À propos</string>
<string name="iconCredits">Icônes par &lt;a href=&quot;http://www.freepik.com&quot; title=&quot;Freepik&quot;&gt;Freepik&lt;/a&gt; chez &lt;a href=&quot;https://www.flaticon.com/&quot; title=&quot;Flaticon&quot;&gt;flaticon.com&lt;/a&gt; Licence &lt;a href=&quot;http://creativecommons.org/licenses/by/3.0/&quot; title=&quot;Creative Commons BY 3.0&quot; target=&quot;_blank&quot;&gt;CC 3.0 BY&lt;/a&gt;</string>
<string name="TTS_unavailable">Désolé, votre appareil ne permet pas la synthèse vocale.</string>
<string name="STT_unavailable">Désolé, votre appareil ne permet pas la reconnaissance vocale.</string>
<string name="OK">OK</string>
<string name="cancel">Annuler</string>
<string name="audio_record_permission_denied">La reconnaissance vocale a besoin de la permission d\'enregistrer des
fichiers audio pour fonctionner.
</string>
<string name="service">Service : %s</string>
<string name="score_score">Score : %d - %d</string>
<string name="service_img_description">Service</string>
<string name="undo">Annuler</string>
<string name="update_score_speech">"%d - %d. Service : %s. "</string>
<string name="button_hint">Cliquez sur le joueur qui a marqué</string>
<string name="redo">Rétablir</string>
<string name="undo">Annuler</string>
<string name="congrats">Bravo %s !</string>
<string name="previous_matches">Matchs précédents</string>
<string name="new_match">Nouveau match</string>
<string name="share">Partager</string>
<string name="victory_speech">%s gagne par %d à %d.</string>
<string name="share_subject">Match Ping Points : %s contre %s</string>
<string name="share_message">"%s contre %s:\n%s a gagné par %d à %d\nPing Points est disponible sur Google Play\n "</string>
<string name="match_point">Balle de match</string>
<string name="STT_hint">Dîtes : \"Point pour %s\"\nou \"Point pour %s\"</string>
<string name="pattern">(?i:Point pour %s)</string>
<string name="not_understood">Pouvez-vous répéter ?</string>
<string name="STT_disabled">Reconnaissance vocale désactivée.</string>
</resources>

View File

@ -2,5 +2,5 @@
<resources>
<color name="colorPrimary">#016df5</color>
<color name="colorPrimaryDark">#004aa7</color>
<color name="colorAccent">#0088FF</color>
<color name="colorAccent">#0088ff</color>
</resources>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#3C3A41</color>
<color name="ic_launcher_background">#26A69A</color>
</resources>

View File

@ -1,27 +1,45 @@
<resources>
<string name="app_name">Ping Points</string>
<string name="go_button">Play</string>
<string name="starter_name_dialog_message">Who starts?</string>
<string name="info">Click on the scoring player</string>
<string name="service">Service: %s</string>
<string name="score">Score: %d - %d</string>
<string name="button_text" translatable="false">%s &lt;br /&gt; &lt;br /&gt; &lt;big&gt; &lt;big&gt; %d &lt;/big&gt; &lt;/big&gt;</string>
<string name="end_match_dialog_title">Congratulations, %s!</string>
<string-array name="default_players_names">
<item>Player 1</item>
<item>Player 2</item>
</string-array>
<string name="new_match">New match</string>
<string name="quit_button">Quit</string>
<string name="name">Name</string>
<string name="share_button">Share</string>
<string name="share_subject">Ping Points Match: %s vs. %s</string>
<string name="share_message">%s vs. %s:\n%s won by %d to %d\n\nGet Ping Points on Google Play</string>
<string name="radioText" translatable="false"></string>
<string name="who_starts">Who starts?</string>
<string name="player_1_default_name">Player 1</string>
<string name="player_2_default_name">Player 2</string>
<string name="TTS">Text to speech</string>
<string name="STT">Voice recognizer</string>
<string name="start">Play</string>
<string name="swap_names">Swap names</string>
<string name="PingPointsCredits">Ping Points by Adrien Malin</string>
<string name="iconCredits">Icons made by &lt;a href=&quot;http://www.freepik.com&quot; title=&quot;Freepik&quot;&gt;Freepik&lt;/a&gt; from &lt;a href=&quot;https://www.flaticon.com/&quot; title=&quot;Flaticon&quot;&gt;www.flaticon.com&lt;/a&gt; is licensed by &lt;a href=&quot;http://creativecommons.org/licenses/by/3.0/&quot; title=&quot;Creative Commons BY 3.0&quot; target=&quot;_blank&quot;&gt;CC 3.0 BY&lt;/a&gt;</string>
<string name="about">About</string>
<string name="iconCredits">Icons made by &lt;a href=&quot;http://www.freepik.com&quot; title=&quot;Freepik&quot;&gt;Freepik&lt;/a&gt;
from &lt;a href=&quot;https://www.flaticon.com/&quot; title=&quot;Flaticon&quot;&gt;flaticon.com&lt;/a&gt; is
licensed by &lt;a href=&quot;http://creativecommons.org/licenses/by/3.0/&quot; title=&quot;Creative Commons BY
3.0&quot; target=&quot;_blank&quot;&gt;CC 3.0 BY&lt;/a&gt;
</string>
<string name="TTS_unavailable">Sorry, your device doesn\'t support text to speech.</string>
<string name="STT_unavailable">Sorry, your device doesn\'t support voice recognition.</string>
<string name="OK">OK</string>
<string name="cancel">Cancel</string>
<string name="audio_record_permission_denied">Audio recording permission required to use voice recognition.</string>
<string name="service">Service: %s</string>
<string name="score_score">Score: %d - %d</string>
<string name="service_img_description">Service</string>
<string name="button_text" translatable="false">%s &lt;br /&gt; &lt;br /&gt; &lt;big&gt; &lt;big&gt; %d &lt;/big&gt;
&lt;/big&gt;
</string>
<string name="update_score_speech">"%d - %d. Service: %s. "</string>
<string name="button_hint">Click on the scoring player</string>
<string name="undo">Undo</string>
<string name="redo">Redo</string>
<string name="congrats">Congratulations, %s!</string>
<string name="previous_matches">Previous matches</string>
<string name="new_match">New match</string>
<string name="share">Share</string>
<string name="results" translatable="false">%s\t%s\t%s\n%s</string>
<string name="victory_speech">%s wins by %d to %d.</string>
<string name="share_subject">Ping Points Match: %s vs. %s</string>
<string name="share_message">%s vs. %s:\n%s won by %d to %d\nGet Ping Points on Google Play</string>
<string name="match_point">Match point</string>
<string name="STT_hint">Say: \"Point for %s\"\nor \"Point for %s\"</string>
<string name="pattern">(?i:Point for %s)</string>
<string name="not_understood">Can you repeat, please?</string>
<string name="score" translatable="false">%d - %d</string>
<string name="STT_disabled">Voice recognition disabled.</string>
</resources>

View File

@ -0,0 +1,17 @@
<resources>
<!-- the theme applied to the application or activity -->
<style name="PingPointsTheme" parent="Base.V22.Theme.AppCompat">
<item name="android:actionBarStyle">@style/ColoredActionBarBackground</item>
<!-- Support library compatibility -->
<item name="actionBarStyle">@style/ColoredActionBarBackground</item>
</style>
<style name="ColoredActionBarBackground"
parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
<item name="android:background">@color/colorPrimaryDark</item>
<!-- Support library compatibility -->
<item name="background">@color/colorPrimaryDark</item>
</style>
<style name="ScoreButton">
<item name="colorButtonNormal">@color/colorAccent</item>
</style>
</resources>

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="430.556" android:viewportWidth="430.556"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFF" android:pathData="M139.689,93.625c0.552,-4.94 5.006,-8.496 9.944,-7.945c4.94,0.552 8.497,5.004 7.945,9.943c-0.398,3.566 3.715,14.81 21.66,34.326c16.172,17.59 39.202,37.165 64.845,55.121c17.287,12.104 35.165,23.035 51.702,31.609c4.413,2.288 6.135,7.721 3.847,12.133c-1.602,3.089 -4.743,4.859 -7.997,4.859c-1.396,0 -2.811,-0.325 -4.135,-1.012c-17.231,-8.935 -35.814,-20.293 -53.741,-32.846C184.855,165.572 136.803,119.458 139.689,93.625zM52.83,91.751c-4.802,-1.301 -9.739,1.543 -11.036,6.341c-5.789,21.428 -4.187,44.349 4.51,64.541c2.622,6.087 5.887,11.938 9.705,17.391l25.55,36.492c11.818,16.878 28.379,29.397 47.893,36.205c0.981,0.342 1.981,0.505 2.964,0.505c3.721,0 7.203,-2.326 8.498,-6.038c1.637,-4.693 -0.84,-9.825 -5.533,-11.463c-15.926,-5.556 -29.438,-15.768 -39.076,-29.533l-25.551,-36.493c-3.116,-4.45 -5.78,-9.223 -7.917,-14.186c-7.098,-16.478 -8.399,-35.203 -3.666,-52.727C60.468,97.988 57.629,93.047 52.83,91.751zM306.703,198.433c3.112,0 6.139,-1.616 7.805,-4.507c2.483,-4.306 1.005,-9.81 -3.301,-12.292c-11.505,-6.634 -23.224,-14.118 -34.83,-22.244c-21.658,-15.165 -41.119,-31.282 -56.278,-46.611c-3.495,-3.532 -9.192,-3.565 -12.728,-0.07c-3.534,3.495 -3.566,9.193 -0.07,12.728c15.907,16.085 36.223,32.925 58.752,48.698c12.036,8.428 24.203,16.197 36.163,23.094C303.632,198.044 305.177,198.433 306.703,198.433zM179.468,105.23c4.071,2.851 9.683,1.86 12.535,-2.21l27.736,-39.611c16.175,-23.102 40.497,-38.542 68.484,-43.477c27.986,-4.938 56.124,1.255 79.227,17.431c42.257,29.588 57.098,86.902 34.521,133.317c-2.174,4.47 -0.313,9.855 4.157,12.03c1.268,0.616 2.609,0.908 3.93,0.908c3.336,0 6.542,-1.863 8.1,-5.065c12.747,-26.206 15.785,-56.35 8.555,-84.876c-7.311,-28.845 -24.69,-54.08 -48.939,-71.059C350.733,3.685 317.821,-3.568 285.097,2.205c-32.722,5.77 -61.17,23.839 -80.103,50.879l-27.736,39.611C174.406,96.767 175.396,102.379 179.468,105.23zM349.668,380.735c2.235,3.19 3.094,7.069 2.416,10.92c-0.679,3.851 -2.812,7.203 -6.006,9.439l-37.92,26.552c-2.546,1.781 -5.469,2.636 -8.363,2.637c-4.613,0 -9.154,-2.171 -11.994,-6.224l-23.765,-33.94c-0.015,-0.021 -0.03,-0.042 -0.045,-0.063c-0.015,-0.021 -0.029,-0.042 -0.044,-0.063l-26.687,-38.114c-0.039,-0.053 -0.077,-0.105 -0.114,-0.159c-0.037,-0.054 -0.074,-0.107 -0.11,-0.161l-10.572,-15.099c-2.851,-4.071 -1.861,-9.684 2.21,-12.534c4.072,-2.853 9.684,-1.862 12.535,2.21l5.521,7.886l39.754,-27.834c4.072,-2.852 9.684,-1.862 12.535,2.21l26.714,38.153c0.044,0.061 0.088,0.121 0.131,0.183s0.085,0.123 0.126,0.186L349.668,380.735zM273.574,372.358l32.381,-22.673l-16.519,-23.593l-32.381,22.673L273.574,372.358zM332.984,388.288l-16.705,-23.858l-32.381,22.673l16.706,23.859L332.984,388.288zM424.708,240.113c0,29.289 -23.828,53.117 -53.117,53.117c-15.028,0 -29.419,-6.41 -39.483,-17.587c-8.792,-9.765 -13.634,-22.383 -13.634,-35.53c0,-29.289 23.828,-53.117 53.117,-53.117S424.708,210.823 424.708,240.113zM406.708,240.113c0,-19.363 -15.753,-35.117 -35.117,-35.117s-35.117,15.754 -35.117,35.117c0,8.691 3.2,17.032 9.011,23.485c6.655,7.393 16.171,11.632 26.106,11.632C390.955,275.23 406.708,259.476 406.708,240.113zM118.872,288.815c3.721,0 7.203,-2.326 8.498,-6.038c1.637,-4.693 -0.841,-9.825 -5.534,-11.462c-21.089,-7.355 -38.982,-20.88 -51.746,-39.112L37.09,185.075c-16.176,-23.103 -22.366,-51.238 -17.431,-79.226c4.935,-27.988 20.377,-52.31 43.48,-68.486c36.03,-25.229 84.706,-25.36 121.124,-0.324c4.097,2.815 9.7,1.778 12.515,-2.318c2.816,-4.097 1.778,-9.699 -2.318,-12.516C151.887,-7.061 94.963,-6.895 52.815,22.619C25.774,41.552 7.703,70.001 1.933,102.724s1.479,65.635 20.413,92.676l32.998,47.126c14.943,21.346 35.886,37.178 60.564,45.785C116.889,288.653 117.888,288.815 118.872,288.815zM236.791,289.807l-16.505,23.571c-0.001,0.001 -0.001,0.002 -0.002,0.003c-0.001,0.002 -0.002,0.004 -0.003,0.005l-77.493,110.67c-2.839,4.056 -7.382,6.229 -11.995,6.229c-2.894,0 -5.815,-0.855 -8.361,-2.636l-37.924,-26.557c-3.194,-2.235 -5.327,-5.587 -6.006,-9.437c-0.679,-3.85 0.18,-7.729 2.417,-10.923l23.721,-33.877c0.028,-0.041 0.057,-0.083 0.085,-0.124c0.029,-0.042 0.059,-0.083 0.088,-0.123l26.655,-38.067c0.033,-0.049 0.066,-0.097 0.1,-0.146c0.034,-0.049 0.068,-0.097 0.103,-0.145l26.631,-38.032c0.036,-0.054 0.073,-0.107 0.111,-0.161c0.037,-0.054 0.076,-0.107 0.114,-0.16l16.389,-23.406c-17.779,-23.404 -26.645,-52.261 -25.064,-82.017c0.263,-4.964 4.5,-8.781 9.465,-8.51c4.963,0.264 8.773,4.501 8.51,9.465c-1.461,27.494 7.484,54.077 25.188,74.851c2.659,3.12 2.874,7.643 0.522,11l-15.216,21.73l32.381,22.674l15.216,-21.73c2.351,-3.357 6.672,-4.702 10.515,-3.271c20.884,7.781 44.326,8.711 66.005,2.615c4.785,-1.345 9.755,1.443 11.1,6.229s-1.443,9.754 -6.228,11.1C284.255,297.106 259.48,296.782 236.791,289.807zM146.689,387.102l-32.38,-22.673l-16.707,23.859l32.38,22.673L146.689,387.102zM173.533,348.767l-32.381,-22.674l-16.519,23.591l32.381,22.674L173.533,348.767zM200.377,310.429l-32.38,-22.673l-16.52,23.593l32.38,22.673L200.377,310.429z"/>
</vector>

View File

@ -1,17 +0,0 @@
package adrienmalin.pingpoints
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.2.50'
ext.kotlin_version = '1.2.71'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong

View File

@ -1,13 +1,21 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official

Binary file not shown.

View File

@ -1,6 +1,5 @@
#Sat Aug 11 18:40:19 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip