Merge remote branch 'origin/android_branch' into android_branch
2
xwords4/android/XWords4/.gitignore
vendored
|
@ -5,4 +5,6 @@ bin
|
|||
gen
|
||||
libs
|
||||
proguard.cfg
|
||||
proguard-project.txt
|
||||
obj
|
||||
res/drawable*/*gen.png
|
||||
|
|
|
@ -22,14 +22,14 @@
|
|||
to come from a domain that you own or have control over. -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.eehouse.android.xw4"
|
||||
android:versionCode="61"
|
||||
android:versionCode="64"
|
||||
android:versionName="@string/app_version"
|
||||
>
|
||||
|
||||
<!-- BE SURE TO MODIFY project.project AND the variable TARGET in
|
||||
../scripts/setup_local_props.sh if targetSdkVersion changes!!!
|
||||
-->
|
||||
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="11" />
|
||||
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14" />
|
||||
|
||||
<supports-screens android:resizeable="true"
|
||||
android:smallScreens="true"
|
||||
|
@ -51,6 +51,7 @@
|
|||
<uses-feature android:name="android.hardware.telephony"
|
||||
android:required = "false"
|
||||
/>
|
||||
<uses-feature android:name="android.hardware.nfc" android:required="true" />
|
||||
|
||||
<!-- GCM stuff -->
|
||||
<permission android:name="org.eehouse.android.xw4.permission.C2D_MESSAGE"
|
||||
|
@ -59,6 +60,7 @@
|
|||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
|
||||
<application android:icon="@drawable/icon48x48"
|
||||
android:label="@string/app_name"
|
||||
|
@ -74,6 +76,13 @@
|
|||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="@string/xwords_nfc_mime" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity android:name="DictsActivity"
|
||||
|
|
|
@ -51,20 +51,38 @@
|
|||
|
||||
<property name="INITIAL_CLIENT_VERS" value="3"/>
|
||||
<target name="-pre-clean">
|
||||
<exec dir="." executable="../scripts/ndksetup.sh" output="/dev/null">
|
||||
<arg value="${build.target}"/>
|
||||
</exec>
|
||||
<exec dir="." executable="../scripts/ndkbuild.sh" output="/dev/null">
|
||||
<arg value="clean"/>
|
||||
</exec>
|
||||
|
||||
<exec dir="." executable="../scripts/mkimages.sh"
|
||||
failonerror="true" output="/dev/null" >
|
||||
<arg value="--clean"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="-pre-build">
|
||||
<exec dir="." executable="../scripts/ndksetup.sh" output="/dev/null">
|
||||
<arg value="${build.target}"/>
|
||||
</exec>
|
||||
|
||||
<property name="CHAT_ENABLED" value="true" />
|
||||
<property name="THUMBNAIL_ENABLED" value="true" />
|
||||
<exec dir="." executable="../scripts/ndkbuild.sh" failonerror="true">
|
||||
<arg value="BUILD_TARGET=${build.target}" />
|
||||
<arg value="-j3"/>
|
||||
<arg value="INITIAL_CLIENT_VERS=${INITIAL_CLIENT_VERS}" />
|
||||
<arg value="CHAT_ENABLED=${CHAT_ENABLED}" />
|
||||
<arg value="THUMBNAIL_ENABLED=${THUMBNAIL_ENABLED}" />
|
||||
</exec>
|
||||
|
||||
<exec dir="." executable="../scripts/mkimages.sh"
|
||||
failonerror="true" output="/dev/null"
|
||||
/>
|
||||
|
||||
<exec dir="." executable="../scripts/gen_gcmid.sh"
|
||||
output="src/org/eehouse/android/xw4/GCMConsts.java"
|
||||
logError="true"
|
||||
|
@ -74,6 +92,8 @@
|
|||
<arg value="xw4"/>
|
||||
<arg value="${INITIAL_CLIENT_VERS}" />
|
||||
<arg value="${CHAT_ENABLED}" />
|
||||
<arg value="${THUMBNAIL_ENABLED}" />
|
||||
<arg value="${build.target}" />
|
||||
</exec>
|
||||
</target>
|
||||
<!--
|
||||
|
|
11
xwords4/android/XWords4/img_src/back.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g transform='translate(46.03,16.24)' id='g1584'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 0,0 5.5,5.502 -16.87,27.87 35.7,27.87 35.7,35.65 -16.87,35.65 5.5,58.02 0,63.52 -31.76,31.76 0,0 z' id='path1586'/>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 609 B |
18
xwords4/android/XWords4/img_src/content_discard.svg
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g id='g1254'>
|
||||
<g id='g1256'>
|
||||
<g transform='translate(68.92,54.16)' id='g1262'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 0,0 C -0.046,0.281 -0.218,0.557 -0.476,0.82 -2.555,-1.292 -10.92,-1.642 -20.92,-1.642 -30.92,-1.642 -39.28,-1.292 -41.37,0.82 -41.62,0.557 -41.78,0.281 -41.84,0 L -41.86,0 -41.86,-0.152 C -41.86,-0.17 -41.86,-0.188 -41.86,-0.206 -41.86,-0.247 -41.85,-0.283 -41.85,-0.322 L -40.22,-33.68 -40.21,-33.68 C -40.07,-36.29 -37.07,-40.24 -20.92,-40.24 -4.766,-40.24 -1.77,-36.29 -1.629,-33.68 L -1.617,-33.68 0.013,-0.322 C 0.016,-0.283 0.028,-0.247 0.028,-0.206 0.028,-0.188 0.016,-0.17 0.016,-0.152 L 0.028,0 0,0 z' id='path1264'/>
|
||||
</g>
|
||||
<g transform='translate(42.16,71.94)' id='g1266'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 0,0 -0.657,-0.041 -0.657,3.221 C -0.657,4.647 -0.458,5.815 -0.223,5.815 L 2.809,5.815 8.002,5.815 11.03,5.815 C 11.27,5.815 11.46,4.647 11.46,3.221 L 11.46,0.012 C 9.658,0.105 7.779,0.164 5.835,0.164 3.82,0.164 1.863,0.105 0,0 M 15.79,-0.326 15.79,7.549 C 15.79,8.971 14.63,10.15 13.19,10.15 L -2.392,10.15 C -3.813,10.15 -4.982,8.971 -4.982,7.549 L -4.982,-0.416 C -12.69,-1.29 -17.96,-3.06 -17.96,-5.11 L -17.96,-9.003 C -17.96,-9.802 -17.15,-10.56 -15.7,-11.25 -11.9,-13.03 -3.686,-14.27 5.835,-14.27 15.36,-14.27 23.58,-13.03 27.38,-11.25 28.82,-10.56 29.64,-9.802 29.64,-9.003 L 29.64,-5.11 C 29.64,-2.988 23.96,-1.161 15.79,-0.326' id='path1268'/>
|
||||
</g>
|
||||
</g>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
11
xwords4/android/XWords4/img_src/content_new.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g transform='translate(83.05,50.93)' id='g1336'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none' d='M 0,0 -32.12,0 -32.12,32.12 -37.98,32.12 -37.98,0 -70.1,0 -70.1,-5.861 -37.98,-5.861 -37.98,-37.98 -32.12,-37.98 -32.12,-5.861 0,-5.861 0,0 z' id='path1338'/>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 650 B |
9
xwords4/android/XWords4/img_src/dict.svg
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 68.54,65.8 27.62,65.8 27.62,69.47 68.54,69.47 68.54,65.8 z M 68.54,56.09 27.62,56.09 27.62,59.76 68.54,59.76 68.54,56.09 z M 68.54,46.06 27.62,46.06 27.62,50.05 68.54,50.05 68.54,46.06 z M 68.38,36.35 27.46,36.35 27.46,40.18 68.38,40.18 68.38,36.35 z M 68.38,26.8 27.62,26.8 27.62,30.47 68.38,30.47 68.38,26.8 z M 61.6,80.19 21.74,80.19 21.74,15.81 74.26,15.81 74.26,80.19 61.6,80.19 z' id='path1422'/></g>
|
||||
</svg>
|
After Width: | Height: | Size: 839 B |
53
xwords4/android/XWords4/img_src/down.svg
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="120"
|
||||
height="120"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="down.svg"><metadata
|
||||
id="metadata11"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs9" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="640"
|
||||
inkscape:window-height="480"
|
||||
id="namedview7"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.9666667"
|
||||
inkscape:cx="60"
|
||||
inkscape:cy="60"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" />
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g
|
||||
transform="translate(47.72,32.35)"
|
||||
id="g676">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m -1.163978,-15.143535 -23.537465,32.092623 14.683237,0 0,29.964616 17.5617961,0 0,-29.964616 14.8298969,0 z"
|
||||
id="path678"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
11
xwords4/android/XWords4/img_src/download.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g transform='translate(47.72,32.35)' id='g676'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 0,0 -16.37,22.32 -6.158,22.32 -6.158,43.16 6.056,43.16 6.056,22.32 16.37,22.32 0,0 z M -33.34,-5.839 -33.34,-11.85 33.9,-11.85 33.89,-5.839 -33.34,-5.839 z' id='path678'/>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 664 B |
13
xwords4/android/XWords4/img_src/email.svg
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g id='g1198' transform='translate(14.92,58.06)'>
|
||||
<path id='path1200' style='fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none' d='M 0,0 0,-34.61 66.16,-34.61 66.16,0 33.08,-16.45 0,0 z'/>
|
||||
</g><g id='g1202' transform='translate(14.92,72.55)'>
|
||||
<path id='path1204' style='fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none' d='M 0,0 0,-9.209 33.08,-25.65 66.16,-9.209 66.16,0 0,0 z'/>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 766 B |
20
xwords4/android/XWords4/img_src/new_group.svg
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g id='g1388' transform='translate(66.77,29.35)'>
|
||||
<path id='path1390' d='M 0,0 0,13.3 -4.16,13.3 -4.16,0 -17.26,0 -17.26,-4.162 -4.16,-4.162 -4.16,-17.46 0,-17.46 0,-4.162 13.11,-4.162 13.11,0 0,0 z' style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none'/>
|
||||
</g><g id='g1392'>
|
||||
<g id='g1394'>
|
||||
<g id='g1400' transform='translate(33.31,41.18)'>
|
||||
<path id='path1402' d='M 0,0 -2.713,2.713 16.38,21.81 19.09,19.09 0,0 z M -8.74,8.739 10.47,27.95 13.18,25.24 -6.027,6.024 -8.74,8.739 z M -10.61,-4.437 C -11.92,-4.437 -12.97,-3.381 -12.97,-2.08 -12.97,-0.778 -11.92,0.277 -10.61,0.277 -9.311,0.277 -8.256,-0.778 -8.256,-2.08 -8.256,-3.381 -9.311,-4.437 -10.61,-4.437 M 10.82,39.59 -17.15,11.85 -17.19,-8.752 3.41,-8.703 31.38,19.04 10.82,39.59 z' style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none'/>
|
||||
</g>
|
||||
<g id='g1404' transform='translate(32.95,84.1)'>
|
||||
<path id='path1406' d='M 0,0 -12.49,-23.01 7.558,-3.594 0,0 z' style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none'/>
|
||||
</g>
|
||||
</g>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
13
xwords4/android/XWords4/img_src/prefs.svg
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g id='g1522'>
|
||||
<g id='g1524'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 84.01,25.99 72.01,25.99 72.01,21.99 84.01,21.99 84.01,25.99 z M 54,25.99 11.99,25.99 11.99,21.99 54,21.99 54,25.99 z M 84.01,50 42,50 42,46 84.01,46 84.01,50 z M 23.99,50 11.99,50 11.99,46 23.99,46 23.99,50 z M 84.01,74.01 72.01,74.01 72.01,70.01 84.01,70.01 84.01,74.01 z M 54,74.01 11.99,74.01 11.99,70.01 54,70.01 54,74.01 z M 62.12,85.01 C 59.31,85.01 57,82.71 57,79.89 L 57,64.12 C 57,61.3 59.31,59 62.12,59 L 63.89,59 C 66.71,59 69.01,61.3 69.01,64.12 L 69.01,79.89 C 69.01,82.71 66.71,85.01 63.89,85.01 L 62.12,85.01 z M 62.12,37 C 59.31,37 57,34.7 57,31.87 L 57,16.11 C 57,13.29 59.31,10.99 62.12,10.99 L 63.89,10.99 C 66.69,10.99 69.01,13.29 69.01,16.11 L 69.01,31.87 C 69.01,34.7 66.69,37 63.89,37 L 62.12,37 z M 32.12,61 C 29.3,61 26.99,58.7 26.99,55.88 L 26.99,40.12 C 26.99,37.3 29.3,35 32.12,35 L 33.88,35 C 36.69,35 39,37.3 39,40.12 L 39,55.88 C 39,58.7 36.69,61 33.88,61 L 32.12,61 z' id='path1530'/>
|
||||
</g>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
18
xwords4/android/XWords4/img_src/relabel.svg
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g id='g1424'>
|
||||
<g id='g1426'>
|
||||
<g transform='translate(38.5,25.12)' id='g1432'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 0,0 -3.633,3.633 21.93,29.2 25.56,25.57 0,0 z M -11.7,11.7 14.02,37.43 17.65,33.79 -8.072,8.067 -11.7,11.7 z M -14.21,-5.94 C -15.96,-5.94 -17.37,-4.528 -17.37,-2.783 -17.37,-1.042 -15.96,0.372 -14.21,0.372 -12.47,0.372 -11.06,-1.042 -11.06,-2.783 -11.06,-4.528 -12.47,-5.94 -14.21,-5.94 M 14.49,53.02 -22.96,15.87 -23.02,-11.72 4.564,-11.65 42.02,25.5 14.49,53.02 z' id='path1434'/>
|
||||
</g>
|
||||
<g transform='translate(38.02,82.6)' id='g1436'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 0,0 -16.73,-30.81 10.12,-4.812 0,0 z' id='path1438'/>
|
||||
</g>
|
||||
</g>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
11
xwords4/android/XWords4/img_src/reset.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g transform='translate(79.95,67.35)' id='g764'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 0,0 -30.38,-17.54 -30.38,0 -63.89,-19.35 -30.38,-38.7 -30.38,-21.16 0,-38.7 0,0 z' id='path766'/>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 590 B |
13
xwords4/android/XWords4/img_src/save.svg
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g id='g1298'>
|
||||
<g id='g1300'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 70.84,50.41 25.16,50.41 25.16,19.32 70.84,19.32 70.84,50.41 z M 80.88,67.78 80.88,16.74 C 80.88,15.66 80,14.78 78.92,14.78 L 17.08,14.78 C 16,14.78 15.12,15.66 15.12,16.74 L 15.12,79.26 C 15.12,80.34 16,81.22 17.08,81.22 L 25.16,81.22 25.16,57.47 60.8,57.47 60.8,81.22 67.45,81.22 80.88,67.78 z M 64.84,30.94 29.86,30.94 29.86,27.02 64.84,27.02 64.84,30.94 z M 64.84,41.95 29.86,41.95 29.86,38.02 64.84,38.02 64.84,41.95 z M 55.13,61.11 41.52,61.11 41.52,78.59 55.13,78.59 55.13,61.11 z' id='path1306'/>
|
||||
</g>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 988 B |
11
xwords4/android/XWords4/img_src/send.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
|
||||
height="120" xml:space="preserve">
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g transform='translate(20.24,20.6)' id='g1090'>
|
||||
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 0,0 5.287,24.92 38.6,27.24 38.6,27.57 5.287,29.89 0,54.81 55.52,27.4 0,0 z' id='path1092'/>
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 584 B |
53
xwords4/android/XWords4/img_src/up.svg
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="120"
|
||||
height="120"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="up.svg"><metadata
|
||||
id="metadata11"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs9" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="640"
|
||||
inkscape:window-height="480"
|
||||
id="namedview7"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.9666667"
|
||||
inkscape:cx="60.000001"
|
||||
inkscape:cy="60.000001"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" />
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(-1.25,0,0,1.25,116.39005,-0.58771313)">
|
||||
<g
|
||||
transform="translate(47.72,32.35)"
|
||||
id="g676">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m -1.163978,-15.143535 -23.537465,32.092623 14.683237,0 0,29.964616 17.5617961,0 0,-29.964616 14.8298969,0 z"
|
||||
id="path678"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
xwords4/android/XWords4/jni/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Application.mk
|
|
@ -4,17 +4,17 @@ LOCAL_PATH := $(call my-dir)
|
|||
include $(CLEAR_VARS)
|
||||
|
||||
COMMON_PATH=../../../common
|
||||
local_C_INCLUDES+= \
|
||||
LOCAL_C_INCLUDES+= \
|
||||
-I$(LOCAL_PATH)/$(COMMON_PATH) \
|
||||
-I$(LOCAL_PATH)/../../../relay \
|
||||
|
||||
local_LDLIBS += -llog
|
||||
LOCAL_LDLIBS += -llog
|
||||
|
||||
ifeq ($(BUILD_TARGET),debug)
|
||||
local_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DCOMMS_CHECKSUM -Wno-unused-but-set-variable
|
||||
LOCAL_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DCOMMS_CHECKSUM -Wno-unused-but-set-variable
|
||||
endif
|
||||
local_DEFINES += \
|
||||
$(local_DEBUG) \
|
||||
LOCAL_DEFINES += \
|
||||
$(LOCAL_DEBUG) \
|
||||
-DXWFEATURE_RELAY \
|
||||
-DXWFEATURE_SMS \
|
||||
-DXWFEATURE_COMMSACK \
|
||||
|
@ -37,17 +37,18 @@ local_DEFINES += \
|
|||
-DHASH_STREAM \
|
||||
-DXWFEATURE_BASE64 \
|
||||
-DXWFEATURE_DEVID \
|
||||
-DCOMMON_LAYOUT \
|
||||
-DINITIAL_CLIENT_VERS=${INITIAL_CLIENT_VERS} \
|
||||
-DRELAY_ROOM_DEFAULT=\"\" \
|
||||
-D__LITTLE_ENDIAN \
|
||||
|
||||
ifeq ($(CHAT_ENABLED),true)
|
||||
local_DEFINES += -DXWFEATURE_CHAT
|
||||
LOCAL_DEFINES += -DXWFEATURE_CHAT
|
||||
endif
|
||||
|
||||
# -DXWFEATURE_SCOREONEPASS \
|
||||
|
||||
local_SRC_FILES += \
|
||||
LOCAL_SRC_FILES += \
|
||||
xwjni.c \
|
||||
utilwrapper.c \
|
||||
drawwrapper.c \
|
||||
|
@ -58,7 +59,7 @@ local_SRC_FILES += \
|
|||
|
||||
|
||||
COMMON_PATH=../../../common
|
||||
common_SRC_FILES += \
|
||||
COMMON_SRC_FILES += \
|
||||
$(COMMON_PATH)/boarddrw.c \
|
||||
$(COMMON_PATH)/scorebdp.c \
|
||||
$(COMMON_PATH)/dragdrpp.c \
|
||||
|
@ -81,9 +82,12 @@ common_SRC_FILES += \
|
|||
$(COMMON_PATH)/dbgutil.c \
|
||||
|
||||
|
||||
LOCAL_CFLAGS+=$(local_C_INCLUDES) $(local_DEFINES) -Wall
|
||||
LOCAL_SRC_FILES := $(linux_SRC_FILES) $(local_SRC_FILES) $(common_SRC_FILES)
|
||||
LOCAL_CFLAGS+=$(LOCAL_C_INCLUDES) $(LOCAL_DEFINES)
|
||||
LOCAL_SRC_FILES := $(linux_SRC_FILES) $(LOCAL_SRC_FILES) $(COMMON_SRC_FILES)
|
||||
LOCAL_MODULE := xwjni
|
||||
LOCAL_LDLIBS := -L${SYSROOT}/usr/lib -llog -lz
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
COMMON_SRC_FILES :=
|
||||
COMMON_PATH :=
|
||||
|
|
|
@ -88,6 +88,30 @@ getInt( JNIEnv* env, jobject obj, const char* name )
|
|||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
getInts( JNIEnv* env, void* cobj, jobject jobj, const SetInfo* sis, XP_U16 nSis )
|
||||
{
|
||||
int ii;
|
||||
for ( ii = 0; ii < nSis; ++ii ) {
|
||||
const SetInfo* si = &sis[ii];
|
||||
uint8_t* ptr = ((uint8_t*)cobj) + si->offset;
|
||||
int val = getInt( env, jobj, si->name );
|
||||
switch( si->siz ) {
|
||||
case 4:
|
||||
*(uint32_t*)ptr = val;
|
||||
break;
|
||||
case 2:
|
||||
*(uint16_t*)ptr = val;
|
||||
break;
|
||||
case 1:
|
||||
*ptr = val;
|
||||
break;
|
||||
}
|
||||
/* XP_LOGF( "%s: wrote int %s of size %d with val %d at offset %d", */
|
||||
/* __func__, si->name, si->siz, val, si->offset ); */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setInt( JNIEnv* env, jobject obj, const char* name, int value )
|
||||
{
|
||||
|
@ -99,6 +123,34 @@ setInt( JNIEnv* env, jobject obj, const char* name, int value )
|
|||
deleteLocalRef( env, cls );
|
||||
}
|
||||
|
||||
void
|
||||
setInts( JNIEnv* env, jobject jobj, void* cobj, const SetInfo* sis, XP_U16 nSis )
|
||||
{
|
||||
int ii;
|
||||
for ( ii = 0; ii < nSis; ++ii ) {
|
||||
const SetInfo* si = &sis[ii];
|
||||
uint8_t* ptr = ((uint8_t*)cobj) + si->offset;
|
||||
int val;
|
||||
switch( si->siz ) {
|
||||
case 4:
|
||||
val = *(uint32_t*)ptr;
|
||||
break;
|
||||
case 2:
|
||||
val = *(uint16_t*)ptr;
|
||||
break;
|
||||
case 1:
|
||||
val = *ptr;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
setInt( env, jobj, si->name, val );
|
||||
/* XP_LOGF( "%s: read int %s of size %d with val %d from offset %d", */
|
||||
/* __func__, si->name, si->siz, val, si->offset ); */
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
setBool( JNIEnv* env, jobject obj, const char* name, bool value )
|
||||
{
|
||||
|
@ -114,6 +166,19 @@ setBool( JNIEnv* env, jobject obj, const char* name, bool value )
|
|||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
setBools( JNIEnv* env, jobject jobj, void* cobj, const SetInfo* sis, XP_U16 nSis )
|
||||
{
|
||||
int ii;
|
||||
for ( ii = 0; ii < nSis; ++ii ) {
|
||||
const SetInfo* si = &sis[ii];
|
||||
XP_Bool val = *(XP_Bool*)(((uint8_t*)cobj)+si->offset);
|
||||
setBool( env, jobj, si->name, val );
|
||||
/* XP_LOGF( "%s: read bool %s with val %d from offset %d", __func__, */
|
||||
/* si->name, val, si->offset ); */
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
setString( JNIEnv* env, jobject obj, const char* name, const XP_UCHAR* value )
|
||||
{
|
||||
|
@ -210,6 +275,19 @@ getBool( JNIEnv* env, jobject obj, const char* name )
|
|||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
getBools( JNIEnv* env, void* cobj, jobject jobj, const SetInfo* sis, XP_U16 nSis )
|
||||
{
|
||||
int ii;
|
||||
for ( ii = 0; ii < nSis; ++ii ) {
|
||||
const SetInfo* si = &sis[ii];
|
||||
XP_Bool val = getBool( env, jobj, si->name );
|
||||
*(XP_Bool*)(((uint8_t*)cobj)+si->offset) = val;
|
||||
/* XP_LOGF( "%s: wrote bool %s with val %d at offset %d", __func__, */
|
||||
/* si->name, val, si->offset ); */
|
||||
}
|
||||
}
|
||||
|
||||
jintArray
|
||||
makeIntArray( JNIEnv *env, int siz, const jint* vals )
|
||||
{
|
||||
|
@ -275,13 +353,25 @@ getIntFromArray( JNIEnv* env, jintArray arr, bool del )
|
|||
{
|
||||
jint* ints = (*env)->GetIntArrayElements(env, arr, 0);
|
||||
int result = ints[0];
|
||||
(*env)->ReleaseIntArrayElements( env, arr, ints, 0);
|
||||
(*env)->ReleaseIntArrayElements( env, arr, ints, 0 );
|
||||
if ( del ) {
|
||||
deleteLocalRef( env, arr );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
setIntInArray( JNIEnv* env, jintArray arr, int index, int val )
|
||||
{
|
||||
jint* ints = (*env)->GetIntArrayElements( env, arr, 0 );
|
||||
#ifdef DEBUG
|
||||
jsize len = (*env)->GetArrayLength( env, arr );
|
||||
XP_ASSERT( len > index );
|
||||
#endif
|
||||
ints[index] = val;
|
||||
(*env)->ReleaseIntArrayElements( env, arr, ints, 0 );
|
||||
}
|
||||
|
||||
jobjectArray
|
||||
makeStringArray( JNIEnv *env, int siz, const XP_UCHAR** vals )
|
||||
{
|
||||
|
|
|
@ -33,10 +33,28 @@
|
|||
void and_send_on_close( XWStreamCtxt* stream, void* closure );
|
||||
XWStreamCtxt* and_empty_stream( MPFORMAL AndGlobals* globals );
|
||||
|
||||
typedef struct _SetInfo {
|
||||
const char* name;
|
||||
int offset;
|
||||
int siz;
|
||||
} SetInfo;
|
||||
#define ARR_MEMBER(obj, fld) { .name = #fld, \
|
||||
.offset = OFFSET_OF(obj, fld), \
|
||||
.siz = sizeof(((obj *)0)->fld) \
|
||||
}
|
||||
|
||||
int getInt( JNIEnv* env, jobject obj, const char* name );
|
||||
void setInt( JNIEnv* env, jobject obj, const char* name, int value );
|
||||
void setInts( JNIEnv* env, jobject jobj, void* cobj,
|
||||
const SetInfo* sis, XP_U16 nSis );
|
||||
void getInts( JNIEnv* env, void* cobj, jobject jobj,
|
||||
const SetInfo* sis, XP_U16 nSis );
|
||||
bool getBool( JNIEnv* env, jobject obj, const char* name );
|
||||
void getBools( JNIEnv* env, void* cobj, jobject jobj,
|
||||
const SetInfo* sis, XP_U16 nSis );
|
||||
bool setBool( JNIEnv* env, jobject obj, const char* name, bool value );
|
||||
void setBools( JNIEnv* env, jobject jobj, void* cobj,
|
||||
const SetInfo* sis, XP_U16 nSis );
|
||||
bool setString( JNIEnv* env, jobject obj, const char* name, const XP_UCHAR* value );
|
||||
void getString( JNIEnv* env, jobject jlp, const char* name, XP_UCHAR* buf,
|
||||
int bufLen );
|
||||
|
@ -48,6 +66,7 @@ bool getObject( JNIEnv* env, jobject obj, const char* name, const char* sig,
|
|||
|
||||
jintArray makeIntArray( JNIEnv *env, int size, const jint* vals );
|
||||
int getIntFromArray( JNIEnv* env, jintArray arr, bool del );
|
||||
void setIntInArray( JNIEnv* env, jintArray arr, int index, int val );
|
||||
|
||||
jbyteArray makeByteArray( JNIEnv* env, int size, const jbyte* vals );
|
||||
|
||||
|
|
|
@ -423,31 +423,34 @@ and_draw_trayBegin( DrawCtx* dctx, const XP_Rect* rect, XP_U16 owner,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
static XP_Bool
|
||||
and_draw_drawTile( DrawCtx* dctx, const XP_Rect* rect, const XP_UCHAR* text,
|
||||
const XP_Bitmaps* bitmaps, XP_U16 val, CellFlags flags )
|
||||
{
|
||||
XP_Bool result;
|
||||
DRAW_CBK_HEADER( "drawTile",
|
||||
"(Landroid/graphics/Rect;Ljava/lang/String;II)V" );
|
||||
"(Landroid/graphics/Rect;Ljava/lang/String;II)Z" );
|
||||
jobject jrect = makeJRect( draw, JCACHE_RECT0, rect );
|
||||
jstring jtext = NULL;
|
||||
if ( !!text ) {
|
||||
jtext = (*env)->NewStringUTF( env, text );
|
||||
}
|
||||
|
||||
(*env)->CallVoidMethod( env, draw->jdraw, mid,
|
||||
jrect, jtext, val, flags );
|
||||
result = (*env)->CallBooleanMethod( env, draw->jdraw, mid,
|
||||
jrect, jtext, val, flags );
|
||||
|
||||
deleteLocalRef( env, jtext );
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
static XP_Bool
|
||||
and_draw_drawTileMidDrag( DrawCtx* dctx, const XP_Rect* rect,
|
||||
const XP_UCHAR* text, const XP_Bitmaps* bitmaps,
|
||||
XP_U16 val, XP_U16 owner, CellFlags flags )
|
||||
{
|
||||
XP_Bool result;
|
||||
DRAW_CBK_HEADER( "drawTileMidDrag",
|
||||
"(Landroid/graphics/Rect;Ljava/lang/String;III)V" );
|
||||
"(Landroid/graphics/Rect;Ljava/lang/String;III)Z" );
|
||||
|
||||
jobject jrect = makeJRect( draw, JCACHE_RECT0, rect );
|
||||
jstring jtext = NULL;
|
||||
|
@ -455,21 +458,21 @@ and_draw_drawTileMidDrag( DrawCtx* dctx, const XP_Rect* rect,
|
|||
jtext = (*env)->NewStringUTF( env, text );
|
||||
}
|
||||
|
||||
(*env)->CallVoidMethod( env, draw->jdraw, mid,
|
||||
jrect, jtext, val, owner, flags );
|
||||
result = (*env)->CallBooleanMethod( env, draw->jdraw, mid,
|
||||
jrect, jtext, val, owner, flags );
|
||||
|
||||
deleteLocalRef( env, jtext );
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
static XP_Bool
|
||||
and_draw_drawTileBack( DrawCtx* dctx, const XP_Rect* rect, CellFlags flags )
|
||||
{
|
||||
DRAW_CBK_HEADER( "drawTileBack", "(Landroid/graphics/Rect;I)V" );
|
||||
DRAW_CBK_HEADER( "drawTileBack", "(Landroid/graphics/Rect;I)Z" );
|
||||
|
||||
jobject jrect = makeJRect( draw, JCACHE_RECT0, rect );
|
||||
|
||||
(*env)->CallVoidMethod( env, draw->jdraw, mid,
|
||||
jrect, flags );
|
||||
return (*env)->CallBooleanMethod( env, draw->jdraw, mid, jrect, flags );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -644,21 +647,23 @@ makeDraw( MPFORMAL JNIEnv** envp, jobject jdraw )
|
|||
void
|
||||
destroyDraw( DrawCtx** dctx )
|
||||
{
|
||||
AndDraw* draw = (AndDraw*)*dctx;
|
||||
JNIEnv* env = *draw->env;
|
||||
if ( NULL != draw->jdraw ) {
|
||||
(*env)->DeleteGlobalRef( env, draw->jdraw );
|
||||
}
|
||||
|
||||
int ii;
|
||||
for ( ii = 0; ii < JCACHE_COUNT; ++ii ) {
|
||||
jobject jobj = draw->jCache[ii];
|
||||
if ( !!jobj ) {
|
||||
(*env)->DeleteGlobalRef( env, jobj );
|
||||
if ( !!*dctx ) {
|
||||
AndDraw* draw = (AndDraw*)*dctx;
|
||||
JNIEnv* env = *draw->env;
|
||||
if ( NULL != draw->jdraw ) {
|
||||
(*env)->DeleteGlobalRef( env, draw->jdraw );
|
||||
}
|
||||
}
|
||||
|
||||
XP_FREE( draw->mpool, draw->vtable );
|
||||
XP_FREE( draw->mpool, draw );
|
||||
*dctx = NULL;
|
||||
int ii;
|
||||
for ( ii = 0; ii < JCACHE_COUNT; ++ii ) {
|
||||
jobject jobj = draw->jCache[ii];
|
||||
if ( !!jobj ) {
|
||||
(*env)->DeleteGlobalRef( env, jobj );
|
||||
}
|
||||
}
|
||||
|
||||
XP_FREE( draw->mpool, draw->vtable );
|
||||
XP_FREE( draw->mpool, draw );
|
||||
*dctx = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,47 +39,54 @@
|
|||
#include "jniutlswrapper.h"
|
||||
#include "paths.h"
|
||||
|
||||
static const SetInfo gi_ints[] = {
|
||||
ARR_MEMBER( CurGameInfo, nPlayers )
|
||||
,ARR_MEMBER( CurGameInfo, gameSeconds )
|
||||
,ARR_MEMBER( CurGameInfo, boardSize )
|
||||
,ARR_MEMBER( CurGameInfo, gameID )
|
||||
,ARR_MEMBER( CurGameInfo, dictLang )
|
||||
};
|
||||
|
||||
static const SetInfo gi_bools[] = {
|
||||
ARR_MEMBER( CurGameInfo, hintsNotAllowed )
|
||||
,ARR_MEMBER( CurGameInfo, timerEnabled )
|
||||
,ARR_MEMBER( CurGameInfo, allowPickTiles )
|
||||
,ARR_MEMBER( CurGameInfo, allowHintRect )
|
||||
};
|
||||
|
||||
static CurGameInfo*
|
||||
makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
|
||||
makeGI( MPFORMAL JNIEnv* env, jobject jgi )
|
||||
{
|
||||
CurGameInfo* gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*gi) );
|
||||
XP_UCHAR buf[256]; /* in case needs whole path */
|
||||
|
||||
gi->nPlayers = getInt( env, j_gi, "nPlayers");
|
||||
gi->gameSeconds = getInt( env, j_gi, "gameSeconds");
|
||||
gi->boardSize = getInt( env, j_gi, "boardSize" );
|
||||
getInts( env, (void*)gi, jgi, gi_ints, VSIZE(gi_ints) );
|
||||
getBools( env, (void*)gi, jgi, gi_bools, VSIZE(gi_bools) );
|
||||
|
||||
/* Unlike on other platforms, gi is created without a call to
|
||||
game_makeNewGame, which sets gameID. So check here if it's still unset
|
||||
and if necessary set it -- including back in the java world. */
|
||||
gi->gameID = getInt( env, j_gi, "gameID" );
|
||||
if ( 0 == gi->gameID ) {
|
||||
while ( 0 == gi->gameID ) {
|
||||
gi->gameID = getCurSeconds( env );
|
||||
}
|
||||
setInt( env, j_gi, "gameID", gi->gameID );
|
||||
setInt( env, jgi, "gameID", gi->gameID );
|
||||
}
|
||||
|
||||
gi->dictLang = getInt( env, j_gi, "dictLang" );
|
||||
gi->hintsNotAllowed = getBool( env, j_gi, "hintsNotAllowed" );
|
||||
gi->timerEnabled = getBool( env, j_gi, "timerEnabled" );
|
||||
gi->allowPickTiles = getBool( env, j_gi, "allowPickTiles" );
|
||||
gi->allowHintRect = getBool( env, j_gi, "allowHintRect" );
|
||||
|
||||
gi->phoniesAction =
|
||||
jenumFieldToInt( env, j_gi, "phoniesAction",
|
||||
jenumFieldToInt( env, jgi, "phoniesAction",
|
||||
PKG_PATH("jni/CurGameInfo$XWPhoniesChoice") );
|
||||
gi->serverRole =
|
||||
jenumFieldToInt( env, j_gi, "serverRole",
|
||||
jenumFieldToInt( env, jgi, "serverRole",
|
||||
PKG_PATH("jni/CurGameInfo$DeviceRole"));
|
||||
|
||||
getString( env, j_gi, "dictName", buf, VSIZE(buf) );
|
||||
getString( env, jgi, "dictName", buf, VSIZE(buf) );
|
||||
gi->dictName = copyString( mpool, buf );
|
||||
|
||||
XP_ASSERT( gi->nPlayers <= MAX_NUM_PLAYERS );
|
||||
|
||||
jobject jplayers;
|
||||
if ( getObject( env, j_gi, "players", "[L" PKG_PATH("jni/LocalPlayer") ";",
|
||||
if ( getObject( env, jgi, "players", "[L" PKG_PATH("jni/LocalPlayer") ";",
|
||||
&jplayers ) ) {
|
||||
int ii;
|
||||
for ( ii = 0; ii < gi->nPlayers; ++ii ) {
|
||||
|
@ -114,14 +121,10 @@ static void
|
|||
setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
|
||||
{
|
||||
// set fields
|
||||
setInt( env, jgi, "nPlayers", gi->nPlayers );
|
||||
setInt( env, jgi, "gameSeconds", gi->gameSeconds );
|
||||
setInt( env, jgi, "boardSize", gi->boardSize );
|
||||
setInt( env, jgi, "gameID", gi->gameID );
|
||||
setInt( env, jgi, "dictLang", gi->dictLang );
|
||||
setBool( env, jgi, "hintsNotAllowed", gi->hintsNotAllowed );
|
||||
setBool( env, jgi, "timerEnabled", gi->timerEnabled );
|
||||
setBool( env, jgi, "allowPickTiles", gi->allowPickTiles );
|
||||
|
||||
setInts( env, jgi, (void*)gi, gi_ints, VSIZE(gi_ints) );
|
||||
setBools( env, jgi, (void*)gi, gi_bools, VSIZE(gi_bools) );
|
||||
|
||||
setString( env, jgi, "dictName", gi->dictName );
|
||||
|
||||
intToJenumField( env, jgi, gi->phoniesAction, "phoniesAction",
|
||||
|
@ -155,6 +158,36 @@ setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
|
|||
}
|
||||
} /* setJGI */
|
||||
|
||||
#ifdef COMMON_LAYOUT
|
||||
static const SetInfo bd_ints[] = {
|
||||
ARR_MEMBER( BoardDims, left )
|
||||
,ARR_MEMBER( BoardDims, top )
|
||||
,ARR_MEMBER( BoardDims, width )
|
||||
,ARR_MEMBER( BoardDims, height )
|
||||
,ARR_MEMBER( BoardDims, scoreHt )
|
||||
,ARR_MEMBER( BoardDims, scoreWidth )
|
||||
,ARR_MEMBER( BoardDims, boardWidth )
|
||||
,ARR_MEMBER( BoardDims, boardHt )
|
||||
,ARR_MEMBER( BoardDims, trayTop )
|
||||
,ARR_MEMBER( BoardDims, trayHt )
|
||||
,ARR_MEMBER( BoardDims, cellSize )
|
||||
,ARR_MEMBER( BoardDims, maxCellSize )
|
||||
,ARR_MEMBER( BoardDims, timerWidth )
|
||||
};
|
||||
|
||||
static void
|
||||
dimsJToC( JNIEnv* env, BoardDims* out, jobject jdims )
|
||||
{
|
||||
getInts( env, (void*)out, jdims, bd_ints, VSIZE(bd_ints) );
|
||||
}
|
||||
|
||||
static void
|
||||
dimsCtoJ( JNIEnv* env, jobject jdims, const BoardDims* in )
|
||||
{
|
||||
setInts( env, jdims, (void*)in, bd_ints, VSIZE(bd_ints) );
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
destroyGI( MPFORMAL CurGameInfo** gip )
|
||||
{
|
||||
|
@ -417,7 +450,10 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
|
|||
globals->util = makeUtil( MPPARM(mpool) &state->env, j_util, gi,
|
||||
globals );
|
||||
globals->jniutil = makeJNIUtil( MPPARM(mpool) &state->env, jniu );
|
||||
DrawCtx* dctx = makeDraw( MPPARM(mpool) &state->env, j_draw );
|
||||
DrawCtx* dctx = NULL;
|
||||
if ( !!j_draw ) {
|
||||
dctx = makeDraw( MPPARM(mpool) &state->env, j_draw );
|
||||
}
|
||||
globals->dctx = dctx;
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) &state->env, j_procs );
|
||||
CommonPrefs cp;
|
||||
|
@ -486,7 +522,9 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
|
|||
globals->jniutil = makeJNIUtil( MPPARM(mpool) &state->env, jniu );
|
||||
makeDicts( MPPARM(mpool) env, globals->jniutil, &dict, &dicts, jdictNames,
|
||||
jdicts, jpaths, jlang );
|
||||
globals->dctx = makeDraw( MPPARM(mpool) &state->env, jdraw );
|
||||
if ( !!jdraw ) {
|
||||
globals->dctx = makeDraw( MPPARM(mpool) &state->env, jdraw );
|
||||
}
|
||||
globals->xportProcs = makeXportProcs( MPPARM(mpool) &state->env, jprocs );
|
||||
|
||||
XWStreamCtxt* stream = streamFromJStream( MPPARM(mpool) env,
|
||||
|
@ -560,6 +598,21 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveSucceeded
|
|||
XWJNI_END();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setDraw
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject jdraw )
|
||||
{
|
||||
XWJNI_START_GLOBALS();
|
||||
|
||||
DrawCtx* newDraw = makeDraw( MPPARM(mpool) &state->env, jdraw );
|
||||
board_setDraw( state->game.board, newDraw );
|
||||
|
||||
destroyDraw( &globals->dctx );
|
||||
globals->dctx = newDraw;
|
||||
|
||||
XWJNI_END();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1invalAll
|
||||
( JNIEnv *env, jclass C, jint gamePtr )
|
||||
|
@ -580,6 +633,45 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1draw
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef COMMON_LAYOUT
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1figureLayout
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject jgi, jint left, jint top,
|
||||
jint width, jint height, jint scorePct, jint trayPct, jint scoreWidth,
|
||||
jint fontWidth, jint fontHt, jboolean squareTiles, jobject jdims )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XWJNI_START();
|
||||
CurGameInfo* gi = makeGI( MPPARM(mpool) env, jgi );
|
||||
|
||||
BoardDims dims;
|
||||
board_figureLayout( state->game.board, gi, left, top, width, height,
|
||||
scorePct, trayPct, scoreWidth,
|
||||
fontWidth, fontHt, squareTiles,
|
||||
((!!jdims) ? &dims : NULL) );
|
||||
|
||||
destroyGI( MPPARM(mpool) &gi );
|
||||
|
||||
if ( !!jdims ) {
|
||||
dimsCtoJ( env, jdims, &dims );
|
||||
}
|
||||
XWJNI_END();
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1applyLayout
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject jdims )
|
||||
{
|
||||
XWJNI_START();
|
||||
BoardDims dims;
|
||||
dimsJToC( env, &dims, jdims );
|
||||
board_applyLayout( state->game.board, &dims );
|
||||
XWJNI_END();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setPos
|
||||
(JNIEnv *env, jclass C, jint gamePtr, jint left, jint top, jint width,
|
||||
|
@ -591,20 +683,6 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setPos
|
|||
XWJNI_END();
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1zoom
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jint zoomBy, jbooleanArray jCanZoom )
|
||||
{
|
||||
jboolean result;
|
||||
XWJNI_START();
|
||||
XP_Bool canInOut[2];
|
||||
result = board_zoom( state->game.board, zoomBy, canInOut );
|
||||
jboolean canZoom[2] = { canInOut[0], canInOut[1] };
|
||||
setBoolArray( env, jCanZoom, VSIZE(canZoom), canZoom );
|
||||
XWJNI_END();
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setScoreboardLoc
|
||||
( JNIEnv *env, jclass C, jint gamePtr, jint left, jint top,
|
||||
|
@ -639,6 +717,46 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setTrayLoc
|
|||
minDividerWidth );
|
||||
XWJNI_END();
|
||||
}
|
||||
#endif
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1zoom
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jint zoomBy, jbooleanArray jCanZoom )
|
||||
{
|
||||
jboolean result;
|
||||
XWJNI_START();
|
||||
XP_Bool canInOut[2];
|
||||
result = board_zoom( state->game.board, zoomBy, canInOut );
|
||||
jboolean canZoom[2] = { canInOut[0], canInOut[1] };
|
||||
setBoolArray( env, jCanZoom, VSIZE(canZoom), canZoom );
|
||||
XWJNI_END();
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef XWFEATURE_ACTIVERECT
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1getActiveRect
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject jrect, jintArray dims )
|
||||
{
|
||||
jboolean result;
|
||||
XWJNI_START();
|
||||
XP_Rect rect;
|
||||
XP_U16 nCols, nRows;
|
||||
result = board_getActiveRect( state->game.board, &rect, &nCols, &nRows );
|
||||
if ( result ) {
|
||||
setInt( env, jrect, "left", rect.left );
|
||||
setInt( env, jrect, "top", rect.top );
|
||||
setInt( env, jrect, "right", rect.left + rect.width );
|
||||
setInt( env, jrect, "bottom", rect.top + rect.height );
|
||||
if ( !!dims ) {
|
||||
setIntInArray( env, dims, 0, nCols );
|
||||
setIntInArray( env, dims, 1, nRows );
|
||||
}
|
||||
}
|
||||
XWJNI_END();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenDown
|
||||
|
@ -1281,6 +1399,21 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1getGi
|
|||
XWJNI_END();
|
||||
}
|
||||
|
||||
static const SetInfo gsi_ints[] = {
|
||||
ARR_MEMBER( GameStateInfo, visTileCount ),
|
||||
ARR_MEMBER( GameStateInfo, trayVisState ),
|
||||
};
|
||||
static const SetInfo gsi_bools[] = {
|
||||
ARR_MEMBER( GameStateInfo,canHint ),
|
||||
ARR_MEMBER( GameStateInfo, canRedo ),
|
||||
ARR_MEMBER( GameStateInfo, inTrade ),
|
||||
ARR_MEMBER( GameStateInfo, tradeTilesSelected ),
|
||||
ARR_MEMBER( GameStateInfo, canChat ),
|
||||
ARR_MEMBER( GameStateInfo, canShuffle ),
|
||||
ARR_MEMBER( GameStateInfo, curTurnSelected ),
|
||||
ARR_MEMBER( GameStateInfo, canHideRack ),
|
||||
};
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_game_1getState
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject jgsi )
|
||||
|
@ -1289,15 +1422,8 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1getState
|
|||
GameStateInfo info;
|
||||
game_getState( &state->game, &info );
|
||||
|
||||
setInt( env, jgsi, "visTileCount", info.visTileCount );
|
||||
setInt( env, jgsi, "trayVisState", info.trayVisState );
|
||||
setBool( env, jgsi, "canHint", info.canHint );
|
||||
setBool( env, jgsi, "canRedo", info.canRedo);
|
||||
setBool( env, jgsi, "inTrade", info.inTrade );
|
||||
setBool( env, jgsi, "tradeTilesSelected", info.tradeTilesSelected );
|
||||
setBool( env, jgsi, "canChat", info.canChat );
|
||||
setBool( env, jgsi, "canShuffle", info.canShuffle );
|
||||
setBool( env, jgsi, "curTurnSelected", info.curTurnSelected );
|
||||
setInts( env, jgsi, (void*)&info, gsi_ints, VSIZE(gsi_ints) );
|
||||
setBools( env, jgsi, (void*)&info, gsi_bools, VSIZE(gsi_bools) );
|
||||
|
||||
XWJNI_END();
|
||||
}
|
||||
|
|
|
@ -11,4 +11,4 @@
|
|||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=Google Inc.:Google APIs:11
|
||||
target=Google Inc.:Google APIs:14
|
||||
|
|
BIN
xwords4/android/XWords4/res/drawable-hdpi/content_edit.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3 KiB |
BIN
xwords4/android/XWords4/res/drawable-mdpi/content_edit.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.9 KiB |
BIN
xwords4/android/XWords4/res/drawable-xhdpi/content_edit.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 3.1 KiB |
|
@ -5,29 +5,6 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
>
|
||||
<LinearLayout android:id="@+id/empty_games_list"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
>
|
||||
<TextView android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/empty_games_list"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:background="#FF202020"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
/>
|
||||
<TextView android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/empty_games_list2"
|
||||
android:background="#FF202020"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<ExpandableListView android:id="@id/android:list"
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -35,29 +12,4 @@
|
|||
android:layout_weight="1"
|
||||
android:drawSelectorOnTop="false"
|
||||
/>
|
||||
<TextView android:id="@+id/empty_list_msg"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
android:text="@string/empty_list_msg"
|
||||
/>
|
||||
|
||||
<LinearLayout android:id="@+id/new_buttons"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
>
|
||||
<Button android:id="@+id/new_game"
|
||||
android:text="@string/button_new_game"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
<Button android:id="@+id/new_group"
|
||||
android:text="@string/button_new_group"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- -*- compile-command: "cd ../../; ant install"; -*- -->
|
||||
|
||||
|
||||
<!-- top-level layout is hozontal, with an image and another layout -->
|
||||
<org.eehouse.android.xw4.GameListItem
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
@ -12,7 +11,6 @@
|
|||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
android:background="@android:drawable/list_selector_background"
|
||||
android:paddingLeft="12dp"
|
||||
>
|
||||
|
||||
<TextView android:id="@+id/view_unloaded"
|
||||
|
@ -36,11 +34,18 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_weight="0"
|
||||
android:paddingLeft="8dip"
|
||||
android:paddingRight="8dip"
|
||||
/>
|
||||
|
||||
<ImageView android:id="@+id/thumbnail"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:padding="2dip"
|
||||
android:background="#FF7F7F7F"
|
||||
/>
|
||||
|
||||
<!-- this layout is vertical, holds everything but the status
|
||||
icon[s] (plural later) -->
|
||||
<LinearLayout android:orientation="vertical"
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
>
|
||||
<Button android:id="@+id/newgame_invite"
|
||||
<Button android:id="@+id/newgame_invite_net"
|
||||
android:text="@string/newgame_invite"
|
||||
style="@style/spaced_buttons"
|
||||
/>
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
android:title="@string/board_menu_game_left" />
|
||||
<item android:id="@+id/board_menu_game_history"
|
||||
android:title="@string/board_menu_game_history" />
|
||||
<item android:id="@+id/board_menu_game_final"
|
||||
<item android:id="@+id/board_menu_game_resign"
|
||||
android:title="@string/board_menu_game_final" />
|
||||
<item android:id="@+id/board_menu_game_resend"
|
||||
android:title="@string/board_menu_game_resend" />
|
||||
|
|
|
@ -4,16 +4,37 @@
|
|||
|
||||
<group android:id="@+id/group_done">
|
||||
<!-- title set in BoardActivity -->
|
||||
<item android:id="@+id/board_menu_invite"
|
||||
android:title="@string/board_menu_invite"
|
||||
android:showAsAction="ifRoom"
|
||||
android:icon="@drawable/send__gen"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/board_menu_done"
|
||||
android:alphabeticShortcut="D"
|
||||
android:showAsAction="ifRoom"
|
||||
android:icon="@drawable/save__gen"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/board_menu_trade"
|
||||
android:title="@string/board_menu_trade"
|
||||
android:alphabeticShortcut="T"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
</group>
|
||||
|
||||
<item android:id="@+id/board_menu_trade_cancel"
|
||||
android:title="@string/button_trade_cancel"
|
||||
android:showAsAction="ifRoom"
|
||||
android:icon="@drawable/back__gen"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/board_menu_trade_commit"
|
||||
android:title="@string/button_trade_commit"
|
||||
android:showAsAction="ifRoom"
|
||||
android:icon="@drawable/save__gen"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/board_menu_undo_last"
|
||||
android:title="@string/board_menu_undo_last"
|
||||
android:alphabeticShortcut="U"
|
||||
|
@ -22,8 +43,7 @@
|
|||
<item android:id="@+id/board_menu_tray"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/board_submenu_game"
|
||||
android:title="@string/board_submenu_game">
|
||||
<item android:title="@string/board_submenu_game">
|
||||
<menu>
|
||||
<item android:id="@+id/board_menu_game_counts"
|
||||
android:title="@string/board_menu_game_counts" />
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/dicts_item_move"
|
||||
android:title="@string/dicts_item_move"
|
||||
/>
|
||||
<item android:id="@+id/dicts_item_select"
|
||||
android:title="@string/dicts_item_select"
|
||||
/>
|
||||
</menu>
|
25
xwords4/android/XWords4/res/menu/dicts_menu.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:id="@+id/dicts_download"
|
||||
android:title="@string/download_dicts"
|
||||
android:icon="@drawable/download__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/dicts_delete"
|
||||
android:title="@string/list_item_delete"
|
||||
android:icon="@drawable/content_discard__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/dicts_move"
|
||||
android:title="@string/dicts_item_move"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/dicts_select"
|
||||
android:title="@string/dicts_item_select"
|
||||
/>
|
||||
|
||||
</menu>
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/list_group_default"
|
||||
android:title="@string/list_group_default"
|
||||
/>
|
||||
<item android:id="@+id/list_group_rename"
|
||||
android:title="@string/list_group_rename"
|
||||
/>
|
||||
<item android:id="@+id/list_group_moveup"
|
||||
android:title="@string/list_group_moveup"
|
||||
/>
|
||||
<item android:id="@+id/list_group_movedown"
|
||||
android:title="@string/list_group_movedown"
|
||||
/>
|
||||
<item android:id="@+id/list_group_delete"
|
||||
android:title="@string/list_group_delete"
|
||||
/>
|
||||
</menu>
|
|
@ -1,40 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/list_item_config"
|
||||
android:title="@string/list_item_config"
|
||||
/>
|
||||
<item android:id="@+id/list_item_rename"
|
||||
android:title="@string/list_item_rename"
|
||||
/>
|
||||
<item android:id="@+id/list_item_move"
|
||||
android:title="@string/list_item_move"
|
||||
/>
|
||||
<item android:id="@+id/list_item_delete"
|
||||
android:title="@string/list_item_delete"
|
||||
/>
|
||||
<item android:id="@+id/list_item_reset"
|
||||
android:title="@string/list_item_reset"
|
||||
/>
|
||||
<item android:id="@+id/list_item_new_from"
|
||||
android:title="@string/list_item_new_from"
|
||||
/>
|
||||
<item android:id="@+id/list_item_copy"
|
||||
android:title="@string/list_item_copy"
|
||||
/>
|
||||
<!-- <item android:id="@+id/list_item_hide" -->
|
||||
<!-- android:title="@string/list_item_hide" -->
|
||||
<!-- /> -->
|
||||
<!-- <item android:id="@+id/list_item_move_up" -->
|
||||
<!-- android:title="@string/list_item_move_up" -->
|
||||
<!-- /> -->
|
||||
<!-- <item android:id="@+id/list_item_move_down" -->
|
||||
<!-- android:title="@string/list_item_move_down" -->
|
||||
<!-- /> -->
|
||||
<!-- <item android:id="@+id/list_item_move_to_top" -->
|
||||
<!-- android:title="@string/list_item_move_to_top" -->
|
||||
<!-- /> -->
|
||||
<!-- <item android:id="@+id/list_item_move_to_bottom" -->
|
||||
<!-- android:title="@string/list_item_move_to_bottom" -->
|
||||
<!-- /> -->
|
||||
</menu>
|
|
@ -1,52 +1,103 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/gamel_menu_newgame"
|
||||
<item android:id="@+id/games_menu_newgame"
|
||||
android:title="@string/button_new_game"
|
||||
android:icon="@drawable/content_new"
|
||||
android:icon="@drawable/content_new__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_newgroup"
|
||||
<item android:id="@+id/games_menu_newgroup"
|
||||
android:title="@string/button_new_group"
|
||||
android:icon="@android:drawable/ic_menu_add"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_delete"
|
||||
android:title="@string/list_item_delete"
|
||||
android:icon="@drawable/ic_action_delete"
|
||||
android:icon="@drawable/new_group__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_prefs"
|
||||
<item android:id="@+id/games_menu_prefs"
|
||||
android:title="@string/menu_prefs"
|
||||
android:icon="@android:drawable/ic_menu_preferences"
|
||||
android:icon="@drawable/prefs__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_dicts"
|
||||
<item android:id="@+id/games_menu_dicts"
|
||||
android:title="@string/gamel_menu_dicts"
|
||||
android:icon="@drawable/dicticon"
|
||||
android:icon="@drawable/dict__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_about"
|
||||
<item android:id="@+id/games_menu_email"
|
||||
android:title="@string/board_menu_file_email"
|
||||
android:icon="@drawable/email__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_menu_about"
|
||||
android:title="@string/board_menu_file_about"
|
||||
android:icon="@android:drawable/ic_menu_info_details"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/gamel_menu_email"
|
||||
android:title="@string/board_menu_file_email"
|
||||
android:icon="@android:drawable/ic_menu_send"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/gamel_menu_checkmoves"
|
||||
<item android:id="@+id/games_menu_checkmoves"
|
||||
android:title="@string/gamel_menu_checkmoves"
|
||||
android:icon="@drawable/stat_notify_sync"
|
||||
/>
|
||||
|
||||
<!-- Game items -->
|
||||
<item android:id="@+id/games_game_delete"
|
||||
android:title="@string/list_item_delete"
|
||||
android:icon="@drawable/content_discard__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_game_config"
|
||||
android:title="@string/list_item_config"
|
||||
android:icon="@drawable/content_edit"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_game_move"
|
||||
android:title="@string/list_item_move"
|
||||
android:icon="@drawable/relabel__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_game_reset"
|
||||
android:title="@string/list_item_reset"
|
||||
android:icon="@drawable/reset__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_game_new_from"
|
||||
android:title="@string/list_item_new_from"
|
||||
/>
|
||||
<item android:id="@+id/games_game_rename"
|
||||
android:title="@string/list_item_rename"
|
||||
/>
|
||||
<item android:id="@+id/games_game_copy"
|
||||
android:title="@string/list_item_copy"
|
||||
/>
|
||||
|
||||
<!-- Group items -->
|
||||
<item android:id="@+id/games_group_moveup"
|
||||
android:title="@string/list_group_moveup"
|
||||
android:icon="@drawable/up__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_group_movedown"
|
||||
android:title="@string/list_group_movedown"
|
||||
android:icon="@drawable/down__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_group_delete"
|
||||
android:title="@string/list_group_delete"
|
||||
android:icon="@drawable/content_discard__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_group_default"
|
||||
android:title="@string/list_group_default"
|
||||
/>
|
||||
<item android:id="@+id/games_group_rename"
|
||||
android:title="@string/list_group_rename"
|
||||
/>
|
||||
|
||||
<!-- Debug only menuitems -->
|
||||
<item android:id="@+id/gamel_menu_checkupdates"
|
||||
<item android:id="@+id/games_menu_checkupdates"
|
||||
android:title="@string/gamel_menu_checkupdates"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_storedb"
|
||||
<item android:id="@+id/games_menu_storedb"
|
||||
android:title="@string/gamel_menu_storedb"
|
||||
/>
|
||||
<item android:id="@+id/gamel_menu_loaddb"
|
||||
<item android:id="@+id/games_menu_loaddb"
|
||||
android:title="@string/gamel_menu_loaddb"
|
||||
/>
|
||||
|
||||
<!-- ic_menu_archive.png -->
|
||||
</menu>
|
||||
|
|
|
@ -5,26 +5,24 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<b>Crosswords 4.4 beta 69 release</b>
|
||||
<b>Crosswords 4.4 beta 72 release</b>
|
||||
|
||||
<p>This release features a major upgrade to how the app communicates
|
||||
with the relay, in essence switching from each game communicating
|
||||
individually (and only when open) to the app communicating on behalf
|
||||
of all games. You should notice only that moves are transmitted
|
||||
more reliably. But this being new code you may also notice bugs.
|
||||
If you don't <a href="mailto:xwords@eehouse.org">tell me about
|
||||
them</a> they will not get fixed.
|
||||
</p>
|
||||
<p>This release is for the new x86-processor-based Android devices
|
||||
just coming out. Otherwise identical to beta 71, it adds support for
|
||||
x86 processors to existing support for ARM (which has been
|
||||
99.9% of the market until now.)</p>
|
||||
|
||||
<p>Thanks to Brendan Le Foll for the patches!</p>
|
||||
|
||||
<h3>New with this release</h3>
|
||||
<ul>
|
||||
<li>Fix relay registration problem (Thanks DS!)</li>
|
||||
<li>Show Turn done/Pass in actionbar where possible</li>
|
||||
<li>Add support for x86 processors.
|
||||
</ul>
|
||||
|
||||
<h3>Next up</h3>
|
||||
<ul>
|
||||
<li>Take advantage of newer Android UI features, e.g. Action Bar</li>
|
||||
<li>Add thumbnail of board to main screen</li>
|
||||
<li>Use Actionbar and select/act pattern on more screens</li>
|
||||
<li>Offer "Rematch" when game's over</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -59,9 +59,6 @@
|
|||
<string name="board_menu_game_resend">Reenvia els missatges</string>
|
||||
<string name="board_menu_file_about">Quant al Crosswords</string>
|
||||
|
||||
<string name="gamel_menu_delete_all">Suprimeix-les totes</string>
|
||||
<!-- <string name="gamel_menu_view_hidden">Partides amagades</string> -->
|
||||
|
||||
<!-- returned by util_getUserString -->
|
||||
<string name="strd_robot_traded">El robot ha canviat %d fitxes en aquest torn.</string>
|
||||
<string name="str_robot_moved">El robot ha fet aquesta jugada:</string>
|
||||
|
|
|
@ -58,9 +58,6 @@
|
|||
<string name="board_menu_game_resend">Přeposlat zprávy</string>
|
||||
<string name="board_menu_file_about">O Crosswords</string>
|
||||
|
||||
<string name="gamel_menu_delete_all">Vymazat vše</string>
|
||||
<!-- <string name="gamel_menu_view_hidden">Hidden games</string> -->
|
||||
|
||||
<!-- returned by util_getUserString -->
|
||||
<string name="strd_robot_traded">Robot v tomto tahu vyměnil %d kamenů.</string>
|
||||
<string name="str_robot_moved">Robot provedl tento tah:</string>
|
||||
|
|
|
@ -13,15 +13,6 @@
|
|||
# This is the first screen you see when you launch Crosswords
|
||||
############################################################
|
||||
-->
|
||||
<!-- These two messages appear at the top of the list of games
|
||||
(unless the hide_intro preferences checkbox is checked.)-->
|
||||
<string name="empty_games_list">Use o botão abaixo para criar um novo
|
||||
jogo. Selecione um jogo existente para continuá-lo ou dê um toque
|
||||
longo para outras opções.</string>
|
||||
<!-- -->
|
||||
<string name="empty_games_list2">Você pode esconder essa mensagem
|
||||
e os botões abaixo na seção Aparência das Configurações (acessada
|
||||
através do botão menu do seu dispositivo.)</string>
|
||||
|
||||
<!-- Text of button at bottom of main games-list screen and of
|
||||
menuitem in main games-list screen's menu. (The botton can
|
||||
|
@ -29,12 +20,6 @@
|
|||
<string name="button_new_game">Novo jogo</string>
|
||||
<string name="button_new_group">Novo grupo</string>
|
||||
|
||||
<!-- When the game list is empty and the above messages and button
|
||||
are hidden via preferences, this text is shown -->
|
||||
<string name="empty_list_msg">Use a tecla menu para adicionar um
|
||||
jogo.</string>
|
||||
|
||||
|
||||
<!-- Used to format game name plus some other information as the
|
||||
one-line summary for each game in the main screen. The name
|
||||
of the game is substituted for %1$s. Something else
|
||||
|
@ -122,9 +107,6 @@
|
|||
<string name="no_games_to_refresh">Nenhum jogo encontrado que conecta
|
||||
pelo servidor.</string>
|
||||
|
||||
<!-- Deletes all games on the device (after confirmation) -->
|
||||
<string name="gamel_menu_delete_all">Excluir todos</string>
|
||||
|
||||
<!-- Brings up "About Crosswords" dialog -->
|
||||
<string name="board_menu_file_about">Sobre Crosswords</string>
|
||||
|
||||
|
@ -175,11 +157,6 @@
|
|||
list_item_rename) -->
|
||||
<string name="rename_label">Mudar o nome desse jogo para:</string>
|
||||
|
||||
<!-- Text of confirmation dialog posted when list_item_delete menu is
|
||||
selected -->
|
||||
<string name="confirm_delete">Você tem certeza que quer excluir
|
||||
esse jogo?</string>
|
||||
|
||||
<!-- Text of confirmation dialog posted when list_item_reset menu
|
||||
is selected -->
|
||||
<string name="confirm_reset">Você tem certeza que quer reiniciar
|
||||
|
@ -254,9 +231,9 @@
|
|||
wordlist delete confiration dialog in the case where the
|
||||
wordlist to be deleted is the last in its language. The name
|
||||
of the language is substituted for %s. -->
|
||||
<string name="confirm_deleteonly_dictf">\u0020É a única lista de
|
||||
palavras em %s instalada. Um ou mais jogos não poderão ser abertos
|
||||
sem ela.</string>
|
||||
<!-- <string name="confirm_deleteonly_dictf">\u0020É a única lista de -->
|
||||
<!-- palavras em %s instalada. Um ou mais jogos não poderão ser abertos -->
|
||||
<!-- sem ela.</string> -->
|
||||
<!-- Additional text appended to text confirm_delete_dictf in the
|
||||
wordlist delete confiration dialog in the case where the
|
||||
wordlist to be deleted is NOT the last in its language. The
|
||||
|
@ -275,9 +252,9 @@
|
|||
<!-- Used as the text fo the confirming/querying dialog that goes
|
||||
up when the dicts_item_select menuitem is chosen. The
|
||||
possible answers are the three button text strings below. -->
|
||||
<string name="set_default_messagef">Para que jogadores essa lista
|
||||
de palavras deve ser a padrão para novos jogos? (o idioma %s será
|
||||
padrão para ambos.)</string>
|
||||
<!-- <string name="set_default_messagef">Para que jogadores essa lista -->
|
||||
<!-- de palavras deve ser a padrão para novos jogos? (o idioma %s será -->
|
||||
<!-- padrão para ambos.)</string> -->
|
||||
|
||||
<!-- These three strings are the text for three buttons giving
|
||||
choices in respose to the dialog launched in response to the
|
||||
|
@ -931,14 +908,6 @@
|
|||
etc. -->
|
||||
<string name="game_summary_field_state">Estado do jogo</string>
|
||||
|
||||
<!-- The main screen, by default, has a "add game" button and some
|
||||
text at the top that take up space and are unnecessary for
|
||||
experienced users. This checkbox hides them. -->
|
||||
<string name="hide_intro">Esconder dicas da tela principal</string>
|
||||
<!-- clarification of above -->
|
||||
<string name="hide_intro_summary">São úteis somente quando você
|
||||
está começando...</string>
|
||||
|
||||
<!-- Checkbox that when set prevents showing a title bar in the
|
||||
game board window to save space -->
|
||||
<string name="hide_title">Esconder barra de título</string>
|
||||
|
@ -2156,7 +2125,6 @@
|
|||
lista de palavras?</string>
|
||||
<string name="button_decline">Recusar</string>
|
||||
|
||||
<string name="downloadingf">Baixando %s...</string>
|
||||
<string name="download_done">Download concluído</string>
|
||||
<string name="download_failed">Download falhou</string>
|
||||
|
||||
|
@ -2184,9 +2152,6 @@
|
|||
<string name="rename_group_label">Mudar o nome desse grupo para:</string>
|
||||
<string name="game_name_group_title">Nomear grupo</string>
|
||||
|
||||
<string name="cannot_delete_default_group">O grupo para novos jogos
|
||||
não pode ser apagado."</string>
|
||||
|
||||
<string name="no_move_onegroup">Não é possível mover até que exista
|
||||
mais de um grupo.</string>
|
||||
<string name="group_namef">%1$s (%2$d jogos)</string>
|
||||
|
@ -2199,8 +2164,6 @@
|
|||
<string name="square_tiles">Peças quadradas</string>
|
||||
<string name="square_tiles_summary">Mesmo se puderem ser mais altas</string>
|
||||
|
||||
<string name="change_groupf">Mover jogo %s</string>
|
||||
|
||||
<string name="show_wordlist_browser">Listas de palavras</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -57,9 +57,6 @@
|
|||
<string name="board_menu_game_resend">Preposlať správy</string>
|
||||
<string name="board_menu_file_about">O Crosswords</string>
|
||||
|
||||
<string name="gamel_menu_delete_all">Vymazať všetko</string>
|
||||
<!-- <string name="gamel_menu_view_hidden">Hidden games</string> -->
|
||||
|
||||
<!-- returned by util_getUserString -->
|
||||
<string name="strd_robot_traded">Robot v tomto ťahu vymenil %d kameňov.</string>
|
||||
<string name="str_robot_moved">Robot uskutočnil tento ťah:</string>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<string name="app_version">4.4 beta 69</string>
|
||||
<string name="app_version">4.4 beta 72</string>
|
||||
</resources>
|
||||
|
|
|
@ -56,8 +56,10 @@
|
|||
<string name="key_notify_sound">key_notify_sound</string>
|
||||
<string name="key_notify_vibrate">key_notify_vibrate</string>
|
||||
<string name="key_enable_sms">key_enable_sms</string>
|
||||
<string name="key_hide_intro">key_hide_intro</string>
|
||||
<string name="key_keep_screenon">key_keep_screenon</string>
|
||||
<string name="key_thumbsize">key_thumbsize2</string>
|
||||
<string name="key_thumb_enabled">key_thumb_disabled</string>
|
||||
|
||||
<string name="key_summary_field">key_summary_field</string>
|
||||
<string name="key_default_loc">key_default_loc</string>
|
||||
|
||||
|
@ -80,6 +82,8 @@
|
|||
<string name="key_udp_interval">key_udp_interval</string>
|
||||
|
||||
<string name="key_notagain_sync">key_notagain_sync</string>
|
||||
<string name="key_notagain_newselect">key_notagain_newselect</string>
|
||||
<string name="key_notagain_backclears">key_notagain_backclears</string>
|
||||
<string name="key_notagain_chat">key_notagain_chat</string>
|
||||
<string name="key_notagain_relay">key_notagain_relay</string>
|
||||
<string name="key_notagain_hintprev">key_notagain_hintprev</string>
|
||||
|
@ -102,6 +106,7 @@
|
|||
<string name="key_na_browseall">key_na_browseall</string>
|
||||
<string name="key_na_values">key_na_values</string>
|
||||
<string name="key_enable_debug">key_enable_debug</string>
|
||||
<string name="key_enable_dup_invite">key_enable_dup_invite</string>
|
||||
<string name="key_download_path">key_download_path</string>
|
||||
|
||||
<!-- Nor is my email address -->
|
||||
|
@ -109,10 +114,12 @@
|
|||
|
||||
<!-- other -->
|
||||
<string name="default_host">eehouse.org</string>
|
||||
|
||||
<string name="xwords_nfc_mime">application/org.eehouse.android.xw4</string>
|
||||
<string name="invite_host">eehouse.org</string>
|
||||
<string name="invite_prefix">/and/</string>
|
||||
<string name="invite_mime">application/x-xwordsinvite</string>
|
||||
<string name="game_summary_field_rowid">rowid</string>
|
||||
<string name="game_summary_field_gameid">gameid</string>
|
||||
<!--string name="invite_mime">text/plain</string-->
|
||||
|
||||
<string name="dict_url">http://eehouse.org/and_wordlists</string>
|
||||
|
@ -126,12 +133,26 @@
|
|||
<string name="redir_host">Invite redirect host</string>
|
||||
<string name="dict_host">Wordlist download URL</string>
|
||||
<string name="logging_on">Enable logging</string>
|
||||
<string name="logging_on_summary">(release builds only)</string>
|
||||
<string name="debug_features">Enable debug features</string>
|
||||
<string name="debug_features_summary">Menuitems etc. (release builds
|
||||
only)</string>
|
||||
|
||||
<string name="git_rev_title">Source version id</string>
|
||||
<string name="relay_port">Relay game port</string>
|
||||
<string name="proxy_port">Relay device port</string>
|
||||
<string name="name_dict_fmt">%1$s/%2$s</string>
|
||||
<string name="gamel_menu_storedb">Write DB to SD card</string>
|
||||
<string name="gamel_menu_loaddb">Load DB from SD card</string>
|
||||
<string name="enable_dupes_title">Accept duplicate invites</string>
|
||||
<string name="enable_dupes_summary">Accept invitations more than once</string>
|
||||
|
||||
|
||||
<string name="game_thumb_half">1/2</string>
|
||||
<string name="game_thumb_third">1/3</string>
|
||||
<string name="game_thumb_quarter">1/4</string>
|
||||
<string name="game_thumb_fifth">1/5</string>
|
||||
<string name="game_thumb_sixth">1/6</string>
|
||||
|
||||
<!--string name="dict_url">http://10.0.2.2/~eehouse/and_dicts</string-->
|
||||
|
||||
|
@ -238,7 +259,7 @@
|
|||
<item>http://dictionary.com/browse/%2$s</item> -->
|
||||
<!-- -->
|
||||
<item>TheFreeDictionary.com</item>
|
||||
<item>:en:es:</item>
|
||||
<item>:en:es:de:</item>
|
||||
<item>http://%1$s.thefreedictionary.com/_/dict.aspx?word=%2$s</item>
|
||||
<!-- -->
|
||||
<item>Larousse.com</item>
|
||||
|
@ -279,4 +300,12 @@
|
|||
<item>@string/confirm_sms_willpay</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="game_thumb_values">
|
||||
<item>@string/game_thumb_half</item>
|
||||
<item>@string/game_thumb_third</item>
|
||||
<item>@string/game_thumb_quarter</item>
|
||||
<item>@string/game_thumb_fifth</item>
|
||||
<item>@string/game_thumb_sixth</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -13,28 +13,11 @@
|
|||
# This is the first screen you see when you launch Crosswords
|
||||
############################################################
|
||||
-->
|
||||
<!-- These two messages appear at the top of the list of games
|
||||
(unless the hide_intro preferences checkbox is checked.)-->
|
||||
<string name="empty_games_list">Use the button below to create a
|
||||
game. Tap an existing game to play it or long-tap it for other
|
||||
options.</string>
|
||||
<!-- -->
|
||||
<string name="empty_games_list2">You can hide this and the buttons
|
||||
below in the Appearance section of Settings (accessed via your
|
||||
device\'s menu key.)</string>
|
||||
|
||||
<!-- Text of button at bottom of main games-list screen and of
|
||||
menuitem in main games-list screen's menu. (The botton can
|
||||
be hidden in the same way as the above text.) -->
|
||||
<!-- Text of menuitem in main games-list screen's menu -->
|
||||
<string name="button_new_game">Add game</string>
|
||||
<string name="button_new_group">Add group</string>
|
||||
|
||||
<!-- When the game list is empty and the above messages and button
|
||||
are hidden via preferences, this text is shown -->
|
||||
<string name="empty_list_msg">Use the menu key to add a
|
||||
game.</string>
|
||||
|
||||
|
||||
<!-- Used to format game name plus some other information as the
|
||||
one-line summary for each game in the main screen. The name
|
||||
of the game is substituted for %1$s. Something else
|
||||
|
@ -51,7 +34,7 @@
|
|||
they aren't available yet because the connection is not
|
||||
complete. Displayed in the lists of players found in each
|
||||
game listing. -->
|
||||
<string name="missing_player">(not here yet...)</string>
|
||||
<string name="missing_player">(not here yet…)</string>
|
||||
|
||||
<!-- The display of each networked game includes one of three
|
||||
states it can be in in the process of connecting to the
|
||||
|
@ -102,10 +85,10 @@
|
|||
-->
|
||||
|
||||
<!-- Brings up the Wordlists (formerly Dictionaries) screen -->
|
||||
<string name="gamel_menu_dicts">Wordlists</string>
|
||||
<string name="gamel_menu_dicts">Wordlists…</string>
|
||||
|
||||
<!-- text of menu that brings up the Settings (preferences) dialog -->
|
||||
<string name="menu_prefs">Settings</string>
|
||||
<string name="menu_prefs">App Settings…</string>
|
||||
|
||||
<!-- Regardless of the setting of the connect_frequency
|
||||
preference, checks the relay immediately for any moves for
|
||||
|
@ -115,18 +98,15 @@
|
|||
|
||||
<!-- Text of progress indicator shown while check is being conducted -->
|
||||
<string name="msgs_progress">Checking relay for moves
|
||||
etc...</string>
|
||||
etc…</string>
|
||||
|
||||
<!-- If you choose the above option and have no networked games
|
||||
you get this error message -->
|
||||
<string name="no_games_to_refresh">No games found that connect via
|
||||
the relay.</string>
|
||||
|
||||
<!-- Deletes all games on the device (after confirmation) -->
|
||||
<string name="gamel_menu_delete_all">Delete all</string>
|
||||
|
||||
<!-- Brings up "About Crosswords" dialog -->
|
||||
<string name="board_menu_file_about">About Crosswords</string>
|
||||
<string name="board_menu_file_about">About Crosswords…</string>
|
||||
|
||||
<!--
|
||||
############################################################
|
||||
|
@ -140,11 +120,11 @@
|
|||
|
||||
<!-- ############## menu items ############## -->
|
||||
<!-- pulls up dialog to configure the selected game -->
|
||||
<string name="list_item_config">Game settings...</string>
|
||||
<string name="list_item_config">Game settings…</string>
|
||||
<!-- pulls up dialog to rename (change name of) the selected game -->
|
||||
<string name="list_item_rename">Rename...</string>
|
||||
<string name="list_item_rename">Rename…</string>
|
||||
<!-- pulls up dialog to change the group of the selected game -->
|
||||
<string name="list_item_move">Move to group...</string>
|
||||
<string name="list_item_move">Move to group…</string>
|
||||
|
||||
<!-- pulls up dialog to delete the selected game -->
|
||||
<string name="list_item_delete">Delete</string>
|
||||
|
@ -174,19 +154,14 @@
|
|||
list_item_rename) -->
|
||||
<string name="rename_label">Change the name of this game to:</string>
|
||||
|
||||
<!-- Text of confirmation dialog posted when list_item_delete menu is
|
||||
selected -->
|
||||
<string name="confirm_delete">Are you sure you want to delete this
|
||||
game?</string>
|
||||
|
||||
<string name="confirm_seldeletes">Are you sure you want to delete
|
||||
all selected games? This action cannot be undone.</string>
|
||||
<string name="confirm_seldeletesf">Are you sure you want to delete
|
||||
the %d selected game[s]? This action cannot be undone.</string>
|
||||
|
||||
<!-- Text of confirmation dialog posted when list_item_reset menu
|
||||
is selected -->
|
||||
<string name="confirm_reset">Are you sure you want to reset this
|
||||
game? Resetting erases all moves and any connection
|
||||
information.</string>
|
||||
<string name="confirm_reset">Are you sure you want to reset the
|
||||
selected game[s]? (Resetting erases all moves and any connection
|
||||
information.)</string>
|
||||
|
||||
<!--
|
||||
############################################################
|
||||
|
@ -202,7 +177,7 @@
|
|||
<!-- text of button at the bottom of the screen. It launches the
|
||||
browser pointed at the site where additional wordlists can be
|
||||
found. -->
|
||||
<string name="download_dicts">Download more...</string>
|
||||
<string name="download_dicts">Download more…</string>
|
||||
|
||||
<!-- One of the strings used in the right column of the list of
|
||||
installed wordlists to describe those that are part of
|
||||
|
@ -250,13 +225,13 @@
|
|||
wordlist is substituted for %s. Sometimes one of the two
|
||||
strings below is appended. -->
|
||||
<string name="confirm_delete_dictf">Are you sure you want to
|
||||
delete %s?</string>
|
||||
delete the wordlist[s] %s?</string>
|
||||
|
||||
<!-- Additional text appended to text confirm_delete_dictf in the
|
||||
wordlist delete confiration dialog in the case where the
|
||||
wordlist to be deleted is the last in its language. The name
|
||||
of the language is substituted for %s. -->
|
||||
<string name="confirm_deleteonly_dictf">\u0020It is the only %s
|
||||
<string name="confirm_deleteonly_dictf">%1$s is the only %2$s
|
||||
wordlist installed. One or more games will be unopenable
|
||||
without it.</string>
|
||||
<!-- Additional text appended to text confirm_delete_dictf in the
|
||||
|
@ -277,9 +252,9 @@
|
|||
<!-- Used as the text fo the confirming/querying dialog that goes
|
||||
up when the dicts_item_select menuitem is chosen. The
|
||||
possible answers are the three button text strings below. -->
|
||||
<string name="set_default_messagef">For what players should this
|
||||
wordlist be the default for new games? (The language %s will be
|
||||
the default for both.)</string>
|
||||
<string name="set_default_messagef">For what players should the
|
||||
wordlist %1$s be the default for new games? (The language %2$s will be
|
||||
the default for both.)</string>
|
||||
|
||||
<!-- These three strings are the text for three buttons giving
|
||||
choices in respose to the dialog launched in response to the
|
||||
|
@ -309,7 +284,7 @@
|
|||
############################################################
|
||||
-->
|
||||
<!-- window title (game name substituted for %s) -->
|
||||
<string name="title_game_configf">%s settings</string>
|
||||
<string name="title_game_configf">Settings for %s</string>
|
||||
|
||||
<!-- alternate window title used when game is networked -->
|
||||
<string name="title_gamenet_configf">%s settings (networked)</string>
|
||||
|
@ -326,7 +301,7 @@
|
|||
|
||||
<!-- text for separator above the list of players that's used for
|
||||
non-networked games -->
|
||||
<string name="players_label_standalone">Players</string>
|
||||
<string name="players_label_standalone">Players (tap to edit)</string>
|
||||
|
||||
<!-- text for separator above the list of players that's used for
|
||||
networked games. The numbers of local and non-local players
|
||||
|
@ -527,10 +502,10 @@
|
|||
|
||||
<!-- Buttons shown at bottom when board is in exchange mode,
|
||||
i.e. after user has picked board_menu_trade menu item -->
|
||||
<string name="button_trade_commit">Commit exchange</string>
|
||||
<string name="button_trade_cancel">Cancel exchange</string>
|
||||
<string name="button_trade_commit">Commit trade</string>
|
||||
<string name="button_trade_cancel">Cancel trade</string>
|
||||
|
||||
<string name="entering_trade">Tap tiles to select...</string>
|
||||
<string name="entering_trade">Tap tiles to select…</string>
|
||||
|
||||
|
||||
<!-- Bonus value hint that's displayed in gray text in the colored
|
||||
|
@ -653,7 +628,7 @@
|
|||
|
||||
<!-- This menu begins an exchange of tiles: puts the board into
|
||||
trade mode. -->
|
||||
<string name="board_menu_trade">Exchange tiles</string>
|
||||
<string name="board_menu_trade">Trade</string>
|
||||
|
||||
<!-- hide and shows the tray. On devices where there is enough
|
||||
room for the full board and tray to be shown then hiding the
|
||||
|
@ -669,23 +644,23 @@
|
|||
<string name="board_menu_undo_last">Undo last</string>
|
||||
|
||||
<!-- Title of submenu -->
|
||||
<string name="board_submenu_game">Game</string>
|
||||
<string name="board_submenu_game">Game -></string>
|
||||
|
||||
<!-- menu on Game submenu: brings up dialog listing all tiles in
|
||||
the language of the game along with how many of each there
|
||||
are and how many points each is worth. This display is the
|
||||
same throughout the game. -->
|
||||
<string name="board_menu_game_counts">Counts and values</string>
|
||||
<string name="board_menu_game_counts">Counts and values…</string>
|
||||
|
||||
<!-- menu on Game submenu: brings up dialog listing all tiles not
|
||||
yet played and not in the rack of the player whose rack is
|
||||
visible (whose turn it is, generally). This display will
|
||||
change as tiles are used and depending on what player is
|
||||
asking. -->
|
||||
<string name="board_menu_game_left">Tiles remaining</string>
|
||||
<string name="board_menu_game_left">Tiles remaining…</string>
|
||||
|
||||
<!-- Brings up listing of all moves played so far this game. -->
|
||||
<string name="board_menu_game_history">Game history</string>
|
||||
<string name="board_menu_game_history">Game history…</string>
|
||||
|
||||
<!-- Brings up explanation of the game's final score. If the game
|
||||
is not yet over, gives you a choice whether to end it now,
|
||||
|
@ -797,7 +772,7 @@
|
|||
############################################################
|
||||
-->
|
||||
<!-- window title -->
|
||||
<string name="title_prefs">Crosswords settings</string>
|
||||
<string name="title_prefs">Crosswords Settings</string>
|
||||
|
||||
<!--
|
||||
############################################################
|
||||
|
@ -851,7 +826,7 @@
|
|||
|
||||
<!-- Used to indicate that a preference is not enabled, i.e. not
|
||||
part of the game and that the user should ignore it. -->
|
||||
<string name="tell_unused">Not used yet...</string>
|
||||
<string name="tell_unused">Not used yet…</string>
|
||||
|
||||
<!-- sub-preference for dictionaries (soon to be called "word lists") -->
|
||||
<string name="prefs_dicts">Wordlists</string>
|
||||
|
@ -922,14 +897,6 @@
|
|||
etc. -->
|
||||
<string name="game_summary_field_state">Game state</string>
|
||||
|
||||
<!-- The main screen, by default, has a "add game" button and some
|
||||
text at the top that take up space and are unnecessary for
|
||||
experienced users. This checkbox hides them. -->
|
||||
<string name="hide_intro">Hide main-page hint</string>
|
||||
<!-- clarification of above -->
|
||||
<string name="hide_intro_summary">It\'s useful only when you\'re
|
||||
starting out...</string>
|
||||
|
||||
<!-- Checkbox that when set prevents showing a title bar in the
|
||||
game board window to save space -->
|
||||
<string name="hide_title">Hide titlebar</string>
|
||||
|
@ -1214,12 +1181,17 @@
|
|||
explanation/guidance. -->
|
||||
<string name="sms_or_email">Send invitation using SMS (texting) or
|
||||
via email?</string>
|
||||
<string name="nfc_or_email">Send invitation using NFC (Android
|
||||
beaming – NEW) or via email?</string>
|
||||
<string name="nfc_or_sms_or_email">Send invitation using SMS
|
||||
(texting) or NFC (\"Android beaming\" – NEW) or via email?</string>
|
||||
|
||||
<!-- When an invitation is sent, the user gets to choose between
|
||||
plaintext and html formatting. These two strings are shown in the
|
||||
two buttons in the dialog. -->
|
||||
<string name="button_text">SMS/Text</string>
|
||||
<string name="button_html">Email</string>
|
||||
<string name="button_nfc">NFC</string>
|
||||
|
||||
<!-- This is the subject line of the email/text sent to invite
|
||||
someone to join a game. -->
|
||||
|
@ -1431,7 +1403,7 @@
|
|||
Guest wordlists; Host wins.</string>
|
||||
|
||||
|
||||
<string name="downloading_dictf">Downloading %s...</string>
|
||||
<string name="downloading_dictf">Downloading %s…</string>
|
||||
|
||||
<!--
|
||||
############################################################
|
||||
|
@ -1558,7 +1530,7 @@
|
|||
sure you want to create another?</string>
|
||||
|
||||
<!-- Title of generic dialog used to display information -->
|
||||
<string name="info_title">FYI...</string>
|
||||
<string name="info_title">FYI…</string>
|
||||
|
||||
<!-- title of dialog allowing user to pick tiles "face up". (This
|
||||
feature is not yet supported on Android.) -->
|
||||
|
@ -1596,7 +1568,7 @@
|
|||
|
||||
<!-- Title for generic dialog asking a question, usually in the
|
||||
middle of a game, like "do you want to commit this move?"-->
|
||||
<string name="query_title">A question...</string>
|
||||
<string name="query_title">A question…</string>
|
||||
|
||||
<!--
|
||||
###########################################################
|
||||
|
@ -1629,9 +1601,13 @@
|
|||
|
||||
<!-- Shown when the user chooses the "board_menu_trade" menu -->
|
||||
<string name="not_again_trading">You are entering tile-exchange
|
||||
mode. Tap tiles to add/remove them from the set to be
|
||||
exchanged. Use the buttons to commit your turn or exit exchange
|
||||
mode.</string>
|
||||
mode.\n\nTap tiles to add/remove them from the set to be
|
||||
exchanged.\n\n</string>
|
||||
|
||||
<string name="not_again_trading_buttons">Use the buttons to
|
||||
commit your turn or exit exchange mode.</string>
|
||||
<string name="not_again_trading_menu">Use the menu or action bar
|
||||
to commit your turn or exit exchange mode.</string>
|
||||
|
||||
<!-- Currently not used -->
|
||||
<!-- <string name="not_again_newgame">The new game you have created has -->
|
||||
|
@ -1741,7 +1717,7 @@
|
|||
another players turn. The idea is to give a hint about how to
|
||||
find out about recent moves. -->
|
||||
<string name="not_again_turnchanged">The player whose turn it is
|
||||
is drawn large in the scoreboard. Hold your finger on a name in
|
||||
is drawn large in the scoreboard.\n\nHold your finger on a name in
|
||||
the scoreboard to get details about that player\'s most recent
|
||||
move.</string>
|
||||
|
||||
|
@ -1886,7 +1862,7 @@
|
|||
<!-- -->
|
||||
<string name="email_body_revf">(If relevant, please include the
|
||||
version: \"%s\"; and make/model of your phone or
|
||||
tablet.)"</string>
|
||||
tablet.)</string>
|
||||
|
||||
<string name="newgame_enable_bt">Turn Bluetooth on</string>
|
||||
|
||||
|
@ -1898,7 +1874,7 @@
|
|||
<!-- -->
|
||||
<string name="scan_progress">Scanning for Crosswords on paired devices</string>
|
||||
<!-- -->
|
||||
<string name="invite_progress">Sending new game info...</string>
|
||||
<string name="invite_progress">Sending new game info…</string>
|
||||
|
||||
<!-- -->
|
||||
<string name="summary_wait_host">Waiting for connection[s]</string>
|
||||
|
@ -2024,7 +2000,7 @@
|
|||
<string name="board_menu_dict">Browse wordlist</string>
|
||||
|
||||
<!-- -->
|
||||
<string name="game_list_tmp">Loading game summary...</string>
|
||||
<string name="game_list_tmp">Building game summary…</string>
|
||||
|
||||
<!-- -->
|
||||
<string name="connstat_nonet">This is a standalone game. There is
|
||||
|
@ -2124,7 +2100,6 @@
|
|||
wordlist?</string>
|
||||
<string name="button_decline">Decline</string>
|
||||
|
||||
<string name="downloadingf">Downloading %s...</string>
|
||||
<string name="download_done">Download finished</string>
|
||||
<string name="download_failed">Download unsuccessful</string>
|
||||
|
||||
|
@ -2145,14 +2120,18 @@
|
|||
<string name="group_new_games">New games</string>
|
||||
|
||||
<string name="group_confirm_del">Are you sure you want to delete
|
||||
this group?</string>
|
||||
the selected group?</string>
|
||||
<string name="groups_confirm_del">Are you sure you want to delete
|
||||
the selected groups?</string>
|
||||
<string name="group_confirm_delf">\u0020(It contains %d game[s],
|
||||
which will also be deleted.)</string>
|
||||
<string name="groups_confirm_delf">\u0020(They contains %d game[s],
|
||||
which will also be deleted.)</string>
|
||||
|
||||
<string name="rename_group_label">Change the name of this group to:</string>
|
||||
<string name="game_name_group_title">Name group</string>
|
||||
|
||||
<string name="cannot_delete_default_group">The group for new games
|
||||
<string name="cannot_delete_default_groupf">The group for new games, %s,
|
||||
cannot be deleted.</string>
|
||||
|
||||
<string name="no_move_onegroup">Moving is impossible until there
|
||||
|
@ -2169,9 +2148,43 @@
|
|||
<string name="square_tiles">Square rack tiles</string>
|
||||
<string name="square_tiles_summary">Even if they can be taller</string>
|
||||
|
||||
<string name="change_groupf">Move game %s</string>
|
||||
<string name="change_group">Move games</string>
|
||||
|
||||
<string name="show_wordlist_browser">Wordlist browser</string>
|
||||
|
||||
<string name="relay_alert_title">Message from relay</string>
|
||||
|
||||
<string name="not_again_newselect">Tapping a game opens it.\n\nYou
|
||||
can instead tap the icons at the left to select or deselect games,
|
||||
then act on selected games, e.g. to delete them, using the menu or
|
||||
\"Actionbar.\"</string>
|
||||
|
||||
<string name="not_again_backclears">The back button clears any
|
||||
selection instead of exiting. Hit it again to exit the
|
||||
app.</string>
|
||||
|
||||
<string name="sel_gamesf">Games: %d</string>
|
||||
<string name="sel_groupsf">Groups: %d</string>
|
||||
<string name="summary_thumbsize">Thumbnail size</string>
|
||||
<string name="sel_dictsf">Wordlists: %d</string>
|
||||
|
||||
<string name="thumb_enabled">Show thumbnails</string>
|
||||
<string name="summary_thumb_enabled">Display snapshots of games</string>
|
||||
|
||||
<string name="prefs_thumb">Thumbnails</string>
|
||||
<string name="prefs_thumb_summary">Setting for game snapshots</string>
|
||||
<string name="dropped_dupe">Invitation received but ignored: it
|
||||
has already been used to create a game.</string>
|
||||
<string name="cur_menu_markerf">%1$s (yours)</string>
|
||||
<string name="board_menu_invite">Invite</string>
|
||||
|
||||
<string name="enable_nfc">NFC is turned off on this device. You
|
||||
can use the Android Settings app to turn it on .</string>
|
||||
|
||||
<string name="button_go_settings">Launch Settings</string>
|
||||
|
||||
<string name="no_hide_titlebar">This setting is ignored on devices
|
||||
like yours that depend on the \"Action bar.\"</string>
|
||||
|
||||
<string name="sms_ready_text">Tap the receiving device now</string>
|
||||
</resources>
|
||||
|
|
|
@ -110,18 +110,32 @@
|
|||
<PreferenceScreen android:title="@string/prefs_appearance"
|
||||
android:summary="@string/prefs_appearance_summary"
|
||||
>
|
||||
<org.eehouse.android.xw4.XWListPreference
|
||||
<PreferenceScreen android:title="@string/prefs_thumb"
|
||||
android:summary="@string/prefs_thumb_summary"
|
||||
>
|
||||
<CheckBoxPreference android:key="@string/key_thumb_enabled"
|
||||
android:title="@string/thumb_enabled"
|
||||
android:summary="@string/summary_thumb_enabled"
|
||||
android:defaultValue="true"
|
||||
/>
|
||||
|
||||
<org.eehouse.android.xw4.XWListPreference
|
||||
android:key="@string/key_thumbsize"
|
||||
android:title="@string/summary_thumbsize"
|
||||
android:entries="@array/game_thumb_values"
|
||||
android:entryValues="@array/game_thumb_values"
|
||||
android:defaultValue="@string/game_thumb_third"
|
||||
/>
|
||||
</PreferenceScreen>
|
||||
|
||||
<org.eehouse.android.xw4.XWSumListPreference
|
||||
android:key="@string/key_summary_field"
|
||||
android:title="@string/summary_field"
|
||||
android:entries="@array/game_summary_values"
|
||||
android:entryValues="@array/game_summary_values"
|
||||
android:defaultValue="@string/game_summary_field_opponents"
|
||||
/>
|
||||
<CheckBoxPreference android:key="@string/key_hide_intro"
|
||||
android:title="@string/hide_intro"
|
||||
android:summary="@string/hide_intro_summary"
|
||||
android:defaultValue="false"
|
||||
/>
|
||||
|
||||
<CheckBoxPreference android:key="@string/key_hide_title"
|
||||
android:title="@string/hide_title"
|
||||
android:summary="@string/hide_title_summary"
|
||||
|
@ -297,11 +311,18 @@
|
|||
/>
|
||||
<CheckBoxPreference android:key="@string/key_logging_on"
|
||||
android:title="@string/logging_on"
|
||||
android:summary="@string/logging_on_summary"
|
||||
android:defaultValue="false"
|
||||
/>
|
||||
<CheckBoxPreference android:key="@string/key_enable_debug"
|
||||
android:title="Enable debug features"
|
||||
android:summary="Menuitems etc."
|
||||
android:title="@string/debug_features"
|
||||
android:summary="@string/debug_features_summary"
|
||||
android:defaultValue="false"
|
||||
/>
|
||||
|
||||
<CheckBoxPreference android:key="@string/key_enable_dup_invite"
|
||||
android:title="@string/enable_dupes_title"
|
||||
android:summary="@string/enable_dupes_summary"
|
||||
android:defaultValue="false"
|
||||
/>
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
GitVersion.java
|
||||
BuildConstants.java
|
||||
GCMConsts.java
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2009-2010 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
public class ABUtils {
|
||||
private static int s_sdkVersion =
|
||||
Integer.valueOf( android.os.Build.VERSION.SDK );
|
||||
|
||||
private static interface SafeInvalOptionsMenu {
|
||||
public void doInval( Activity activity );
|
||||
}
|
||||
private static class SafeInvalOptionsMenuImpl
|
||||
implements SafeInvalOptionsMenu {
|
||||
public void doInval( Activity activity ) {
|
||||
activity.invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
private static SafeInvalOptionsMenu s_safeInval = null;
|
||||
|
||||
private static interface SafeHasMenuKey {
|
||||
public boolean hasMenuKey( Context context );
|
||||
}
|
||||
private static class SafeHasMenuKeyImpl
|
||||
implements SafeHasMenuKey {
|
||||
public boolean hasMenuKey( Context context )
|
||||
{
|
||||
return ViewConfiguration.get(context).hasPermanentMenuKey();
|
||||
}
|
||||
}
|
||||
private static SafeHasMenuKey s_safeHas = null;
|
||||
|
||||
static {
|
||||
if ( 11 <= s_sdkVersion ) {
|
||||
s_safeInval = new SafeInvalOptionsMenuImpl();
|
||||
}
|
||||
if ( 14 <= s_sdkVersion ) {
|
||||
s_safeHas = new SafeHasMenuKeyImpl();
|
||||
}
|
||||
}
|
||||
|
||||
public static void invalidateOptionsMenuIf( Activity activity )
|
||||
{
|
||||
if ( null != s_safeInval ) {
|
||||
s_safeInval.doInval( activity );
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean haveActionBar()
|
||||
{
|
||||
return null != s_safeInval;
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/10929579/how-to-check-if-android-phone-has-hardware-menu-button-in-android-2-1:
|
||||
// If SDK <= 10, assume yes; >= 14, use the API; in the middle,
|
||||
// assume no
|
||||
public static boolean haveMenuKey( Context context )
|
||||
{
|
||||
boolean result;
|
||||
if ( s_sdkVersion <= 10 ) {
|
||||
result = true;
|
||||
} else if ( s_sdkVersion < 14 ) {
|
||||
result = false;
|
||||
} else {
|
||||
result = s_safeHas.hasMenuKey( context );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -21,45 +21,52 @@
|
|||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Window;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.content.Intent;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import android.app.Dialog;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import junit.framework.Assert;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.pm.ActivityInfo;
|
||||
|
||||
import org.eehouse.android.xw4.jni.*;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
|
||||
import org.eehouse.android.xw4.jni.JNIThread.*;
|
||||
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
|
||||
import org.eehouse.android.xw4.jni.JNIThread.*;
|
||||
|
||||
|
||||
public class BoardActivity extends XWActivity
|
||||
implements TransportProcs.TPMsgHandler, View.OnClickListener,
|
||||
DictImportActivity.DownloadFinishedListener,
|
||||
ConnStatusHandler.ConnStatusCBacks {
|
||||
ConnStatusHandler.ConnStatusCBacks,
|
||||
NFCUtils.NFCActor {
|
||||
|
||||
public static final String INTENT_KEY_CHAT = "chat";
|
||||
|
||||
|
@ -79,6 +86,7 @@ public class BoardActivity extends XWActivity
|
|||
private static final int DLG_GETDICT = DLG_OKONLY + 13;
|
||||
private static final int GAME_OVER = DLG_OKONLY + 14;
|
||||
private static final int DLG_CONNSTAT = DLG_OKONLY + 15;
|
||||
private static final int ENABLE_NFC = DLG_OKONLY + 16;
|
||||
|
||||
private static final int CHAT_REQUEST = 1;
|
||||
private static final int BT_INVITE_RESULT = 2;
|
||||
|
@ -120,6 +128,7 @@ public class BoardActivity extends XWActivity
|
|||
private int m_jniGamePtr;
|
||||
private GameLock m_gameLock;
|
||||
private CurGameInfo m_gi;
|
||||
private GameSummary m_summary;
|
||||
private CommsTransport m_xport;
|
||||
private Handler m_handler = null;
|
||||
private TimerRunnable[] m_timers;
|
||||
|
@ -493,7 +502,7 @@ public class BoardActivity extends XWActivity
|
|||
lstnr = new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dialog,
|
||||
int item ) {
|
||||
showEmailOrSMSThen( LAUNCH_INVITE_ACTION );
|
||||
showInviteChoicesThen( LAUNCH_INVITE_ACTION );
|
||||
}
|
||||
};
|
||||
dialog = new AlertDialog.Builder( this )
|
||||
|
@ -505,6 +514,10 @@ public class BoardActivity extends XWActivity
|
|||
}
|
||||
break;
|
||||
|
||||
case ENABLE_NFC:
|
||||
dialog = NFCUtils.makeEnableNFCDialog( this );
|
||||
break;
|
||||
|
||||
default:
|
||||
// just drop it; super.onCreateDialog likely failed
|
||||
break;
|
||||
|
@ -537,11 +550,12 @@ public class BoardActivity extends XWActivity
|
|||
super.onCreate( savedInstanceState );
|
||||
getBundledData( savedInstanceState );
|
||||
|
||||
if ( CommonPrefs.getHideTitleBar( this ) ) {
|
||||
if ( CommonPrefs.getHideTitleBar( this )
|
||||
&& ABUtils.haveMenuKey( this ) ) {
|
||||
requestWindowFeature( Window.FEATURE_NO_TITLE );
|
||||
}
|
||||
|
||||
if ( GitVersion.CHAT_SUPPORTED ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED ) {
|
||||
m_pendingChats = new ArrayList<String>();
|
||||
}
|
||||
|
||||
|
@ -552,14 +566,8 @@ public class BoardActivity extends XWActivity
|
|||
// XWTimerReason
|
||||
m_view = (BoardView)findViewById( R.id.board_view );
|
||||
m_tradeButtons = findViewById( R.id.exchange_buttons );
|
||||
m_exchCommmitButton = (Button)findViewById( R.id.exchange_commit );
|
||||
if ( null != m_exchCommmitButton ) {
|
||||
m_exchCommmitButton.setOnClickListener( this );
|
||||
}
|
||||
m_exchCancelButton = (Button)findViewById( R.id.exchange_cancel );
|
||||
if ( null != m_exchCancelButton ) {
|
||||
m_exchCancelButton.setOnClickListener( this );
|
||||
}
|
||||
m_exchCommmitButton = setListenerOrHide( R.id.exchange_commit );
|
||||
m_exchCancelButton = setListenerOrHide( R.id.exchange_cancel );
|
||||
m_volKeysZoom = XWPrefs.getVolKeysZoom( this );
|
||||
|
||||
Intent intent = getIntent();
|
||||
|
@ -568,6 +576,8 @@ public class BoardActivity extends XWActivity
|
|||
m_haveInvited = intent.getBooleanExtra( GameUtils.INVITED, false );
|
||||
m_overNotShown = true;
|
||||
|
||||
NFCUtils.register( this ); // Don't seem to need to unregister...
|
||||
|
||||
setBackgroundColor();
|
||||
setKeepScreenOn();
|
||||
} // onCreate
|
||||
|
@ -629,7 +639,7 @@ public class BoardActivity extends XWActivity
|
|||
if ( Activity.RESULT_CANCELED != resultCode ) {
|
||||
switch ( requestCode ) {
|
||||
case CHAT_REQUEST:
|
||||
if ( GitVersion.CHAT_SUPPORTED ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED ) {
|
||||
String msg = data.getStringExtra( INTENT_KEY_CHAT );
|
||||
if ( null != msg && msg.length() > 0 ) {
|
||||
m_pendingChats.add( msg );
|
||||
|
@ -722,8 +732,6 @@ public class BoardActivity extends XWActivity
|
|||
MenuItem item;
|
||||
int strId;
|
||||
|
||||
updateMenus( menu );
|
||||
|
||||
if ( null != m_gsi ) {
|
||||
inTrade = m_gsi.inTrade;
|
||||
menu.setGroupVisible( R.id.group_done, !inTrade );
|
||||
|
@ -736,11 +744,28 @@ public class BoardActivity extends XWActivity
|
|||
}
|
||||
item = menu.findItem( R.id.board_menu_tray );
|
||||
item.setTitle( strId );
|
||||
|
||||
hideShowItem( menu, R.id.board_menu_flip, m_gsi.visTileCount >= 1 );
|
||||
hideShowItem( menu, R.id.board_menu_toggle, m_gsi.visTileCount >= 1 );
|
||||
hideShowItem( menu, R.id.board_menu_juggle, m_gsi.canShuffle );
|
||||
hideShowItem( menu, R.id.board_menu_undo_current, m_gsi.canRedo );
|
||||
hideShowItem( menu, R.id.board_menu_hint_prev, m_gsi.canHint );
|
||||
hideShowItem( menu, R.id.board_menu_hint_next, m_gsi.canHint );
|
||||
hideShowItem( menu, R.id.board_menu_chat,
|
||||
BuildConstants.CHAT_SUPPORTED && m_gsi.canChat );
|
||||
hideShowItem( menu, R.id.board_menu_tray,
|
||||
!inTrade && m_gsi.canHideRack );
|
||||
}
|
||||
|
||||
Utils.setItemVisible( menu, R.id.board_menu_invite, 0 < m_missing );
|
||||
Utils.setItemVisible( menu, R.id.board_menu_undo_last, !inTrade );
|
||||
Utils.setItemVisible( menu, R.id.board_menu_tray, !inTrade );
|
||||
Utils.setItemVisible( menu, R.id.board_submenu_game, !inTrade );
|
||||
|
||||
Utils.setItemVisible( menu, R.id.board_menu_trade_cancel, inTrade );
|
||||
Utils.setItemVisible( menu, R.id.board_menu_trade_commit,
|
||||
inTrade && m_gsi.tradeTilesSelected );
|
||||
Utils.setItemVisible( menu, R.id.board_menu_trade,
|
||||
0 == m_missing && !m_gameOver && !inTrade );
|
||||
Utils.setItemVisible( menu, R.id.board_menu_game_resign, !inTrade );
|
||||
|
||||
if ( !inTrade ) {
|
||||
boolean enabled = null == m_gsi || m_gsi.curTurnSelected;
|
||||
|
@ -754,15 +779,14 @@ public class BoardActivity extends XWActivity
|
|||
}
|
||||
item.setTitle( strId );
|
||||
}
|
||||
if ( m_gameOver || DBUtils.gameOver( this, m_rowid ) ) {
|
||||
m_gameOver = true;
|
||||
item = menu.findItem( R.id.board_menu_game_resign );
|
||||
item.setTitle( R.string.board_menu_game_final );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_gameOver || DBUtils.gameOver( this, m_rowid ) ) {
|
||||
m_gameOver = true;
|
||||
item = menu.findItem( R.id.board_menu_game_resign );
|
||||
item.setTitle( R.string.board_menu_game_final );
|
||||
}
|
||||
|
||||
if ( DeviceRole.SERVER_STANDALONE == m_gi.serverRole ) {
|
||||
if ( null != m_gi && DeviceRole.SERVER_STANDALONE == m_gi.serverRole ) {
|
||||
Utils.setItemVisible( menu, R.id.board_menu_game_resend, false );
|
||||
Utils.setItemVisible( menu, R.id.gamel_menu_checkmoves, false );
|
||||
}
|
||||
|
@ -785,7 +809,7 @@ public class BoardActivity extends XWActivity
|
|||
showNotAgainDlgThen( R.string.not_again_done,
|
||||
R.string.key_notagain_done, COMMIT_ACTION );
|
||||
} else {
|
||||
dlgButtonClicked( COMMIT_ACTION, AlertDialog.BUTTON_POSITIVE );
|
||||
dlgButtonClicked( COMMIT_ACTION, AlertDialog.BUTTON_POSITIVE, null );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -819,8 +843,11 @@ public class BoardActivity extends XWActivity
|
|||
break;
|
||||
|
||||
case R.id.board_menu_trade:
|
||||
showNotAgainDlgThen( R.string.not_again_trading,
|
||||
R.string.key_notagain_trading,
|
||||
String msg = getString( R.string.not_again_trading );
|
||||
int strID = ABUtils.haveActionBar() ? R.string.not_again_trading_menu
|
||||
: R.string. not_again_trading_buttons;
|
||||
msg += getString( strID );
|
||||
showNotAgainDlgThen( msg, R.string.key_notagain_trading,
|
||||
START_TRADE_ACTION );
|
||||
break;
|
||||
|
||||
|
@ -833,7 +860,9 @@ public class BoardActivity extends XWActivity
|
|||
case R.id.board_menu_undo_last:
|
||||
showConfirmThen( R.string.confirm_undo_last, UNDO_LAST_ACTION );
|
||||
break;
|
||||
|
||||
case R.id.board_menu_invite:
|
||||
showDialog( DLG_INVITE );
|
||||
break;
|
||||
// small devices only
|
||||
case R.id.board_menu_dict:
|
||||
String dictName = m_gi.dictName( m_view.getCurPlayer() );
|
||||
|
@ -891,14 +920,20 @@ public class BoardActivity extends XWActivity
|
|||
// DlgDelegate.DlgClickNotify interface
|
||||
//////////////////////////////////////////////////
|
||||
@Override
|
||||
public void dlgButtonClicked( int id, int which )
|
||||
public void dlgButtonClicked( int id, int which, Object[] params )
|
||||
{
|
||||
if ( LAUNCH_INVITE_ACTION == id ) {
|
||||
if ( DlgDelegate.DISMISS_BUTTON != which ) {
|
||||
GameUtils.launchInviteActivity( BoardActivity.this,
|
||||
DlgDelegate.EMAIL_BTN == which,
|
||||
m_room, null, m_gi.dictLang,
|
||||
m_gi.dictName, m_gi.nPlayers );
|
||||
if ( DlgDelegate.NFC_BTN == which
|
||||
&& !NFCUtils.nfcAvail( this )[1] ) {
|
||||
showDialog( ENABLE_NFC );
|
||||
} else {
|
||||
String inviteID = GameUtils.formatGameID( m_gi.gameID );
|
||||
GameUtils.launchInviteActivity( this, which, m_room,
|
||||
inviteID, m_gi.dictLang,
|
||||
m_gi.dictName,
|
||||
m_gi.nPlayers );
|
||||
}
|
||||
}
|
||||
} else if ( AlertDialog.BUTTON_POSITIVE == which ) {
|
||||
JNICmd cmd = JNICmd.CMD_NONE;
|
||||
|
@ -1145,6 +1180,24 @@ public class BoardActivity extends XWActivity
|
|||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// NFCUtils.NFCActor
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
public String makeNFCMessage()
|
||||
{
|
||||
String data = null;
|
||||
if ( 0 < m_missing ) { // Isn't there a better test??
|
||||
String inviteID = String.format( "%X", m_gi.gameID );
|
||||
String room = m_summary.roomName;
|
||||
Assert.assertNotNull( room );
|
||||
data = NetLaunchInfo.makeLaunchJSON( this, room, inviteID,
|
||||
m_gi.dictLang,
|
||||
m_gi.dictName, m_gi.nPlayers );
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// ConnStatusHandler.ConnStatusCBacks
|
||||
//////////////////////////////////////////////////
|
||||
|
@ -1285,6 +1338,7 @@ public class BoardActivity extends XWActivity
|
|||
m_room = room;
|
||||
m_missing = nMissing;
|
||||
showDialog( DLG_INVITE );
|
||||
ABUtils.invalidateOptionsMenuIf( this );
|
||||
} else {
|
||||
toastStr = getString( R.string.msg_relay_waiting, devOrder,
|
||||
room, nMissing );
|
||||
|
@ -1302,11 +1356,14 @@ public class BoardActivity extends XWActivity
|
|||
m_toastStr = toastStr;
|
||||
if ( naMsg == 0 ) {
|
||||
dlgButtonClicked( SHOW_EXPL_ACTION,
|
||||
AlertDialog.BUTTON_POSITIVE );
|
||||
AlertDialog.BUTTON_POSITIVE, null );
|
||||
} else {
|
||||
showNotAgainDlgThen( naMsg, naKey, SHOW_EXPL_ACTION );
|
||||
}
|
||||
}
|
||||
|
||||
m_missing = nMissing;
|
||||
ABUtils.invalidateOptionsMenuIf( this );
|
||||
} // handleConndMessage
|
||||
|
||||
private class BoardUtilCtxt extends UtilCtxtImpl {
|
||||
|
@ -1727,7 +1784,7 @@ public class BoardActivity extends XWActivity
|
|||
@Override
|
||||
public void showChat( final String msg )
|
||||
{
|
||||
if ( GitVersion.CHAT_SUPPORTED ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED ) {
|
||||
post( new Runnable() {
|
||||
public void run() {
|
||||
DBUtils.appendChatHistory( BoardActivity.this,
|
||||
|
@ -1769,21 +1826,23 @@ public class BoardActivity extends XWActivity
|
|||
CommonPrefs cp = CommonPrefs.get( this );
|
||||
if ( null == stream ||
|
||||
! XwJNI.game_makeFromStream( m_jniGamePtr, stream,
|
||||
m_gi, dictNames, pairs.m_bytes,
|
||||
pairs.m_paths, langName, m_utils,
|
||||
m_jniu, m_view, cp, m_xport ) ) {
|
||||
XwJNI.game_makeNewGame( m_jniGamePtr, m_gi, m_utils, m_jniu,
|
||||
m_view, cp, m_xport, dictNames,
|
||||
pairs.m_bytes, pairs.m_paths,
|
||||
langName );
|
||||
m_gi, dictNames,
|
||||
pairs.m_bytes,
|
||||
pairs.m_paths, langName,
|
||||
m_utils, m_jniu,
|
||||
null, cp, m_xport ) ) {
|
||||
XwJNI.game_makeNewGame( m_jniGamePtr, m_gi, m_utils,
|
||||
m_jniu, null, cp, m_xport,
|
||||
dictNames, pairs.m_bytes,
|
||||
pairs.m_paths, langName );
|
||||
}
|
||||
|
||||
m_summary = new GameSummary( this, m_gi );
|
||||
XwJNI.game_summarize( m_jniGamePtr, m_summary );
|
||||
|
||||
Handler handler = new Handler() {
|
||||
public void handleMessage( Message msg ) {
|
||||
switch( msg.what ) {
|
||||
case JNIThread.DRAW:
|
||||
m_view.invalidate();
|
||||
break;
|
||||
case JNIThread.DIALOG:
|
||||
m_dlgBytes = (String)msg.obj;
|
||||
m_dlgTitle = msg.arg1;
|
||||
|
@ -1799,11 +1858,11 @@ public class BoardActivity extends XWActivity
|
|||
updateToolbar();
|
||||
if ( m_inTrade != m_gsi.inTrade ) {
|
||||
m_inTrade = m_gsi.inTrade;
|
||||
m_view.setInTrade( m_inTrade );
|
||||
}
|
||||
m_view.setInTrade( m_inTrade );
|
||||
adjustTradeVisibility();
|
||||
Activity self = BoardActivity.this;
|
||||
Utils.invalidateOptionsMenuIf( self );
|
||||
ABUtils.invalidateOptionsMenuIf( self );
|
||||
}
|
||||
break;
|
||||
case JNIThread.GOT_WORDS:
|
||||
|
@ -1922,7 +1981,7 @@ public class BoardActivity extends XWActivity
|
|||
R.string.not_again_undo,
|
||||
R.string.key_notagain_undo,
|
||||
UNDO_ACTION );
|
||||
if ( GitVersion.CHAT_SUPPORTED ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED ) {
|
||||
m_toolbar.setListener( Toolbar.BUTTON_CHAT,
|
||||
R.string.not_again_chat,
|
||||
R.string.key_notagain_chat,
|
||||
|
@ -2011,7 +2070,7 @@ public class BoardActivity extends XWActivity
|
|||
|
||||
private void startChatActivity()
|
||||
{
|
||||
if ( GitVersion.CHAT_SUPPORTED ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED ) {
|
||||
Intent intent = new Intent( this, ChatActivity.class );
|
||||
intent.putExtra( GameUtils.INTENT_KEY_ROWID, m_rowid );
|
||||
startActivityForResult( intent, CHAT_REQUEST );
|
||||
|
@ -2035,6 +2094,14 @@ public class BoardActivity extends XWActivity
|
|||
|
||||
clearThis();
|
||||
|
||||
if ( XWPrefs.getThumbEnabled( this ) ) {
|
||||
// Before we dispose, and after JNIThread has
|
||||
// relinquished interest, redraw on smaller scale.
|
||||
Bitmap thumb =
|
||||
GameUtils.takeSnapshot( this, m_jniGamePtr, m_gi );
|
||||
DBUtils.saveThumbnail( this, m_gameLock, thumb );
|
||||
}
|
||||
|
||||
XwJNI.game_dispose( m_jniGamePtr );
|
||||
m_jniGamePtr = 0;
|
||||
m_gi = null;
|
||||
|
@ -2059,7 +2126,7 @@ public class BoardActivity extends XWActivity
|
|||
|
||||
private void trySendChats()
|
||||
{
|
||||
if ( GitVersion.CHAT_SUPPORTED && null != m_jniThread ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED && null != m_jniThread ) {
|
||||
Iterator<String> iter = m_pendingChats.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
m_jniThread.handle( JNICmd.CMD_SENDCHAT, iter.next() );
|
||||
|
@ -2107,7 +2174,7 @@ public class BoardActivity extends XWActivity
|
|||
m_toolbar.update( Toolbar.BUTTON_HINT_PREV, m_gsi.canHint );
|
||||
m_toolbar.update( Toolbar.BUTTON_HINT_NEXT, m_gsi.canHint );
|
||||
m_toolbar.update( Toolbar.BUTTON_CHAT,
|
||||
GitVersion.CHAT_SUPPORTED && m_gsi.canChat );
|
||||
BuildConstants.CHAT_SUPPORTED && m_gsi.canChat );
|
||||
m_toolbar.update( Toolbar.BUTTON_BROWSE_DICT,
|
||||
null != m_gi.dictName( m_view.getCurPlayer() ) );
|
||||
}
|
||||
|
@ -2120,20 +2187,6 @@ public class BoardActivity extends XWActivity
|
|||
}
|
||||
}
|
||||
|
||||
private void updateMenus( Menu menu )
|
||||
{
|
||||
if ( null != m_gsi ) {
|
||||
hideShowItem( menu, R.id.board_menu_flip, m_gsi.visTileCount >= 1 );
|
||||
hideShowItem( menu, R.id.board_menu_toggle, m_gsi.visTileCount >= 1 );
|
||||
hideShowItem( menu, R.id.board_menu_juggle, m_gsi.canShuffle );
|
||||
hideShowItem( menu, R.id.board_menu_undo_current, m_gsi.canRedo );
|
||||
hideShowItem( menu, R.id.board_menu_hint_prev, m_gsi.canHint );
|
||||
hideShowItem( menu, R.id.board_menu_hint_next, m_gsi.canHint );
|
||||
hideShowItem( menu, R.id.board_menu_chat,
|
||||
GitVersion.CHAT_SUPPORTED && m_gsi.canChat );
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustTradeVisibility()
|
||||
{
|
||||
m_toolbar.setVisibility( m_inTrade? View.GONE : View.VISIBLE );
|
||||
|
@ -2231,5 +2284,18 @@ public class BoardActivity extends XWActivity
|
|||
startActivity( intent );
|
||||
finish();
|
||||
}
|
||||
|
||||
private Button setListenerOrHide( int id )
|
||||
{
|
||||
Button button = (Button)findViewById( id );
|
||||
if ( null != button ) {
|
||||
if ( ABUtils.haveActionBar() ) {
|
||||
button.setVisibility( View.INVISIBLE );
|
||||
} else {
|
||||
button.setOnClickListener( this );
|
||||
}
|
||||
}
|
||||
return button;
|
||||
}
|
||||
|
||||
} // class BoardActivity
|
||||
|
|
|
@ -0,0 +1,867 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2009 - 2013 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.app.Activity;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
|
||||
import org.eehouse.android.xw4.jni.DrawCtx;
|
||||
import org.eehouse.android.xw4.jni.DrawScoreInfo;
|
||||
import org.eehouse.android.xw4.jni.CommonPrefs;
|
||||
import org.eehouse.android.xw4.jni.JNIThread;
|
||||
import org.eehouse.android.xw4.jni.XwJNI;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class BoardCanvas extends Canvas implements DrawCtx {
|
||||
private static final int BLACK = 0xFF000000;
|
||||
private static final int WHITE = 0xFFFFFFFF;
|
||||
private static final int FRAME_GREY = 0xFF101010;
|
||||
private static final int SCORE_HT_DROP = 2;
|
||||
private static final boolean DEBUG_DRAWFRAMES = false;
|
||||
private static final int NOT_TURN_ALPHA = 0x3FFFFFFF;
|
||||
private static final int IN_TRADE_ALPHA = 0x3FFFFFFF;
|
||||
private static final boolean FRAME_TRAY_RECTS = false; // for debugging
|
||||
private static final float MIN_FONT_DIPS = 14.0f;
|
||||
|
||||
private Activity m_activity;
|
||||
private Bitmap m_bitmap;
|
||||
private JNIThread m_jniThread;
|
||||
private Paint m_fillPaint;
|
||||
private Paint m_strokePaint;
|
||||
private Paint m_drawPaint;
|
||||
private Paint m_tileStrokePaint;
|
||||
private String[][] m_scores;
|
||||
private String m_remText;
|
||||
private int m_mediumFontHt;
|
||||
private int m_defaultFontHt;
|
||||
private int m_minRemWidth;
|
||||
private Rect m_boundsScratch = new Rect();
|
||||
private Rect m_letterRect;
|
||||
private Rect m_valRect;
|
||||
|
||||
private int[] m_bonusColors;
|
||||
private int[] m_playerColors;
|
||||
private int[] m_otherColors;
|
||||
private String[] m_bonusSummaries;
|
||||
private CommonPrefs m_prefs;
|
||||
private int m_lastSecsLeft;
|
||||
private int m_lastTimerPlayer;
|
||||
private boolean m_inTrade;
|
||||
private boolean m_darkOnLight;
|
||||
private Drawable m_origin;
|
||||
private boolean m_blackArrow;
|
||||
private Drawable m_rightArrow;
|
||||
private Drawable m_downArrow;
|
||||
private int m_trayOwner = -1;
|
||||
private int m_pendingScore;
|
||||
private int m_dictPtr = 0;
|
||||
private String[] m_dictChars;
|
||||
private boolean m_hasSmallScreen;
|
||||
private int m_backgroundUsed = 0x00000000;
|
||||
|
||||
// FontDims: exists to translate space available to the largest
|
||||
// font we can draw within that space taking advantage of our use
|
||||
// being limited to a known small subset of glyphs. We need two
|
||||
// numbers from this: the textHeight to pass to Paint.setTextSize,
|
||||
// and the descent to use when drawing. Both can be calculated
|
||||
// proportionally. We know the ht we passed to Paint to get the
|
||||
// height we've now measured; that gives a percent to multiply any
|
||||
// future wantHt by. Ditto for the descent
|
||||
private class FontDims {
|
||||
FontDims( float askedHt, int topRow, int bottomRow, float width ) {
|
||||
// DbgUtils.logf( "FontDims(): askedHt=" + askedHt );
|
||||
// DbgUtils.logf( "FontDims(): topRow=" + topRow );
|
||||
// DbgUtils.logf( "FontDims(): bottomRow=" + bottomRow );
|
||||
// DbgUtils.logf( "FontDims(): width=" + width );
|
||||
float gotHt = bottomRow - topRow + 1;
|
||||
m_htProportion = gotHt / askedHt;
|
||||
Assert.assertTrue( (bottomRow+1) >= askedHt );
|
||||
float descent = (bottomRow+1) - askedHt;
|
||||
// DbgUtils.logf( "descent: " + descent );
|
||||
m_descentProportion = descent / askedHt;
|
||||
Assert.assertTrue( m_descentProportion >= 0 );
|
||||
m_widthProportion = width / askedHt;
|
||||
// DbgUtils.logf( "m_htProportion: " + m_htProportion );
|
||||
// DbgUtils.logf( "m_descentProportion: " + m_descentProportion );
|
||||
}
|
||||
private float m_htProportion;
|
||||
private float m_descentProportion;
|
||||
private float m_widthProportion;
|
||||
int heightFor( int ht ) { return (int)(ht / m_htProportion); }
|
||||
int descentFor( int ht ) { return (int)(ht * m_descentProportion); }
|
||||
int widthFor( int width ) { return (int)(width / m_widthProportion); }
|
||||
}
|
||||
private FontDims m_fontDims;
|
||||
|
||||
public BoardCanvas( Activity activity, Bitmap bitmap, JNIThread jniThread,
|
||||
BoardDims dims )
|
||||
{
|
||||
super( bitmap );
|
||||
m_activity = activity;
|
||||
m_bitmap = bitmap;
|
||||
m_jniThread = jniThread;
|
||||
|
||||
m_hasSmallScreen = Utils.hasSmallScreen( activity );
|
||||
|
||||
float scale = activity.getResources().getDisplayMetrics().density;
|
||||
m_defaultFontHt = (int)(MIN_FONT_DIPS * scale + 0.5f);
|
||||
m_mediumFontHt = m_defaultFontHt * 3 / 2;
|
||||
if ( null != dims ) {
|
||||
m_minRemWidth = dims.cellSize;
|
||||
}
|
||||
|
||||
m_drawPaint = new Paint();
|
||||
m_fillPaint = new Paint( Paint.ANTI_ALIAS_FLAG );
|
||||
m_strokePaint = new Paint();
|
||||
m_strokePaint.setStyle( Paint.Style.STROKE );
|
||||
|
||||
Resources res = activity.getResources();
|
||||
m_origin = res.getDrawable( R.drawable.origin );
|
||||
|
||||
m_prefs = CommonPrefs.get( activity );
|
||||
m_playerColors = m_prefs.playerColors;
|
||||
m_bonusColors = m_prefs.bonusColors;
|
||||
m_otherColors = m_prefs.otherColors;
|
||||
|
||||
int[] ids = { R.string.bonus_l2x_summary,
|
||||
R.string.bonus_w2x_summary ,
|
||||
R.string.bonus_l3x_summary,
|
||||
R.string.bonus_w3x_summary };
|
||||
m_bonusSummaries = new String[1 + ids.length];
|
||||
for ( int ii = 0; ii < ids.length; ++ii ) {
|
||||
m_bonusSummaries[ ii+1 ] = res.getString( ids[ii] );
|
||||
}
|
||||
|
||||
m_boundsScratch.set( 0, 0, bitmap.getWidth(), bitmap.getHeight() );
|
||||
fillRect( m_boundsScratch, WHITE );
|
||||
}
|
||||
|
||||
public void setJNIThread( JNIThread jniThread )
|
||||
{
|
||||
if ( ! jniThread.equals( m_jniThread ) ) {
|
||||
DbgUtils.logf( "BoardCanvas changing threads" );
|
||||
m_jniThread = jniThread;
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurPlayer()
|
||||
{
|
||||
return m_trayOwner;
|
||||
}
|
||||
|
||||
public int curPending()
|
||||
{
|
||||
return m_pendingScore;
|
||||
}
|
||||
|
||||
public void setInTrade( boolean inTrade )
|
||||
{
|
||||
if ( m_inTrade != inTrade ) {
|
||||
m_inTrade = inTrade;
|
||||
m_jniThread.handle( JNIThread.JNICmd.CMD_INVALALL );
|
||||
}
|
||||
}
|
||||
|
||||
// DrawCtxt interface implementation
|
||||
public boolean scoreBegin( Rect rect, int numPlayers, int[] scores,
|
||||
int remCount )
|
||||
{
|
||||
fillRectOther( rect, CommonPrefs.COLOR_BACKGRND );
|
||||
m_scores = new String[numPlayers][];
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean measureRemText( Rect r, int nTilesLeft, int[] width,
|
||||
int[] height )
|
||||
{
|
||||
boolean showREM = 0 <= nTilesLeft;
|
||||
if ( showREM ) {
|
||||
// should cache a formatter
|
||||
m_remText = String.format( "%d", nTilesLeft );
|
||||
m_fillPaint.setTextSize( m_mediumFontHt );
|
||||
m_fillPaint.getTextBounds( m_remText, 0, m_remText.length(),
|
||||
m_boundsScratch );
|
||||
|
||||
int minWidth = m_boundsScratch.width();
|
||||
if ( minWidth < m_minRemWidth ) {
|
||||
minWidth = m_minRemWidth; // it's a button; make it bigger
|
||||
}
|
||||
width[0] = minWidth;
|
||||
height[0] = m_boundsScratch.height();
|
||||
}
|
||||
return showREM;
|
||||
}
|
||||
|
||||
public void drawRemText( Rect rInner, Rect rOuter, int nTilesLeft,
|
||||
boolean focussed )
|
||||
{
|
||||
int indx = focussed ? CommonPrefs.COLOR_FOCUS
|
||||
: CommonPrefs.COLOR_TILE_BACK;
|
||||
fillRectOther( rOuter, indx );
|
||||
|
||||
m_fillPaint.setColor( adjustColor(BLACK) );
|
||||
drawCentered( m_remText, rInner, null );
|
||||
}
|
||||
|
||||
public void measureScoreText( Rect rect, DrawScoreInfo dsi,
|
||||
int[] width, int[] height )
|
||||
{
|
||||
String[] scoreInfo = new String[dsi.isTurn?1:2];
|
||||
int indx = 0;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// If it's my turn I get one line. Otherwise squeeze into
|
||||
// two.
|
||||
|
||||
if ( dsi.isTurn ) {
|
||||
sb.append( dsi.name );
|
||||
sb.append( ":" );
|
||||
} else {
|
||||
scoreInfo[indx++] = dsi.name;
|
||||
}
|
||||
sb.append( dsi.totalScore );
|
||||
if ( dsi.nTilesLeft >= 0 ) {
|
||||
sb.append( ":" );
|
||||
sb.append( dsi.nTilesLeft );
|
||||
}
|
||||
scoreInfo[indx] = sb.toString();
|
||||
m_scores[dsi.playerNum] = scoreInfo;
|
||||
|
||||
int rectHt = rect.height();
|
||||
if ( !dsi.isTurn ) {
|
||||
rectHt /= 2;
|
||||
}
|
||||
int textHeight = rectHt - SCORE_HT_DROP;
|
||||
if ( textHeight < m_defaultFontHt ) {
|
||||
textHeight = m_defaultFontHt;
|
||||
}
|
||||
m_fillPaint.setTextSize( textHeight );
|
||||
|
||||
int needWidth = 0;
|
||||
for ( int ii = 0; ii < scoreInfo.length; ++ii ) {
|
||||
m_fillPaint.getTextBounds( scoreInfo[ii], 0, scoreInfo[ii].length(),
|
||||
m_boundsScratch );
|
||||
if ( needWidth < m_boundsScratch.width() ) {
|
||||
needWidth = m_boundsScratch.width();
|
||||
}
|
||||
}
|
||||
if ( needWidth > rect.width() ) {
|
||||
needWidth = rect.width();
|
||||
}
|
||||
width[0] = needWidth;
|
||||
|
||||
height[0] = rect.height();
|
||||
}
|
||||
|
||||
public void score_drawPlayer( Rect rInner, Rect rOuter,
|
||||
int gotPct, DrawScoreInfo dsi )
|
||||
{
|
||||
if ( 0 != (dsi.flags & CELL_ISCURSOR) ) {
|
||||
fillRectOther( rOuter, CommonPrefs.COLOR_FOCUS );
|
||||
} else if ( DEBUG_DRAWFRAMES && dsi.selected ) {
|
||||
fillRectOther( rOuter, CommonPrefs.COLOR_FOCUS );
|
||||
}
|
||||
String[] texts = m_scores[dsi.playerNum];
|
||||
int color = m_playerColors[dsi.playerNum];
|
||||
if ( !m_prefs.allowPeek ) {
|
||||
color = adjustColor( color );
|
||||
}
|
||||
m_fillPaint.setColor( color );
|
||||
|
||||
int height = rOuter.height() / texts.length;
|
||||
rOuter.bottom = rOuter.top + height;
|
||||
for ( String text : texts ) {
|
||||
drawCentered( text, rOuter, null );
|
||||
rOuter.offset( 0, height );
|
||||
}
|
||||
if ( DEBUG_DRAWFRAMES ) {
|
||||
m_strokePaint.setColor( BLACK );
|
||||
drawRect( rInner, m_strokePaint );
|
||||
}
|
||||
}
|
||||
|
||||
public void drawTimer( Rect rect, int player, int secondsLeft )
|
||||
{
|
||||
if ( (m_lastSecsLeft != secondsLeft || m_lastTimerPlayer != player) ) {
|
||||
m_lastSecsLeft = secondsLeft;
|
||||
m_lastTimerPlayer = player;
|
||||
|
||||
String negSign = secondsLeft < 0? "-":"";
|
||||
secondsLeft = Math.abs( secondsLeft );
|
||||
String time = String.format( "%s%d:%02d", negSign, secondsLeft/60,
|
||||
secondsLeft%60 );
|
||||
|
||||
fillRectOther( rect, CommonPrefs.COLOR_BACKGRND );
|
||||
m_fillPaint.setColor( m_playerColors[player] );
|
||||
|
||||
Rect shorter = new Rect( rect );
|
||||
shorter.inset( 0, shorter.height() / 5 );
|
||||
drawCentered( time, shorter, null );
|
||||
|
||||
m_jniThread.handle( JNIThread.JNICmd.CMD_DRAW );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean boardBegin( Rect rect, int cellWidth, int cellHeight )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean drawCell( final Rect rect, String text, int tile, int value,
|
||||
int owner, int bonus, int hintAtts,
|
||||
final int flags )
|
||||
{
|
||||
boolean canDraw = figureFontDims();
|
||||
if ( canDraw ) {
|
||||
int backColor;
|
||||
boolean empty = 0 != (flags & (CELL_DRAGSRC|CELL_ISEMPTY));
|
||||
boolean pending = 0 != (flags & CELL_HIGHLIGHT);
|
||||
String bonusStr = null;
|
||||
|
||||
if ( m_inTrade ) {
|
||||
fillRectOther( rect, CommonPrefs.COLOR_BACKGRND );
|
||||
}
|
||||
|
||||
if ( owner < 0 ) {
|
||||
owner = 0;
|
||||
}
|
||||
int foreColor = m_playerColors[owner];
|
||||
|
||||
if ( 0 != (flags & CELL_ISCURSOR) ) {
|
||||
backColor = m_otherColors[CommonPrefs.COLOR_FOCUS];
|
||||
} else if ( empty ) {
|
||||
if ( 0 == bonus ) {
|
||||
backColor = m_otherColors[CommonPrefs.COLOR_NOTILE];
|
||||
} else {
|
||||
backColor = m_bonusColors[bonus];
|
||||
bonusStr = m_bonusSummaries[bonus];
|
||||
}
|
||||
} else if ( pending ) {
|
||||
if ( darkOnLight() ) {
|
||||
foreColor = WHITE;
|
||||
backColor = BLACK;
|
||||
} else {
|
||||
foreColor = BLACK;
|
||||
backColor = WHITE;
|
||||
}
|
||||
} else {
|
||||
backColor = m_otherColors[CommonPrefs.COLOR_TILE_BACK];
|
||||
}
|
||||
|
||||
fillRect( rect, adjustColor( backColor ) );
|
||||
|
||||
if ( empty ) {
|
||||
if ( (CELL_ISSTAR & flags) != 0 ) {
|
||||
m_origin.setBounds( rect );
|
||||
m_origin.setAlpha( m_inTrade? IN_TRADE_ALPHA >> 24 : 255 );
|
||||
m_origin.draw( BoardCanvas.this );
|
||||
} else if ( null != bonusStr ) {
|
||||
int color = m_otherColors[CommonPrefs.COLOR_BONUSHINT];
|
||||
m_fillPaint.setColor( adjustColor(color) );
|
||||
Rect brect = new Rect( rect );
|
||||
brect.inset( 0, brect.height()/10 );
|
||||
drawCentered( bonusStr, brect, m_fontDims );
|
||||
}
|
||||
} else {
|
||||
m_fillPaint.setColor( adjustColor(foreColor) );
|
||||
drawCentered( text, rect, m_fontDims );
|
||||
}
|
||||
|
||||
if ( (CELL_ISBLANK & flags) != 0 ) {
|
||||
markBlank( rect, backColor );
|
||||
}
|
||||
|
||||
// frame the cell
|
||||
m_strokePaint.setColor( adjustColor(FRAME_GREY) );
|
||||
drawRect( rect, m_strokePaint );
|
||||
|
||||
drawCrosshairs( rect, flags );
|
||||
}
|
||||
return canDraw;
|
||||
} // drawCell
|
||||
|
||||
private boolean m_arrowHintShown = false;
|
||||
public void drawBoardArrow( Rect rect, int bonus, boolean vert,
|
||||
int hintAtts, int flags )
|
||||
{
|
||||
// figure out if the background is more dark than light
|
||||
boolean useDark = darkOnLight();
|
||||
if ( m_blackArrow != useDark ) {
|
||||
m_blackArrow = useDark;
|
||||
m_downArrow = m_rightArrow = null;
|
||||
}
|
||||
Drawable arrow;
|
||||
if ( vert ) {
|
||||
if ( null == m_downArrow ) {
|
||||
m_downArrow = loadAndRecolor( R.drawable.downarrow, useDark );
|
||||
}
|
||||
arrow = m_downArrow;
|
||||
} else {
|
||||
if ( null == m_rightArrow ) {
|
||||
m_rightArrow = loadAndRecolor( R.drawable.rightarrow, useDark );
|
||||
}
|
||||
arrow = m_rightArrow;
|
||||
}
|
||||
|
||||
rect.inset( 2, 2 );
|
||||
arrow.setBounds( rect );
|
||||
arrow.draw( BoardCanvas.this );
|
||||
|
||||
if ( !m_arrowHintShown ) {
|
||||
m_arrowHintShown = true;
|
||||
// Handler handler = getHandler();
|
||||
// if ( null != handler ) {
|
||||
// handler.post( new Runnable() {
|
||||
// public void run() {
|
||||
// m_parent.
|
||||
// showNotAgainDlgThen( R.string.not_again_arrow,
|
||||
// R.string.
|
||||
// key_notagain_arrow );
|
||||
// } } );
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public boolean trayBegin( Rect rect, int owner, int score )
|
||||
{
|
||||
m_trayOwner = owner;
|
||||
m_pendingScore = score;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean drawTile( Rect rect, String text, int val, int flags )
|
||||
{
|
||||
return drawTileImpl( rect, text, val, flags, true );
|
||||
}
|
||||
|
||||
public boolean drawTileMidDrag( Rect rect, String text, int val, int owner,
|
||||
int flags )
|
||||
{
|
||||
return drawTileImpl( rect, text, val, flags, false );
|
||||
}
|
||||
|
||||
public boolean drawTileBack( Rect rect, int flags )
|
||||
{
|
||||
return drawTileImpl( rect, "?", -1, flags, true );
|
||||
}
|
||||
|
||||
public void drawTrayDivider( Rect rect, int flags )
|
||||
{
|
||||
boolean isCursor = 0 != (flags & CELL_ISCURSOR);
|
||||
boolean selected = 0 != (flags & CELL_HIGHLIGHT);
|
||||
|
||||
int index = isCursor? CommonPrefs.COLOR_FOCUS : CommonPrefs.COLOR_BACKGRND;
|
||||
rect.inset( 0, 1 );
|
||||
fillRectOther( rect, index );
|
||||
|
||||
rect.inset( rect.width()/4, 0 );
|
||||
if ( selected ) {
|
||||
drawRect( rect, m_strokePaint );
|
||||
} else {
|
||||
fillRect( rect, m_playerColors[m_trayOwner] );
|
||||
}
|
||||
}
|
||||
|
||||
public void score_pendingScore( Rect rect, int score, int playerNum,
|
||||
int curTurn, int flags )
|
||||
{
|
||||
String text = score >= 0? String.format( "%d", score ) : "??";
|
||||
int otherIndx = (0 == (flags & CELL_ISCURSOR))
|
||||
? CommonPrefs.COLOR_BACKGRND : CommonPrefs.COLOR_FOCUS;
|
||||
++rect.top;
|
||||
fillRectOther( rect, otherIndx );
|
||||
|
||||
int playerColor = m_playerColors[playerNum];
|
||||
if ( playerNum != curTurn ) {
|
||||
playerColor &= NOT_TURN_ALPHA;
|
||||
}
|
||||
m_fillPaint.setColor( playerColor );
|
||||
|
||||
rect.bottom -= rect.height() / 2;
|
||||
drawCentered( text, rect, null );
|
||||
|
||||
rect.offset( 0, rect.height() );
|
||||
drawCentered( m_activity.getResources().getString( R.string.pts ),
|
||||
rect, null );
|
||||
}
|
||||
|
||||
public void objFinished( /*BoardObjectType*/int typ, Rect rect )
|
||||
{
|
||||
if ( DrawCtx.OBJ_BOARD == typ ) {
|
||||
// On squat screens, where I can't use the full width for
|
||||
// the board (without scrolling), the right-most cells
|
||||
// don't draw their right borders due to clipping, so draw
|
||||
// for them.
|
||||
m_strokePaint.setColor( adjustColor(FRAME_GREY) );
|
||||
int xx = rect.left + rect.width() - 1;
|
||||
drawLine( xx, rect.top, xx, rect.top + rect.height(),
|
||||
m_strokePaint );
|
||||
}
|
||||
}
|
||||
|
||||
public void dictChanged( final int dictPtr )
|
||||
{
|
||||
if ( m_dictPtr != dictPtr ) {
|
||||
if ( 0 == dictPtr ) {
|
||||
m_fontDims = null;
|
||||
m_dictChars = null;
|
||||
} else if ( m_dictPtr == 0 ||
|
||||
!XwJNI.dict_tilesAreSame( m_dictPtr, dictPtr ) ) {
|
||||
m_fontDims = null;
|
||||
m_dictChars = null;
|
||||
m_activity.runOnUiThread( new Runnable() {
|
||||
public void run() {
|
||||
m_dictChars = XwJNI.dict_getChars( dictPtr );
|
||||
// draw again
|
||||
if ( null != m_jniThread ) {
|
||||
m_jniThread.handle( JNIThread.JNICmd
|
||||
.CMD_INVALALL );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
m_dictPtr = dictPtr;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean drawTileImpl( Rect rect, String text, int val,
|
||||
int flags, boolean clearBack )
|
||||
{
|
||||
boolean canDraw = figureFontDims();
|
||||
if ( canDraw ) {
|
||||
// boolean valHidden = (flags & CELL_VALHIDDEN) != 0;
|
||||
boolean notEmpty = (flags & CELL_ISEMPTY) == 0;
|
||||
boolean isCursor = (flags & CELL_ISCURSOR) != 0;
|
||||
|
||||
save( Canvas.CLIP_SAVE_FLAG );
|
||||
rect.top += 1;
|
||||
clipRect( rect );
|
||||
|
||||
if ( clearBack ) {
|
||||
fillRectOther( rect, CommonPrefs.COLOR_BACKGRND );
|
||||
}
|
||||
|
||||
if ( isCursor || notEmpty ) {
|
||||
int color = m_otherColors[isCursor? CommonPrefs.COLOR_FOCUS
|
||||
: CommonPrefs.COLOR_TILE_BACK];
|
||||
if ( !clearBack ) {
|
||||
color &= 0x7FFFFFFF; // translucent if being dragged.
|
||||
}
|
||||
fillRect( rect, color );
|
||||
|
||||
m_fillPaint.setColor( m_playerColors[m_trayOwner] );
|
||||
|
||||
if ( notEmpty ) {
|
||||
positionDrawTile( rect, text, val );
|
||||
|
||||
Paint paint = getTileStrokePaint( rect );
|
||||
drawRect( rect, paint ); // frame
|
||||
if ( 0 != (flags & CELL_HIGHLIGHT) ) {
|
||||
int width = (int)paint.getStrokeWidth();
|
||||
rect.inset( width, width );
|
||||
drawRect( rect, paint ); // frame
|
||||
}
|
||||
}
|
||||
}
|
||||
restoreToCount(1); // in case new canvas....
|
||||
}
|
||||
return canDraw;
|
||||
} // drawTileImpl
|
||||
|
||||
private void drawCrosshairs( final Rect rect, final int flags )
|
||||
{
|
||||
int color = m_otherColors[CommonPrefs.COLOR_FOCUS];
|
||||
if ( 0 != (flags & CELL_CROSSHOR) ) {
|
||||
Rect hairRect = new Rect( rect );
|
||||
hairRect.inset( 0, hairRect.height() / 3 );
|
||||
fillRect( hairRect, color );
|
||||
}
|
||||
if ( 0 != (flags & CELL_CROSSVERT) ) {
|
||||
Rect hairRect = new Rect( rect );
|
||||
hairRect.inset( hairRect.width() / 3, 0 );
|
||||
fillRect( hairRect, color );
|
||||
}
|
||||
}
|
||||
|
||||
private void drawCentered( String text, Rect rect, FontDims fontDims )
|
||||
{
|
||||
drawIn( text, rect, fontDims, Paint.Align.CENTER );
|
||||
}
|
||||
|
||||
private void drawIn( String text, Rect rect, FontDims fontDims,
|
||||
Paint.Align align )
|
||||
{
|
||||
int descent = -1;
|
||||
int textSize;
|
||||
if ( null == fontDims ) {
|
||||
textSize = rect.height() - SCORE_HT_DROP;
|
||||
} else {
|
||||
int height = rect.height() - 4; // borders and padding, 2 each
|
||||
descent = fontDims.descentFor( height );
|
||||
textSize = fontDims.heightFor( height );
|
||||
// DbgUtils.logf( "using descent: " + descent + " and textSize: "
|
||||
// + textSize + " in height " + height );
|
||||
}
|
||||
m_fillPaint.setTextSize( textSize );
|
||||
if ( descent == -1 ) {
|
||||
descent = m_fillPaint.getFontMetricsInt().descent;
|
||||
}
|
||||
descent += 2;
|
||||
|
||||
m_fillPaint.getTextBounds( text, 0, text.length(), m_boundsScratch );
|
||||
int extra = rect.width() - m_boundsScratch.width();
|
||||
if ( 0 >= extra ) {
|
||||
m_fillPaint.setTextAlign( Paint.Align.LEFT );
|
||||
drawScaled( text, rect, m_boundsScratch, descent );
|
||||
} else {
|
||||
int bottom = rect.bottom - descent;
|
||||
int origin = rect.left;
|
||||
if ( Paint.Align.CENTER == align ) {
|
||||
origin += rect.width() / 2;
|
||||
} else {
|
||||
origin += (extra / 5) - m_boundsScratch.left;
|
||||
}
|
||||
m_fillPaint.setTextAlign( align );
|
||||
drawText( text, origin, bottom, m_fillPaint );
|
||||
}
|
||||
} // drawCentered
|
||||
|
||||
private void drawScaled( String text, final Rect rect,
|
||||
Rect textBounds, int descent )
|
||||
{
|
||||
textBounds.bottom = rect.height();
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap( textBounds.width(),
|
||||
rect.height(),
|
||||
Bitmap.Config.ARGB_8888 );
|
||||
|
||||
Canvas canvas = new Canvas( bitmap );
|
||||
int bottom = textBounds.bottom - descent;
|
||||
canvas.drawText( text, -textBounds.left, bottom, m_fillPaint );
|
||||
|
||||
drawBitmap( bitmap, null, rect, m_drawPaint );
|
||||
}
|
||||
|
||||
private void positionDrawTile( final Rect rect, String text, int val )
|
||||
{
|
||||
final int offset = 2;
|
||||
if ( null != text ) {
|
||||
if ( null == m_letterRect ) {
|
||||
m_letterRect = new Rect( 0, 0, rect.width() - offset,
|
||||
rect.height() * 3 / 4 );
|
||||
}
|
||||
m_letterRect.offsetTo( rect.left + offset, rect.top + offset );
|
||||
drawIn( text, m_letterRect, m_fontDims, Paint.Align.LEFT );
|
||||
if ( FRAME_TRAY_RECTS ) {
|
||||
drawRect( m_letterRect, m_strokePaint );
|
||||
}
|
||||
}
|
||||
|
||||
if ( val >= 0 ) {
|
||||
int divisor = m_hasSmallScreen ? 3 : 4;
|
||||
if ( null == m_valRect ) {
|
||||
m_valRect = new Rect( 0, 0, rect.width() / divisor,
|
||||
rect.height() / divisor );
|
||||
m_valRect.inset( offset, offset );
|
||||
}
|
||||
m_valRect.offsetTo( rect.right - (rect.width() / divisor),
|
||||
rect.bottom - (rect.height() / divisor) );
|
||||
text = String.format( "%d", val );
|
||||
m_fillPaint.setTextSize( m_valRect.height() );
|
||||
m_fillPaint.setTextAlign( Paint.Align.RIGHT );
|
||||
drawText( text, m_valRect.right, m_valRect.bottom,
|
||||
m_fillPaint );
|
||||
if ( FRAME_TRAY_RECTS ) {
|
||||
drawRect( m_valRect, m_strokePaint );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillRectOther( Rect rect, int index )
|
||||
{
|
||||
fillRect( rect, m_otherColors[index] );
|
||||
}
|
||||
|
||||
private void fillRect( Rect rect, int color )
|
||||
{
|
||||
m_fillPaint.setColor( color );
|
||||
drawRect( rect, m_fillPaint );
|
||||
}
|
||||
|
||||
private boolean figureFontDims()
|
||||
{
|
||||
if ( null == m_fontDims && null != m_dictChars ) {
|
||||
|
||||
final int ht = 24;
|
||||
final int width = 20;
|
||||
|
||||
Paint paint = new Paint(); // CommonPrefs.getFontFlags()??
|
||||
paint.setStyle( Paint.Style.STROKE );
|
||||
paint.setTextAlign( Paint.Align.LEFT );
|
||||
paint.setTextSize( ht );
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap( width, (ht*3)/2,
|
||||
Bitmap.Config.ARGB_8888 );
|
||||
Canvas canvas = new Canvas( bitmap );
|
||||
|
||||
// FontMetrics fmi = paint.getFontMetrics();
|
||||
// DbgUtils.logf( "ascent: " + fmi.ascent );
|
||||
// DbgUtils.logf( "bottom: " + fmi.bottom );
|
||||
// DbgUtils.logf( "descent: " + fmi.descent );
|
||||
// DbgUtils.logf( "leading: " + fmi.leading );
|
||||
// DbgUtils.logf( "top : " + fmi.top );
|
||||
|
||||
// DbgUtils.logf( "using as baseline: " + ht );
|
||||
|
||||
Rect bounds = new Rect();
|
||||
int maxWidth = 0;
|
||||
for ( String str : m_dictChars ) {
|
||||
if ( str.length() == 1 && str.charAt(0) >= 32 ) {
|
||||
canvas.drawText( str, 0, ht, paint );
|
||||
paint.getTextBounds( str, 0, 1, bounds );
|
||||
if ( maxWidth < bounds.right ) {
|
||||
maxWidth = bounds.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for ( int row = 0; row < bitmap.getHeight(); ++row ) {
|
||||
// StringBuffer sb = new StringBuffer( bitmap.getWidth() );
|
||||
// for ( int col = 0; col < bitmap.getWidth(); ++col ) {
|
||||
// int pixel = bitmap.getPixel( col, row );
|
||||
// sb.append( pixel==0? "." : "X" );
|
||||
// }
|
||||
// DbgUtils.logf( sb.append(row).toString() );
|
||||
// }
|
||||
|
||||
int topRow = 0;
|
||||
findTop:
|
||||
for ( int row = 0; row < bitmap.getHeight(); ++row ) {
|
||||
for ( int col = 0; col < bitmap.getWidth(); ++col ) {
|
||||
if ( 0 != bitmap.getPixel( col, row ) ){
|
||||
topRow = row;
|
||||
break findTop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int bottomRow = 0;
|
||||
findBottom:
|
||||
for ( int row = bitmap.getHeight() - 1; row > topRow; --row ) {
|
||||
for ( int col = 0; col < bitmap.getWidth(); ++col ) {
|
||||
if ( 0 != bitmap.getPixel( col, row ) ){
|
||||
bottomRow = row;
|
||||
break findBottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_fontDims = new FontDims( ht, topRow, bottomRow, maxWidth );
|
||||
}
|
||||
return null != m_fontDims;
|
||||
} // figureFontDims
|
||||
|
||||
private int adjustColor( int color )
|
||||
{
|
||||
if ( m_inTrade ) {
|
||||
color = color & IN_TRADE_ALPHA;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
private boolean darkOnLight()
|
||||
{
|
||||
int background = m_otherColors[ CommonPrefs.COLOR_NOTILE ];
|
||||
if ( background != m_backgroundUsed ) {
|
||||
m_backgroundUsed = background;
|
||||
m_darkOnLight = isLightColor( background );
|
||||
}
|
||||
return m_darkOnLight;
|
||||
}
|
||||
|
||||
private void markBlank( final Rect rect, int backColor )
|
||||
{
|
||||
RectF oval = new RectF( rect.left, rect.top, rect.right, rect.bottom );
|
||||
int curColor = 0;
|
||||
boolean whiteOnBlack = !isLightColor( backColor );
|
||||
if ( whiteOnBlack ) {
|
||||
curColor = m_strokePaint.getColor();
|
||||
m_strokePaint.setColor( WHITE );
|
||||
}
|
||||
drawArc( oval, 0, 360, false, m_strokePaint );
|
||||
if ( whiteOnBlack ) {
|
||||
m_strokePaint.setColor( curColor );
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable loadAndRecolor( int resID, boolean useDark )
|
||||
{
|
||||
Resources res = m_activity.getResources();
|
||||
Drawable arrow = res.getDrawable( resID );
|
||||
|
||||
if ( !useDark ) {
|
||||
Bitmap src = ((BitmapDrawable)arrow).getBitmap();
|
||||
Bitmap bitmap = src.copy( Bitmap.Config.ARGB_8888, true );
|
||||
for ( int xx = 0; xx < bitmap.getWidth(); ++xx ) {
|
||||
for( int yy = 0; yy < bitmap.getHeight(); ++yy ) {
|
||||
if ( BLACK == bitmap.getPixel( xx, yy ) ) {
|
||||
bitmap.setPixel( xx, yy, WHITE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arrow = new BitmapDrawable(bitmap);
|
||||
}
|
||||
return arrow;
|
||||
}
|
||||
|
||||
private boolean isLightColor( int color )
|
||||
{
|
||||
int sum = 0;
|
||||
for ( int ii = 0; ii < 3; ++ii ) {
|
||||
sum += color & 0xFF;
|
||||
color >>= 8;
|
||||
}
|
||||
boolean result = sum > (127*3);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Paint getTileStrokePaint( final Rect rect )
|
||||
{
|
||||
if ( null == m_tileStrokePaint ) {
|
||||
Paint paint = new Paint();
|
||||
paint.setStyle( Paint.Style.STROKE );
|
||||
paint.setStrokeWidth( Math.max( 2, rect.width() / 20 ) );
|
||||
m_tileStrokePaint = paint;
|
||||
}
|
||||
return m_tileStrokePaint;
|
||||
}
|
||||
|
||||
}
|
|
@ -23,9 +23,10 @@ package org.eehouse.android.xw4;
|
|||
|
||||
// Why does this have to be its own class...
|
||||
public class BoardDims {
|
||||
public int left, top;
|
||||
public int width, height; // of the bitmap
|
||||
public int scoreHt;
|
||||
public int boardHt;
|
||||
public int scoreWidth, scoreHt;
|
||||
public int boardWidth, boardHt;
|
||||
public int trayTop, trayHt;
|
||||
public int cellSize, maxCellSize;
|
||||
public int timerWidth;
|
||||
|
@ -37,6 +38,7 @@ public class BoardDims {
|
|||
// + " left: " + left
|
||||
// + " top: " + top
|
||||
// + " scoreHt: " + scoreHt
|
||||
// + " scoreWidth: " + scoreWidth
|
||||
// + " boardHt: " + boardHt
|
||||
// + " trayTop: " + trayTop
|
||||
// + " trayHt: " + trayHt
|
||||
|
|
|
@ -40,7 +40,7 @@ public class ChatActivity extends XWActivity implements View.OnClickListener {
|
|||
@Override
|
||||
public void onCreate( Bundle savedInstanceState )
|
||||
{
|
||||
if ( GitVersion.CHAT_SUPPORTED ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED ) {
|
||||
super.onCreate( savedInstanceState );
|
||||
|
||||
setContentView( R.layout.chat );
|
||||
|
|
|
@ -37,7 +37,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||
public static final String TABLE_NAME_DICTINFO = "dictinfo";
|
||||
public static final String TABLE_NAME_GROUPS = "groups";
|
||||
private static final String DB_NAME = "xwdb";
|
||||
private static final int DB_VERSION = 17;
|
||||
private static final int DB_VERSION = 18;
|
||||
|
||||
public static final String GAME_NAME = "GAME_NAME";
|
||||
public static final String VISID = "VISID";
|
||||
|
@ -59,6 +59,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||
public static final String HASMSGS = "HASMSGS";
|
||||
public static final String CONTRACTED = "CONTRACTED";
|
||||
public static final String SNAPSHOT = "SNAPSHOT";
|
||||
public static final String THUMBNAIL = "THUMBNAIL";
|
||||
public static final String CONTYPE = "CONTYPE";
|
||||
public static final String SERVERROLE = "SERVERROLE";
|
||||
public static final String ROOMNAME = "ROOMNAME";
|
||||
|
@ -120,6 +121,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||
,{ CREATE_TIME, "INTEGER" }
|
||||
,{ LASTPLAY_TIME,"INTEGER" }
|
||||
,{ SNAPSHOT, "BLOB" }
|
||||
,{ THUMBNAIL, "BLOB" }
|
||||
};
|
||||
|
||||
private static final String[][] s_obitsColsAndTypes = {
|
||||
|
@ -211,6 +213,8 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||
addSumColumn( db, VISID );
|
||||
setColumnsEqual( db, TABLE_NAME_SUM, VISID, "rowid" );
|
||||
makeAutoincrement( db, TABLE_NAME_SUM, s_summaryColsAndTypes );
|
||||
case 17:
|
||||
addSumColumn( db, THUMBNAIL );
|
||||
// nothing yet
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -25,15 +25,21 @@ import android.content.Context;
|
|||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -41,7 +47,6 @@ import java.util.HashSet;
|
|||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.jni.*;
|
||||
|
@ -50,6 +55,7 @@ import org.eehouse.android.xw4.DictUtils.DictLoc;
|
|||
|
||||
public class DBUtils {
|
||||
public static final int ROWID_NOTFOUND = -1;
|
||||
public static final int GROUPID_UNSPEC = -1;
|
||||
|
||||
private static final String DICTS_SEP = ",";
|
||||
|
||||
|
@ -118,24 +124,23 @@ public class DBUtils {
|
|||
{
|
||||
initDB( context );
|
||||
GameSummary summary = null;
|
||||
String[] columns = { ROW_ID,
|
||||
DBHelper.NUM_MOVES, DBHelper.NUM_PLAYERS,
|
||||
DBHelper.MISSINGPLYRS,
|
||||
DBHelper.GAME_OVER, DBHelper.PLAYERS,
|
||||
DBHelper.TURN, DBHelper.GIFLAGS,
|
||||
DBHelper.CONTYPE, DBHelper.SERVERROLE,
|
||||
DBHelper.ROOMNAME, DBHelper.RELAYID,
|
||||
/*DBHelper.SMSPHONE,*/ DBHelper.SEED,
|
||||
DBHelper.DICTLANG, DBHelper.GAMEID,
|
||||
DBHelper.SCORES, DBHelper.HASMSGS,
|
||||
DBHelper.LASTPLAY_TIME, DBHelper.REMOTEDEVS,
|
||||
DBHelper.LASTMOVE, DBHelper.THUMBNAIL
|
||||
};
|
||||
String selection = String.format( ROW_ID_FMT, lock.getRowid() );
|
||||
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { ROW_ID,
|
||||
DBHelper.NUM_MOVES, DBHelper.NUM_PLAYERS,
|
||||
DBHelper.MISSINGPLYRS,
|
||||
DBHelper.GAME_OVER, DBHelper.PLAYERS,
|
||||
DBHelper.TURN, DBHelper.GIFLAGS,
|
||||
DBHelper.CONTYPE, DBHelper.SERVERROLE,
|
||||
DBHelper.ROOMNAME, DBHelper.RELAYID,
|
||||
/*DBHelper.SMSPHONE,*/ DBHelper.SEED,
|
||||
DBHelper.DICTLANG, DBHelper.GAMEID,
|
||||
DBHelper.SCORES, DBHelper.HASMSGS,
|
||||
DBHelper.LASTPLAY_TIME, DBHelper.REMOTEDEVS,
|
||||
DBHelper.LASTMOVE
|
||||
};
|
||||
String selection = String.format( ROW_ID_FMT, lock.getRowid() );
|
||||
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
|
@ -179,6 +184,18 @@ public class DBUtils {
|
|||
summary.lastMoveTime =
|
||||
cursor.getInt(cursor.getColumnIndex(DBHelper.LASTMOVE));
|
||||
|
||||
if ( BuildConstants.THUMBNAIL_SUPPORTED ) {
|
||||
byte[] data =
|
||||
cursor.getBlob( cursor.
|
||||
getColumnIndex(DBHelper.THUMBNAIL));
|
||||
if ( null != data ) {
|
||||
Bitmap thumb =
|
||||
BitmapFactory.decodeByteArray( data, 0,
|
||||
data.length );
|
||||
summary.setThumbnail( thumb );
|
||||
}
|
||||
}
|
||||
|
||||
String scoresStr =
|
||||
cursor.getString( cursor.getColumnIndex(DBHelper.SCORES));
|
||||
int[] scores = new int[summary.nPlayers];
|
||||
|
@ -239,7 +256,7 @@ public class DBUtils {
|
|||
db.close();
|
||||
}
|
||||
|
||||
if ( null == summary ) {
|
||||
if ( null == summary && lock.canWrite() ) {
|
||||
summary = GameUtils.summarize( context, lock );
|
||||
saveSummary( context, lock, summary );
|
||||
}
|
||||
|
@ -259,6 +276,56 @@ public class DBUtils {
|
|||
long rowid = lock.getRowid();
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
|
||||
ContentValues values = null;
|
||||
if ( null != summary ) {
|
||||
values = new ContentValues();
|
||||
values.put( DBHelper.NUM_MOVES, summary.nMoves );
|
||||
values.put( DBHelper.NUM_PLAYERS, summary.nPlayers );
|
||||
values.put( DBHelper.MISSINGPLYRS, summary.missingPlayers );
|
||||
values.put( DBHelper.TURN, summary.turn );
|
||||
values.put( DBHelper.GIFLAGS, summary.giflags() );
|
||||
values.put( DBHelper.PLAYERS,
|
||||
summary.summarizePlayers() );
|
||||
values.put( DBHelper.DICTLANG, summary.dictLang );
|
||||
values.put( DBHelper.GAMEID, summary.gameID );
|
||||
values.put( DBHelper.GAME_OVER, summary.gameOver? 1 : 0 );
|
||||
values.put( DBHelper.LASTMOVE, summary.lastMoveTime );
|
||||
|
||||
values.put( DBHelper.DICTLIST, summary.dictNames(DICTS_SEP) );
|
||||
values.put( DBHelper.HASMSGS, summary.pendingMsgLevel );
|
||||
if ( null != inviteID ) {
|
||||
values.put( DBHelper.INVITEID, inviteID );
|
||||
}
|
||||
|
||||
if ( null != summary.scores ) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for ( int score : summary.scores ) {
|
||||
sb.append( String.format( "%d ", score ) );
|
||||
}
|
||||
values.put( DBHelper.SCORES, sb.toString() );
|
||||
}
|
||||
|
||||
if ( null != summary.conType ) {
|
||||
values.put( DBHelper.CONTYPE, summary.conType.ordinal() );
|
||||
values.put( DBHelper.SEED, summary.seed );
|
||||
switch( summary.conType ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
values.put( DBHelper.ROOMNAME, summary.roomName );
|
||||
values.put( DBHelper.RELAYID, summary.relayID );
|
||||
break;
|
||||
case COMMS_CONN_BT:
|
||||
case COMMS_CONN_SMS:
|
||||
values.put( DBHelper.REMOTEDEVS,
|
||||
summary.summarizeDevs() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
values.put( DBHelper.SERVERROLE, summary.serverRole.ordinal() );
|
||||
|
||||
addThumb( summary.getThumbnail(), values );
|
||||
}
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
|
@ -266,50 +333,6 @@ public class DBUtils {
|
|||
if ( null == summary ) {
|
||||
db.delete( DBHelper.TABLE_NAME_SUM, selection, null );
|
||||
} else {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.NUM_MOVES, summary.nMoves );
|
||||
values.put( DBHelper.NUM_PLAYERS, summary.nPlayers );
|
||||
values.put( DBHelper.MISSINGPLYRS, summary.missingPlayers );
|
||||
values.put( DBHelper.TURN, summary.turn );
|
||||
values.put( DBHelper.GIFLAGS, summary.giflags() );
|
||||
values.put( DBHelper.PLAYERS,
|
||||
summary.summarizePlayers() );
|
||||
values.put( DBHelper.DICTLANG, summary.dictLang );
|
||||
values.put( DBHelper.GAMEID, summary.gameID );
|
||||
values.put( DBHelper.GAME_OVER, summary.gameOver? 1 : 0 );
|
||||
values.put( DBHelper.LASTMOVE, summary.lastMoveTime );
|
||||
|
||||
values.put( DBHelper.DICTLIST, summary.dictNames(DICTS_SEP) );
|
||||
values.put( DBHelper.HASMSGS, summary.pendingMsgLevel );
|
||||
if ( null != inviteID ) {
|
||||
values.put( DBHelper.INVITEID, inviteID );
|
||||
}
|
||||
|
||||
if ( null != summary.scores ) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for ( int score : summary.scores ) {
|
||||
sb.append( String.format( "%d ", score ) );
|
||||
}
|
||||
values.put( DBHelper.SCORES, sb.toString() );
|
||||
}
|
||||
|
||||
if ( null != summary.conType ) {
|
||||
values.put( DBHelper.CONTYPE, summary.conType.ordinal() );
|
||||
values.put( DBHelper.SEED, summary.seed );
|
||||
switch( summary.conType ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
values.put( DBHelper.ROOMNAME, summary.roomName );
|
||||
values.put( DBHelper.RELAYID, summary.relayID );
|
||||
break;
|
||||
case COMMS_CONN_BT:
|
||||
case COMMS_CONN_SMS:
|
||||
values.put( DBHelper.REMOTEDEVS,
|
||||
summary.summarizeDevs() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
values.put( DBHelper.SERVERROLE, summary.serverRole.ordinal() );
|
||||
|
||||
long result = db.update( DBHelper.TABLE_NAME_SUM,
|
||||
values, selection, null );
|
||||
Assert.assertTrue( result >= 0 );
|
||||
|
@ -323,13 +346,13 @@ public class DBUtils {
|
|||
public static int countGamesUsingLang( Context context, int lang )
|
||||
{
|
||||
int result = 0;
|
||||
String selection = String.format( "%s = %d", DBHelper.DICTLANG,
|
||||
lang );
|
||||
// null for columns will return whole rows: bad
|
||||
String[] columns = { DBHelper.DICTLANG };
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String selection = String.format( "%s = %d", DBHelper.DICTLANG,
|
||||
lang );
|
||||
// null for columns will return whole rows: bad
|
||||
String[] columns = { DBHelper.DICTLANG };
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
|
||||
|
@ -343,16 +366,16 @@ public class DBUtils {
|
|||
public static int countGamesUsingDict( Context context, String dict )
|
||||
{
|
||||
int result = 0;
|
||||
String pattern = String.format( "%%%s%s%s%%",
|
||||
DICTS_SEP, dict, DICTS_SEP );
|
||||
String selection = String.format( "%s LIKE '%s'",
|
||||
DBHelper.DICTLIST, pattern );
|
||||
// null for columns will return whole rows: bad. But
|
||||
// might as well make it an int for speed
|
||||
String[] columns = { DBHelper.DICTLANG };
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String pattern = String.format( "%%%s%s%s%%",
|
||||
DICTS_SEP, dict, DICTS_SEP );
|
||||
String selection = String.format( "%s LIKE '%s'",
|
||||
DBHelper.DICTLIST, pattern );
|
||||
// null for columns will return whole rows: bad. But
|
||||
// might as well make it an int for speed
|
||||
String[] columns = { DBHelper.DICTLANG };
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
result = cursor.getCount();
|
||||
|
@ -384,11 +407,11 @@ public class DBUtils {
|
|||
int dflt )
|
||||
{
|
||||
int result = dflt;
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
String[] columns = { column };
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
String[] columns = { column };
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
|
@ -417,14 +440,54 @@ public class DBUtils {
|
|||
return 0 != getInt( context, rowid, DBHelper.GAME_OVER, 0 );
|
||||
}
|
||||
|
||||
public static void saveThumbnail( Context context, GameLock lock,
|
||||
Bitmap thumb )
|
||||
{
|
||||
if ( BuildConstants.THUMBNAIL_SUPPORTED ) {
|
||||
long rowid = lock.getRowid();
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
ContentValues values = new ContentValues();
|
||||
addThumb( thumb, values );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
|
||||
long result = db.update( DBHelper.TABLE_NAME_SUM,
|
||||
values, selection, null );
|
||||
Assert.assertTrue( result >= 0 );
|
||||
|
||||
db.close();
|
||||
|
||||
notifyListeners( rowid, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearThumbnails( Context context )
|
||||
{
|
||||
if ( BuildConstants.THUMBNAIL_SUPPORTED ) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.putNull( DBHelper.THUMBNAIL );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
long result = db.update( DBHelper.TABLE_NAME_SUM,
|
||||
values, null, null );
|
||||
db.close();
|
||||
|
||||
notifyListeners( -1, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getRelayID( Context context, long rowid )
|
||||
{
|
||||
String result = null;
|
||||
String[] columns = { DBHelper.RELAYID };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { DBHelper.RELAYID };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
|
@ -440,11 +503,11 @@ public class DBUtils {
|
|||
public static long[] getRowIDsFor( Context context, String relayID )
|
||||
{
|
||||
long[] result = null;
|
||||
String[] columns = { ROW_ID };
|
||||
String selection = DBHelper.RELAYID + "='" + relayID + "'";
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { ROW_ID };
|
||||
String selection = DBHelper.RELAYID + "='" + relayID + "'";
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
result = new long[cursor.getCount()];
|
||||
|
@ -460,11 +523,11 @@ public class DBUtils {
|
|||
public static long[] getRowIDsFor( Context context, int gameID )
|
||||
{
|
||||
long[] result = null;
|
||||
String[] columns = { ROW_ID };
|
||||
String selection = String.format( DBHelper.GAMEID + "=%d", gameID );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { ROW_ID };
|
||||
String selection = String.format( DBHelper.GAMEID + "=%d", gameID );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
result = new long[cursor.getCount()];
|
||||
|
@ -484,11 +547,11 @@ public class DBUtils {
|
|||
public static boolean haveGame( Context context, long rowid )
|
||||
{
|
||||
boolean result = false;
|
||||
String[] columns = { ROW_ID };
|
||||
String selection = String.format( ROW_ID + "=%d", rowid );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { ROW_ID };
|
||||
String selection = String.format( ROW_ID + "=%d", rowid );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
Assert.assertTrue( 1 >= cursor.getCount() );
|
||||
|
@ -554,16 +617,16 @@ public class DBUtils {
|
|||
NetLaunchInfo nli )
|
||||
{
|
||||
Date result = null;
|
||||
String[] columns = { DBHelper.CREATE_TIME };
|
||||
String selection =
|
||||
String.format( "%s='%s' AND %s='%s' AND %s=%d AND %s=%d",
|
||||
DBHelper.ROOMNAME, nli.room,
|
||||
DBHelper.INVITEID, nli.inviteID,
|
||||
DBHelper.DICTLANG, nli.lang,
|
||||
DBHelper.NUM_PLAYERS, nli.nPlayersT );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { DBHelper.CREATE_TIME };
|
||||
String selection =
|
||||
String.format( "%s='%s' AND %s='%s' AND %s=%d AND %s=%d",
|
||||
DBHelper.ROOMNAME, nli.room,
|
||||
DBHelper.INVITEID, nli.inviteID,
|
||||
DBHelper.DICTLANG, nli.lang,
|
||||
DBHelper.NUM_PLAYERS, nli.nPlayersT );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null,
|
||||
DBHelper.CREATE_TIME + " DESC" ); // order by
|
||||
|
@ -590,13 +653,13 @@ public class DBUtils {
|
|||
public static String[] getRelayIDs( Context context, long[][] rowIDs )
|
||||
{
|
||||
String[] result = null;
|
||||
initDB( context );
|
||||
String[] columns = { ROW_ID, DBHelper.RELAYID };
|
||||
String selection = DBHelper.RELAYID + " NOT null";
|
||||
ArrayList<String> ids = new ArrayList<String>();
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { ROW_ID, DBHelper.RELAYID };
|
||||
String selection = DBHelper.RELAYID + " NOT null";
|
||||
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
|
@ -626,14 +689,14 @@ public class DBUtils {
|
|||
public static void addDeceased( Context context, String relayID,
|
||||
int seed )
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.RELAYID, relayID );
|
||||
values.put( DBHelper.SEED, seed );
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.RELAYID, relayID );
|
||||
values.put( DBHelper.SEED, seed );
|
||||
|
||||
try {
|
||||
long result = db.replaceOrThrow( DBHelper.TABLE_NAME_OBITS,
|
||||
"", values );
|
||||
|
@ -648,11 +711,11 @@ public class DBUtils {
|
|||
{
|
||||
Obit[] result = null;
|
||||
ArrayList<Obit> al = new ArrayList<Obit>();
|
||||
String[] columns = { DBHelper.RELAYID, DBHelper.SEED };
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { DBHelper.RELAYID, DBHelper.SEED };
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_OBITS, columns,
|
||||
null, null, null, null, null );
|
||||
if ( 0 < cursor.getCount() ) {
|
||||
|
@ -693,25 +756,27 @@ public class DBUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static GameLock saveNewGame( Context context, byte[] bytes )
|
||||
public static GameLock saveNewGame( Context context, byte[] bytes,
|
||||
long groupID )
|
||||
{
|
||||
Assert.assertTrue( GROUPID_UNSPEC != groupID );
|
||||
GameLock lock = null;
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.SNAPSHOT, bytes );
|
||||
|
||||
long timestamp = new Date().getTime();
|
||||
values.put( DBHelper.CREATE_TIME, timestamp );
|
||||
values.put( DBHelper.LASTPLAY_TIME, timestamp );
|
||||
values.put( DBHelper.GROUPID, groupID );
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.SNAPSHOT, bytes );
|
||||
|
||||
long timestamp = new Date().getTime();
|
||||
values.put( DBHelper.CREATE_TIME, timestamp );
|
||||
values.put( DBHelper.LASTPLAY_TIME, timestamp );
|
||||
values.put( DBHelper.GROUPID,
|
||||
XWPrefs.getDefaultNewGameGroup( context ) );
|
||||
values.put( DBHelper.VISID, maxVISID( db ) );
|
||||
|
||||
long rowid = db.insert( DBHelper.TABLE_NAME_SUM, null, values );
|
||||
db.close();
|
||||
|
||||
setCached( rowid, null ); // force reread
|
||||
|
||||
|
@ -740,7 +805,7 @@ public class DBUtils {
|
|||
updateRow( context, DBHelper.TABLE_NAME_SUM, rowid, values );
|
||||
|
||||
setCached( rowid, null ); // force reread
|
||||
if ( -1 != rowid ) { // Means new game?
|
||||
if ( ROWID_NOTFOUND != rowid ) { // Means new game?
|
||||
notifyListeners( rowid, false );
|
||||
}
|
||||
invalGroupsCache();
|
||||
|
@ -750,15 +815,15 @@ public class DBUtils {
|
|||
public static byte[] loadGame( Context context, GameLock lock )
|
||||
{
|
||||
long rowid = lock.getRowid();
|
||||
Assert.assertTrue( -1 != rowid );
|
||||
Assert.assertTrue( ROWID_NOTFOUND != rowid );
|
||||
byte[] result = getCached( rowid );
|
||||
if ( null == result ) {
|
||||
String[] columns = { DBHelper.SNAPSHOT };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
|
||||
String[] columns = { DBHelper.SNAPSHOT };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
|
@ -790,10 +855,10 @@ public class DBUtils {
|
|||
public static void deleteGame( Context context, GameLock lock )
|
||||
{
|
||||
Assert.assertTrue( lock.canWrite() );
|
||||
String selection = String.format( ROW_ID_FMT, lock.getRowid() );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
String selection = String.format( ROW_ID_FMT, lock.getRowid() );
|
||||
db.delete( DBHelper.TABLE_NAME_SUM, selection, null );
|
||||
db.close();
|
||||
}
|
||||
|
@ -802,13 +867,13 @@ public class DBUtils {
|
|||
|
||||
public static int getVisID( Context context, long rowid )
|
||||
{
|
||||
int result = -1;
|
||||
int result = ROWID_NOTFOUND;
|
||||
String[] columns = { DBHelper.VISID };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
|
||||
String[] columns = { DBHelper.VISID };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
|
@ -826,12 +891,12 @@ public class DBUtils {
|
|||
public static String getName( Context context, long rowid )
|
||||
{
|
||||
String result = null;
|
||||
String[] columns = { DBHelper.GAME_NAME };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
|
||||
String[] columns = { DBHelper.GAME_NAME };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
|
@ -855,7 +920,7 @@ public class DBUtils {
|
|||
public static HistoryPair[] getChatHistory( Context context, long rowid )
|
||||
{
|
||||
HistoryPair[] result = null;
|
||||
if ( GitVersion.CHAT_SUPPORTED ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED ) {
|
||||
final String localPrefix = context.getString( R.string.chat_local_id );
|
||||
String history = getChatHistoryStr( context, rowid );
|
||||
if ( null != history ) {
|
||||
|
@ -892,9 +957,26 @@ public class DBUtils {
|
|||
s_groupsCache = null;
|
||||
}
|
||||
|
||||
private static void addThumb( Bitmap thumb, ContentValues values )
|
||||
{
|
||||
if ( null == thumb ) {
|
||||
values.putNull( DBHelper.THUMBNAIL );
|
||||
} else {
|
||||
ByteArrayOutputStream bas = new ByteArrayOutputStream();
|
||||
thumb.compress( CompressFormat.PNG, 0, bas );
|
||||
values.put( DBHelper.THUMBNAIL, bas.toByteArray() );
|
||||
}
|
||||
}
|
||||
|
||||
// Return map of string (group name) to info about all games in
|
||||
// that group.
|
||||
public static HashMap<Long,GameGroupInfo> getGroups( Context context )
|
||||
{
|
||||
return getGroups( context, 0 );
|
||||
}
|
||||
|
||||
private static HashMap<Long,GameGroupInfo> getGroups( Context context,
|
||||
int nRows )
|
||||
{
|
||||
if ( null == s_groupsCache ) {
|
||||
HashMap<Long,GameGroupInfo> result =
|
||||
|
@ -902,6 +984,7 @@ public class DBUtils {
|
|||
initDB( context );
|
||||
String[] columns = { ROW_ID, DBHelper.GROUPNAME,
|
||||
DBHelper.EXPANDED };
|
||||
String limit = 0 == nRows ? null : String.format( "%d", nRows );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_GROUPS, columns,
|
||||
|
@ -909,7 +992,8 @@ public class DBUtils {
|
|||
null, // args
|
||||
null, // groupBy
|
||||
null, // having
|
||||
null //orderby
|
||||
null, //orderby
|
||||
limit
|
||||
);
|
||||
int idIndex = cursor.getColumnIndex( ROW_ID );
|
||||
int nameIndex = cursor.getColumnIndex( DBHelper.GROUPNAME );
|
||||
|
@ -926,9 +1010,9 @@ public class DBUtils {
|
|||
|
||||
Iterator<Long> iter = result.keySet().iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
Long id = iter.next();
|
||||
GameGroupInfo ggi = result.get( id );
|
||||
readTurnInfo( db, id, ggi );
|
||||
Long groupID = iter.next();
|
||||
GameGroupInfo ggi = result.get( groupID );
|
||||
readTurnInfo( db, groupID, ggi );
|
||||
}
|
||||
|
||||
db.close();
|
||||
|
@ -938,13 +1022,31 @@ public class DBUtils {
|
|||
return s_groupsCache;
|
||||
} // getGroups
|
||||
|
||||
private static void readTurnInfo( SQLiteDatabase db, long id,
|
||||
// public static void unhideTo( Context context, long groupID )
|
||||
// {
|
||||
// Assert.assertTrue( GROUPID_UNSPEC != groupID );
|
||||
// initDB( context );
|
||||
// synchronized( s_dbHelper ) {
|
||||
// SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
// ContentValues values = new ContentValues();
|
||||
// values.put( DBHelper.GROUPID, groupID );
|
||||
// String selection = String.format( "%s = %d", DBHelper.GROUPID,
|
||||
// GROUPID_UNSPEC );
|
||||
// long result = db.update( DBHelper.TABLE_NAME_SUM,
|
||||
// values, selection, null );
|
||||
// db.close();
|
||||
|
||||
// notifyListeners( ROWID_NOTFOUND, true );
|
||||
// }
|
||||
// }
|
||||
|
||||
private static void readTurnInfo( SQLiteDatabase db, long groupID,
|
||||
GameGroupInfo ggi )
|
||||
{
|
||||
String[] columns = { DBHelper.LASTMOVE, DBHelper.GIFLAGS,
|
||||
DBHelper.TURN };
|
||||
String orderBy = DBHelper.LASTMOVE;
|
||||
String selection = String.format( "%s=%d", DBHelper.GROUPID, id );
|
||||
String selection = String.format( "%s=%d", DBHelper.GROUPID, groupID );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection,
|
||||
null, // args
|
||||
|
@ -997,9 +1099,9 @@ public class DBUtils {
|
|||
initDB( context );
|
||||
String[] columns = { ROW_ID };
|
||||
String selection = String.format( "%s=%d", DBHelper.GROUPID, groupID );
|
||||
String orderBy = DBHelper.CREATE_TIME + " DESC";
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String orderBy = DBHelper.CREATE_TIME + " DESC";
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, // selection
|
||||
null, // args
|
||||
|
@ -1020,39 +1122,21 @@ public class DBUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static Set<Long> getAllGames( Context context )
|
||||
{
|
||||
HashSet<Long> result = null;
|
||||
initDB( context );
|
||||
String[] columns = { ROW_ID };
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
null, // selection
|
||||
null, // args
|
||||
null, // groupBy
|
||||
null, // having
|
||||
null
|
||||
);
|
||||
int index = cursor.getColumnIndex( ROW_ID );
|
||||
result = new HashSet<Long>( cursor.getCount() );
|
||||
for ( int ii = 0; cursor.moveToNext(); ++ii ) {
|
||||
long rowid = cursor.getInt( index );
|
||||
result.add( rowid );
|
||||
}
|
||||
cursor.close();
|
||||
db.close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// pass ROWID_NOTFOUND to get *any* group. Because there may be
|
||||
// some hidden games stored with group = -1 thanks to
|
||||
// recently-fixed bugs, be sure to skip them.
|
||||
public static long getGroupForGame( Context context, long rowid )
|
||||
{
|
||||
long result = ROWID_NOTFOUND;
|
||||
long result = GROUPID_UNSPEC;
|
||||
initDB( context );
|
||||
String[] columns = { DBHelper.GROUPID };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
|
||||
String selection = String.format( "%s != %d", DBHelper.GROUPID,
|
||||
DBUtils.GROUPID_UNSPEC );
|
||||
if ( ROWID_NOTFOUND != rowid ) {
|
||||
selection += " AND " + String.format( ROW_ID_FMT, rowid );
|
||||
}
|
||||
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
|
@ -1072,15 +1156,27 @@ public class DBUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static long getAnyGroup( Context context )
|
||||
{
|
||||
long result = GROUPID_UNSPEC;
|
||||
HashMap<Long,GameGroupInfo> groups = getGroups( context, 1 );
|
||||
Iterator<Long> iter = groups.keySet().iterator();
|
||||
if ( iter.hasNext() ) {
|
||||
result = iter.next();
|
||||
}
|
||||
Assert.assertTrue( GROUPID_UNSPEC != result );
|
||||
return result;
|
||||
}
|
||||
|
||||
public static long addGroup( Context context, String name )
|
||||
{
|
||||
long rowid = ROWID_NOTFOUND;
|
||||
long rowid = GROUPID_UNSPEC;
|
||||
if ( null != name && 0 < name.length() ) {
|
||||
HashMap<Long,GameGroupInfo> gameInfo = getGroups( context );
|
||||
if ( null == gameInfo.get( name ) ) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.GROUPNAME, name );
|
||||
values.put( DBHelper.EXPANDED, 0 );
|
||||
values.put( DBHelper.EXPANDED, 1 );
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
|
@ -1097,17 +1193,17 @@ public class DBUtils {
|
|||
|
||||
public static void deleteGroup( Context context, long groupid )
|
||||
{
|
||||
// Nuke games having this group id
|
||||
String selection =
|
||||
String.format( "%s=%d", DBHelper.GROUPID, groupid );
|
||||
|
||||
// And nuke the group record itself
|
||||
selection = String.format( ROW_ID_FMT, groupid );
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
|
||||
// Nuke games having this group id
|
||||
String selection =
|
||||
String.format( "%s=%d", DBHelper.GROUPID, groupid );
|
||||
db.delete( DBHelper.TABLE_NAME_SUM, selection, null );
|
||||
|
||||
// And nuke the group record itself
|
||||
selection = String.format( ROW_ID_FMT, groupid );
|
||||
db.delete( DBHelper.TABLE_NAME_GROUPS, selection, null );
|
||||
|
||||
db.close();
|
||||
|
@ -1134,23 +1230,24 @@ public class DBUtils {
|
|||
}
|
||||
|
||||
// Change group id of a game
|
||||
public static void moveGame( Context context, long gameid, long groupid )
|
||||
public static void moveGame( Context context, long gameid, long groupID )
|
||||
{
|
||||
Assert.assertTrue( GROUPID_UNSPEC != groupID );
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.GROUPID, groupid );
|
||||
values.put( DBHelper.GROUPID, groupID );
|
||||
updateRow( context, DBHelper.TABLE_NAME_SUM, gameid, values );
|
||||
}
|
||||
|
||||
private static String getChatHistoryStr( Context context, long rowid )
|
||||
{
|
||||
String result = null;
|
||||
if ( GitVersion.CHAT_SUPPORTED ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED ) {
|
||||
String[] columns = { DBHelper.CHAT_HISTORY };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
|
||||
String[] columns = { DBHelper.CHAT_HISTORY };
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
|
@ -1169,7 +1266,7 @@ public class DBUtils {
|
|||
public static void appendChatHistory( Context context, long rowid,
|
||||
String msg, boolean local )
|
||||
{
|
||||
if ( GitVersion.CHAT_SUPPORTED ) {
|
||||
if ( BuildConstants.CHAT_SUPPORTED ) {
|
||||
Assert.assertNotNull( msg );
|
||||
int id = local ? R.string.chat_local_id : R.string.chat_other_id;
|
||||
msg = context.getString( id ) + msg;
|
||||
|
@ -1246,15 +1343,15 @@ public class DBUtils {
|
|||
{
|
||||
Assert.assertTrue( DictLoc.UNKNOWN != loc );
|
||||
DictBrowseState result = null;
|
||||
String[] columns = { DBHelper.ITERPOS, DBHelper.ITERTOP,
|
||||
DBHelper.ITERMIN, DBHelper.ITERMAX,
|
||||
DBHelper.WORDCOUNTS, DBHelper.ITERPREFIX };
|
||||
String selection =
|
||||
String.format( NAMELOC_FMT, DBHelper.DICTNAME,
|
||||
name, DBHelper.LOC, loc.ordinal() );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { DBHelper.ITERPOS, DBHelper.ITERTOP,
|
||||
DBHelper.ITERMIN, DBHelper.ITERMAX,
|
||||
DBHelper.WORDCOUNTS, DBHelper.ITERPREFIX };
|
||||
String selection =
|
||||
String.format( NAMELOC_FMT, DBHelper.DICTNAME,
|
||||
name, DBHelper.LOC, loc.ordinal() );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_DICTBROWSE, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 >= cursor.getCount() && cursor.moveToFirst() ) {
|
||||
|
@ -1293,25 +1390,26 @@ public class DBUtils {
|
|||
DictLoc loc, DictBrowseState state )
|
||||
{
|
||||
Assert.assertTrue( DictLoc.UNKNOWN != loc );
|
||||
String selection =
|
||||
String.format( NAMELOC_FMT, DBHelper.DICTNAME,
|
||||
name, DBHelper.LOC, loc.ordinal() );
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.ITERPOS, state.m_pos );
|
||||
values.put( DBHelper.ITERTOP, state.m_top );
|
||||
values.put( DBHelper.ITERMIN, state.m_minShown );
|
||||
values.put( DBHelper.ITERMAX, state.m_maxShown );
|
||||
values.put( DBHelper.ITERPREFIX, state.m_prefix );
|
||||
if ( null != state.m_counts ) {
|
||||
String[] nums = new String[state.m_counts.length];
|
||||
for ( int ii = 0; ii < nums.length; ++ii ) {
|
||||
nums[ii] = String.format( "%d", state.m_counts[ii] );
|
||||
}
|
||||
values.put( DBHelper.WORDCOUNTS, TextUtils.join( ":", nums ) );
|
||||
}
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
String selection =
|
||||
String.format( NAMELOC_FMT, DBHelper.DICTNAME,
|
||||
name, DBHelper.LOC, loc.ordinal() );
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.ITERPOS, state.m_pos );
|
||||
values.put( DBHelper.ITERTOP, state.m_top );
|
||||
values.put( DBHelper.ITERMIN, state.m_minShown );
|
||||
values.put( DBHelper.ITERMAX, state.m_maxShown );
|
||||
values.put( DBHelper.ITERPREFIX, state.m_prefix );
|
||||
if ( null != state.m_counts ) {
|
||||
String[] nums = new String[state.m_counts.length];
|
||||
for ( int ii = 0; ii < nums.length; ++ii ) {
|
||||
nums[ii] = String.format( "%d", state.m_counts[ii] );
|
||||
}
|
||||
values.put( DBHelper.WORDCOUNTS, TextUtils.join( ":", nums ) );
|
||||
}
|
||||
int result = db.update( DBHelper.TABLE_NAME_DICTBROWSE,
|
||||
values, selection, null );
|
||||
if ( 0 == result ) {
|
||||
|
@ -1334,12 +1432,12 @@ public class DBUtils {
|
|||
// Called from jni
|
||||
public static void dictsSetMD5Sum( Context context, String name, String sum )
|
||||
{
|
||||
String selection = String.format( NAME_FMT, DBHelper.DICTNAME, name );
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.MD5SUM, sum );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
String selection = String.format( NAME_FMT, DBHelper.DICTNAME, name );
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.MD5SUM, sum );
|
||||
int result = db.update( DBHelper.TABLE_NAME_DICTINFO,
|
||||
values, selection, null );
|
||||
if ( 0 == result ) {
|
||||
|
@ -1353,14 +1451,14 @@ public class DBUtils {
|
|||
public static DictInfo dictsGetInfo( Context context, String name )
|
||||
{
|
||||
DictInfo result = null;
|
||||
String[] columns = { DBHelper.LANGCODE,
|
||||
DBHelper.WORDCOUNT,
|
||||
DBHelper.MD5SUM,
|
||||
DBHelper.LOC };
|
||||
String selection = String.format( NAME_FMT, DBHelper.DICTNAME, name );
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
String[] columns = { DBHelper.LANGCODE,
|
||||
DBHelper.WORDCOUNT,
|
||||
DBHelper.MD5SUM,
|
||||
DBHelper.LOC };
|
||||
String selection = String.format( NAME_FMT, DBHelper.DICTNAME, name );
|
||||
Cursor cursor = db.query( DBHelper.TABLE_NAME_DICTINFO, columns,
|
||||
selection, null, null, null, null );
|
||||
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
|
||||
|
@ -1382,18 +1480,18 @@ public class DBUtils {
|
|||
public static void dictsSetInfo( Context context, DictUtils.DictAndLoc dal,
|
||||
DictInfo info )
|
||||
{
|
||||
String selection =
|
||||
String.format( NAME_FMT, DBHelper.DICTNAME, dal.name );
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put( DBHelper.LANGCODE, info.langCode );
|
||||
values.put( DBHelper.WORDCOUNT, info.wordCount );
|
||||
values.put( DBHelper.MD5SUM, info.md5Sum );
|
||||
values.put( DBHelper.LOC, dal.loc.ordinal() );
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
String selection =
|
||||
String.format( NAME_FMT, DBHelper.DICTNAME, dal.name );
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put( DBHelper.LANGCODE, info.langCode );
|
||||
values.put( DBHelper.WORDCOUNT, info.wordCount );
|
||||
values.put( DBHelper.MD5SUM, info.md5Sum );
|
||||
values.put( DBHelper.LOC, dal.loc.ordinal() );
|
||||
|
||||
int result = db.update( DBHelper.TABLE_NAME_DICTINFO,
|
||||
values, selection, null );
|
||||
if ( 0 == result ) {
|
||||
|
@ -1407,16 +1505,17 @@ public class DBUtils {
|
|||
public static void dictsMoveInfo( Context context, String name,
|
||||
DictLoc fromLoc, DictLoc toLoc )
|
||||
{
|
||||
String selection =
|
||||
String.format( NAMELOC_FMT, DBHelper.DICTNAME,
|
||||
name, DBHelper.LOC, fromLoc.ordinal() );
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.LOC, toLoc.ordinal() );
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
String selection =
|
||||
String.format( NAMELOC_FMT, DBHelper.DICTNAME,
|
||||
name, DBHelper.LOC, fromLoc.ordinal() );
|
||||
ContentValues values = new ContentValues();
|
||||
values.put( DBHelper.LOC, toLoc.ordinal() );
|
||||
db.update( DBHelper.TABLE_NAME_DICTINFO, values, selection, null );
|
||||
db.update( DBHelper.TABLE_NAME_DICTBROWSE, values, selection, null);
|
||||
db.update( DBHelper.TABLE_NAME_DICTBROWSE, values, selection, null );
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
@ -1424,12 +1523,13 @@ public class DBUtils {
|
|||
public static void dictsRemoveInfo( Context context,
|
||||
DictUtils.DictAndLoc dal )
|
||||
{
|
||||
String selection =
|
||||
String.format( NAMELOC_FMT, DBHelper.DICTNAME,
|
||||
dal.name, DBHelper.LOC, dal.loc.ordinal() );
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
String selection =
|
||||
String.format( NAMELOC_FMT, DBHelper.DICTNAME,
|
||||
dal.name, DBHelper.LOC, dal.loc.ordinal() );
|
||||
db.delete( DBHelper.TABLE_NAME_DICTINFO, selection, null );
|
||||
db.delete( DBHelper.TABLE_NAME_DICTBROWSE, selection, null );
|
||||
db.close();
|
||||
|
@ -1500,12 +1600,12 @@ public class DBUtils {
|
|||
private static void updateRow( Context context, String table,
|
||||
long rowid, ContentValues values )
|
||||
{
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
|
||||
|
||||
String selection = String.format( ROW_ID_FMT, rowid );
|
||||
|
||||
int result = db.update( table, values, selection, null );
|
||||
db.close();
|
||||
if ( 0 == result ) {
|
||||
|
|
|
@ -40,7 +40,7 @@ import java.util.Set;
|
|||
|
||||
public class DbgUtils {
|
||||
private static final String TAG = "XW4";
|
||||
private static boolean s_doLog = true;
|
||||
private static boolean s_doLog = BuildConstants.IS_DEBUG_BUILD;
|
||||
|
||||
private static Time s_time = new Time();
|
||||
|
||||
|
@ -52,13 +52,10 @@ public class DbgUtils {
|
|||
public static void logEnable( Context context )
|
||||
{
|
||||
boolean on;
|
||||
if ( XWApp.DEBUG ) {
|
||||
if ( XWApp.DEBUG || BuildConstants.IS_DEBUG_BUILD ) {
|
||||
on = true;
|
||||
} else {
|
||||
SharedPreferences sp
|
||||
= PreferenceManager.getDefaultSharedPreferences( context );
|
||||
String key = context.getString( R.string.key_logging_on );
|
||||
on = sp.getBoolean( key, false );
|
||||
on = XWPrefs.getPrefsBoolean( context, R.string.key_logging_on, false );
|
||||
}
|
||||
logEnable( on );
|
||||
}
|
||||
|
|
|
@ -128,6 +128,9 @@ public class DictBrowseActivity extends XWListActivity
|
|||
// SectionIndexer
|
||||
public int getPositionForSection( int section )
|
||||
{
|
||||
if ( section >= m_indices.length ) {
|
||||
section = m_indices.length - 1;
|
||||
}
|
||||
return m_indices[section];
|
||||
}
|
||||
|
||||
|
@ -301,7 +304,7 @@ public class DictBrowseActivity extends XWListActivity
|
|||
// DlgDelegate.DlgClickNotify interface
|
||||
//////////////////////////////////////////////////
|
||||
@Override
|
||||
public void dlgButtonClicked( int id, int which )
|
||||
public void dlgButtonClicked( int id, int which, Object[] params )
|
||||
{
|
||||
Assert.assertTrue( FINISH_ACTION == id );
|
||||
finish();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
|
@ -33,8 +34,6 @@ import android.database.DataSetObserver;
|
|||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -43,24 +42,28 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ExpandableListAdapter;
|
||||
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.DictUtils.DictAndLoc;
|
||||
import org.eehouse.android.xw4.jni.XwJNI;
|
||||
import org.eehouse.android.xw4.jni.JNIUtilsImpl;
|
||||
import org.eehouse.android.xw4.jni.GameSummary;
|
||||
import org.eehouse.android.xw4.DictUtils.DictLoc;
|
||||
|
||||
public class DictsActivity extends XWExpandableListActivity
|
||||
implements View.OnClickListener, XWListItem.DeleteCallback,
|
||||
MountEventReceiver.SDCardNotifiee, DlgDelegate.DlgClickNotify,
|
||||
implements View.OnClickListener, AdapterView.OnItemLongClickListener,
|
||||
SelectableItem, MountEventReceiver.SDCardNotifiee,
|
||||
DlgDelegate.DlgClickNotify,
|
||||
DictImportActivity.DownloadFinishedListener {
|
||||
|
||||
private static interface SafePopup {
|
||||
|
@ -71,11 +74,6 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
private static final String DICT_DOLAUNCH = "do_launch";
|
||||
private static final String DICT_LANG_EXTRA = "use_lang";
|
||||
private static final String DICT_NAME_EXTRA = "use_dict";
|
||||
private static final String PACKED_POSITION = "packed_position";
|
||||
private static final String DELETE_DICT = "delete_dict";
|
||||
private static final String NAME = "name";
|
||||
private static final String LANG = "lang";
|
||||
private static final String MOVEFROMLOC = "movefromloc";
|
||||
|
||||
private HashSet<String> m_closedLangs;
|
||||
|
||||
|
@ -90,19 +88,14 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
// settle for a hash on the side.
|
||||
private static HashMap<MenuItem, DictAndLoc> s_itemData;
|
||||
|
||||
private int m_lang = 0;
|
||||
private String[] m_langs;
|
||||
private String m_name = null;
|
||||
private String m_deleteDict = null;
|
||||
private String m_download;
|
||||
private ExpandableListView m_expView;
|
||||
private String[] m_locNames;
|
||||
private DictListAdapter m_adapter;
|
||||
private HashSet<XWListItem> m_selDicts;
|
||||
private CharSequence m_origTitle;
|
||||
|
||||
private long m_packedPosition;
|
||||
private DictLoc m_moveFromLoc;
|
||||
private int m_moveFromItem;
|
||||
private int m_moveToItm;
|
||||
private boolean m_launchedForMissing = false;
|
||||
|
||||
private LayoutInflater m_factory;
|
||||
|
@ -144,6 +137,7 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
if ( null == view ) {
|
||||
view = (XWListItem)
|
||||
m_factory.inflate( R.layout.list_item, null );
|
||||
view.setSelCB( DictsActivity.this );
|
||||
|
||||
int lang = (int)getGroupId( groupPosition );
|
||||
DictAndLoc[] dals = DictLangCache.getDALsHaveLang( m_context,
|
||||
|
@ -157,9 +151,6 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
DictLoc loc = dal.loc;
|
||||
view.setComment( m_locNames[loc.ordinal()] );
|
||||
view.cache( loc );
|
||||
if ( DictLoc.BUILT_IN != loc ) {
|
||||
view.setDeleteCallback( DictsActivity.this );
|
||||
}
|
||||
} else {
|
||||
view.setText( m_download );
|
||||
}
|
||||
|
@ -237,11 +228,8 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
|
||||
protected XWListItem getSelChildView()
|
||||
{
|
||||
int groupPosition =
|
||||
ExpandableListView.getPackedPositionGroup( m_packedPosition );
|
||||
int childPosition =
|
||||
ExpandableListView.getPackedPositionChild( m_packedPosition );
|
||||
return (XWListItem)getChildView( groupPosition, childPosition );
|
||||
Assert.assertTrue( 1 == m_selDicts.size() );
|
||||
return m_selDicts.iterator().next();
|
||||
}
|
||||
|
||||
private void addToCache( int group, int child, XWListItem view )
|
||||
|
@ -268,45 +256,48 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
|
||||
switch( id ) {
|
||||
case MOVE_DICT:
|
||||
final XWListItem[] selItems = getSelItems();
|
||||
final int[] moveTo = { -1 };
|
||||
message = Utils.format( this, R.string.move_dictf,
|
||||
m_adapter.getSelChildView().getText() );
|
||||
getJoinedNames( selItems ) );
|
||||
|
||||
OnClickListener newSelLstnr =
|
||||
new OnClickListener() {
|
||||
public void onClick( DialogInterface dlgi, int item ) {
|
||||
m_moveToItm = item;
|
||||
moveTo[0] = item;
|
||||
AlertDialog dlg = (AlertDialog)dlgi;
|
||||
Button btn =
|
||||
dlg.getButton( AlertDialog.BUTTON_POSITIVE );
|
||||
btn.setEnabled( m_moveToItm != m_moveFromItem );
|
||||
btn.setEnabled( true );
|
||||
}
|
||||
};
|
||||
|
||||
lstnr = new OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
XWListItem rowView = m_adapter.getSelChildView();
|
||||
Assert.assertTrue( m_moveToItm != m_moveFromItem );
|
||||
DictLoc toLoc = itemToRealLoc( m_moveToItm );
|
||||
if ( DictUtils.moveDict( DictsActivity.this,
|
||||
rowView.getText(),
|
||||
m_moveFromLoc,
|
||||
toLoc ) ) {
|
||||
rowView.setComment( m_locNames[toLoc.ordinal()] );
|
||||
rowView.cache( toLoc );
|
||||
rowView.invalidate();
|
||||
DBUtils.dictsMoveInfo( DictsActivity.this,
|
||||
rowView.getText(),
|
||||
m_moveFromLoc, toLoc );
|
||||
} else {
|
||||
DbgUtils.logf( "moveDict(%s) failed",
|
||||
rowView.getText() );
|
||||
DictLoc toLoc = itemToRealLoc( moveTo[0] );
|
||||
for ( XWListItem selItem : selItems ) {
|
||||
DictLoc fromLoc = (DictLoc)selItem.getCached();
|
||||
String name = selItem.getText();
|
||||
if ( fromLoc == toLoc ) {
|
||||
DbgUtils.logf( "not moving %s: same loc", name );
|
||||
} else if ( DictUtils.moveDict( DictsActivity.this,
|
||||
name, fromLoc,
|
||||
toLoc ) ) {
|
||||
selItem.setComment( m_locNames[toLoc.ordinal()] );
|
||||
selItem.cache( toLoc );
|
||||
selItem.invalidate();
|
||||
DBUtils.dictsMoveInfo( DictsActivity.this,
|
||||
name, fromLoc, toLoc );
|
||||
} else {
|
||||
DbgUtils.logf( "moveDict(%s) failed", name );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dialog = new AlertDialog.Builder( this )
|
||||
.setTitle( message )
|
||||
.setSingleChoiceItems( makeDictDirItems(), m_moveFromItem,
|
||||
.setSingleChoiceItems( makeDictDirItems(), moveTo[0],
|
||||
newSelLstnr )
|
||||
.setPositiveButton( R.string.button_move, lstnr )
|
||||
.setNegativeButton( R.string.button_cancel, null )
|
||||
|
@ -314,22 +305,22 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
break;
|
||||
|
||||
case SET_DEFAULT:
|
||||
final XWListItem row = m_selDicts.iterator().next();
|
||||
lstnr = new OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
if ( DialogInterface.BUTTON_NEGATIVE == item
|
||||
|| DialogInterface.BUTTON_POSITIVE == item ) {
|
||||
setDefault( R.string.key_default_dict );
|
||||
setDefault( row, R.string.key_default_dict );
|
||||
}
|
||||
if ( DialogInterface.BUTTON_NEGATIVE == item
|
||||
|| DialogInterface.BUTTON_NEUTRAL == item ) {
|
||||
setDefault( R.string.key_default_robodict );
|
||||
setDefault( row, R.string.key_default_robodict );
|
||||
}
|
||||
}
|
||||
};
|
||||
XWListItem rowView = m_adapter.getSelChildView();
|
||||
String lang =
|
||||
DictLangCache.getLangName( this, rowView.getText() );
|
||||
message = getString( R.string.set_default_messagef, lang );
|
||||
String name = row.getText();
|
||||
String lang = DictLangCache.getLangName( this, name);
|
||||
message = getString( R.string.set_default_messagef, name, lang );
|
||||
dialog = new AlertDialog.Builder( this )
|
||||
.setTitle( R.string.query_title )
|
||||
.setMessage( message )
|
||||
|
@ -392,7 +383,6 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
protected void onCreate( Bundle savedInstanceState )
|
||||
{
|
||||
super.onCreate( savedInstanceState );
|
||||
getBundledData( savedInstanceState );
|
||||
|
||||
m_closedLangs = new HashSet<String>();
|
||||
String[] closed = XWPrefs.getClosedLangs( this );
|
||||
|
@ -411,15 +401,17 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
|
||||
setContentView( R.layout.dict_browse );
|
||||
m_expView = getExpandableListView();
|
||||
registerForContextMenu( m_expView );
|
||||
|
||||
m_expView.setOnItemLongClickListener( this );
|
||||
|
||||
Button download = (Button)findViewById( R.id.download );
|
||||
download.setOnClickListener( this );
|
||||
if ( ABUtils.haveActionBar() ) {
|
||||
download.setVisibility( View.GONE );
|
||||
} else {
|
||||
download.setOnClickListener( this );
|
||||
}
|
||||
|
||||
mkListAdapter();
|
||||
|
||||
// showNotAgainDlg( R.string.not_again_dicts,
|
||||
// R.string.key_notagain_dicts );
|
||||
m_selDicts = new HashSet<XWListItem>();
|
||||
|
||||
Intent intent = getIntent();
|
||||
if ( null != intent ) {
|
||||
|
@ -436,6 +428,8 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
downloadNewDict( intent );
|
||||
}
|
||||
}
|
||||
|
||||
m_origTitle = getTitle();
|
||||
} // onCreate
|
||||
|
||||
@Override
|
||||
|
@ -448,35 +442,6 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
expandGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState( Bundle outState )
|
||||
{
|
||||
super.onSaveInstanceState( outState );
|
||||
|
||||
outState.putLong( PACKED_POSITION, m_packedPosition );
|
||||
outState.putString( NAME, m_name );
|
||||
outState.putInt( LANG, m_lang );
|
||||
outState.putString( DELETE_DICT, m_deleteDict );
|
||||
if ( null != m_moveFromLoc ) {
|
||||
outState.putInt( MOVEFROMLOC, m_moveFromLoc.ordinal() );
|
||||
}
|
||||
}
|
||||
|
||||
private void getBundledData( Bundle savedInstanceState )
|
||||
{
|
||||
if ( null != savedInstanceState ) {
|
||||
m_packedPosition = savedInstanceState.getLong( PACKED_POSITION );
|
||||
m_name = savedInstanceState.getString( NAME );
|
||||
m_lang = savedInstanceState.getInt( LANG );
|
||||
m_deleteDict = savedInstanceState.getString( DELETE_DICT );
|
||||
|
||||
int tmp = savedInstanceState.getInt( MOVEFROMLOC, -1 );
|
||||
if ( -1 != tmp ) {
|
||||
m_moveFromLoc = DictLoc.values()[tmp];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
MountEventReceiver.unregister( this );
|
||||
|
@ -495,65 +460,61 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu( ContextMenu menu, View view,
|
||||
ContextMenuInfo menuInfo )
|
||||
{
|
||||
super.onCreateContextMenu( menu, view, menuInfo );
|
||||
|
||||
ExpandableListView.ExpandableListContextMenuInfo info
|
||||
= (ExpandableListView.ExpandableListContextMenuInfo)menuInfo;
|
||||
long packedPosition = info.packedPosition;
|
||||
int childPosition = ExpandableListView.
|
||||
getPackedPositionChild( packedPosition );
|
||||
// int groupPosition = ExpandableListView.
|
||||
// getPackedPositionGroup( packedPosition );
|
||||
// DbgUtils.logf( "onCreateContextMenu: group: %d; child: %d",
|
||||
// groupPosition, childPosition );
|
||||
|
||||
// We don't have a menu yet for languages, just for their dict
|
||||
// children
|
||||
if ( childPosition >= 0 ) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate( R.menu.dicts_item_menu, menu );
|
||||
|
||||
XWListItem row = (XWListItem)info.targetView;
|
||||
DictLoc loc = (DictLoc)row.getCached();
|
||||
if ( loc == DictLoc.BUILT_IN
|
||||
|| ! DictUtils.haveWriteableSD() ) {
|
||||
menu.removeItem( R.id.dicts_item_move );
|
||||
}
|
||||
|
||||
String title = getString( R.string.game_item_menu_titlef,
|
||||
row.getText() );
|
||||
menu.setHeaderTitle( title );
|
||||
public void onBackPressed() {
|
||||
if ( 0 == m_selDicts.size() ) {
|
||||
super.onBackPressed();
|
||||
} else {
|
||||
clearSelections();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected( MenuItem item )
|
||||
{
|
||||
boolean handled = false;
|
||||
ExpandableListContextMenuInfo info = null;
|
||||
try {
|
||||
info = (ExpandableListContextMenuInfo)item.getMenuInfo();
|
||||
} catch (ClassCastException cce) {
|
||||
DbgUtils.loge( cce );
|
||||
return false;
|
||||
}
|
||||
|
||||
m_packedPosition = info.packedPosition;
|
||||
|
||||
int id = item.getItemId();
|
||||
switch( id ) {
|
||||
case R.id.dicts_item_move:
|
||||
askMoveDict( (XWListItem)info.targetView );
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu( Menu menu )
|
||||
{
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate( R.menu.dicts_menu, menu );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu( Menu menu )
|
||||
{
|
||||
int nSel = m_selDicts.size();
|
||||
Utils.setItemVisible( menu, R.id.dicts_download,
|
||||
0 == nSel && ABUtils.haveActionBar() );
|
||||
Utils.setItemVisible( menu, R.id.dicts_select, 1 == nSel );
|
||||
|
||||
boolean allVolatile = selItemsVolatile();
|
||||
Utils.setItemVisible( menu, R.id.dicts_move,
|
||||
allVolatile && DictUtils.haveWriteableSD() );
|
||||
Utils.setItemVisible( menu, R.id.dicts_delete, allVolatile );
|
||||
|
||||
return super.onPrepareOptionsMenu( menu );
|
||||
}
|
||||
|
||||
public boolean onOptionsItemSelected( MenuItem item )
|
||||
{
|
||||
boolean handled = true;
|
||||
|
||||
switch ( item.getItemId() ) {
|
||||
case R.id.dicts_download:
|
||||
startDownload( 0, null );
|
||||
break;
|
||||
case R.id.dicts_item_select:
|
||||
case R.id.dicts_delete:
|
||||
deleteSelected();
|
||||
break;
|
||||
case R.id.dicts_move:
|
||||
askMoveSelDicts();
|
||||
break;
|
||||
case R.id.dicts_select:
|
||||
showDialog( SET_DEFAULT );
|
||||
break;
|
||||
default:
|
||||
handled = false;
|
||||
}
|
||||
|
||||
return handled;
|
||||
return handled || super.onOptionsItemSelected( item );
|
||||
}
|
||||
|
||||
private void downloadNewDict( Intent intent )
|
||||
|
@ -567,9 +528,8 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
}
|
||||
}
|
||||
|
||||
private void setDefault( int keyId )
|
||||
private void setDefault( XWListItem view, int keyId )
|
||||
{
|
||||
XWListItem view = m_adapter.getSelChildView();
|
||||
SharedPreferences sp
|
||||
= PreferenceManager.getDefaultSharedPreferences( this );
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
|
@ -582,20 +542,39 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
// Move dict. Put up dialog asking user to confirm move from XX
|
||||
// to YY. So we need both XX and YY. There may be several
|
||||
// options for YY?
|
||||
private void askMoveDict( XWListItem item )
|
||||
private void askMoveSelDicts()
|
||||
{
|
||||
m_moveFromLoc = (DictLoc)item.getCached();
|
||||
showDialog( MOVE_DICT );
|
||||
}
|
||||
|
||||
// XWListItem.DeleteCallback interface
|
||||
public void deleteCalled( XWListItem item )
|
||||
{
|
||||
String dict = item.getText();
|
||||
String msg = getString( R.string.confirm_delete_dictf, dict );
|
||||
// OnItemLongClickListener interface
|
||||
public boolean onItemLongClick( AdapterView<?> parent, View view,
|
||||
int position, long id ) {
|
||||
boolean success = view instanceof SelectableItem.LongClickHandler;
|
||||
if ( success ) {
|
||||
((SelectableItem.LongClickHandler)view).longClicked();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
m_deleteDict = dict;
|
||||
m_moveFromLoc = (DictLoc)item.getCached();
|
||||
private boolean selItemsVolatile()
|
||||
{
|
||||
boolean result = 0 < m_selDicts.size();
|
||||
for ( Iterator<XWListItem> iter = m_selDicts.iterator();
|
||||
result && iter.hasNext(); ) {
|
||||
DictLoc loc = (DictLoc)iter.next().getCached();
|
||||
if ( loc == DictLoc.BUILT_IN ) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void deleteSelected()
|
||||
{
|
||||
XWListItem[] items = getSelItems();
|
||||
String msg = getString( R.string.confirm_delete_dictf,
|
||||
getJoinedNames( items ) );
|
||||
|
||||
// When and what to warn about. First off, if there's another
|
||||
// identical dict, simply confirm. Or if nobody's using this
|
||||
|
@ -604,30 +583,36 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
// want different warnings depending on whether it's the last
|
||||
// available dict in its language.
|
||||
|
||||
if ( 1 < DictLangCache.getDictCount( this, dict ) ) {
|
||||
// there's another; do nothing
|
||||
} else {
|
||||
int fmtid = 0;
|
||||
int langcode = DictLangCache.getDictLangCode( this, dict );
|
||||
DictAndLoc[] langDals = DictLangCache.getDALsHaveLang( this,
|
||||
langcode );
|
||||
int nUsingLang = DBUtils.countGamesUsingLang( this, langcode );
|
||||
for ( XWListItem item : items ) {
|
||||
String dict = item.getText();
|
||||
if ( 1 < DictLangCache.getDictCount( this, dict ) ) {
|
||||
// there's another; do nothing
|
||||
} else {
|
||||
String newMsg = null;
|
||||
int langcode = DictLangCache.getDictLangCode( this, dict );
|
||||
String langName = DictLangCache.getLangName( this, langcode );
|
||||
DictAndLoc[] langDals = DictLangCache.getDALsHaveLang( this,
|
||||
langcode );
|
||||
int nUsingLang = DBUtils.countGamesUsingLang( this, langcode );
|
||||
|
||||
if ( 1 == langDals.length ) { // last in this language?
|
||||
if ( 0 < nUsingLang ) {
|
||||
fmtid = R.string.confirm_deleteonly_dictf;
|
||||
if ( 1 == langDals.length ) { // last in this language?
|
||||
if ( 0 < nUsingLang ) {
|
||||
newMsg = getString( R.string.confirm_deleteonly_dictf,
|
||||
dict, langName );
|
||||
}
|
||||
} else if ( 0 < DBUtils.countGamesUsingDict( this, dict ) ) {
|
||||
newMsg = getString( R.string.confirm_deletemore_dictf,
|
||||
langName );
|
||||
}
|
||||
if ( null != newMsg ) {
|
||||
msg += "\n\n" + newMsg;
|
||||
}
|
||||
} else if ( 0 < DBUtils.countGamesUsingDict( this, dict ) ) {
|
||||
fmtid = R.string.confirm_deletemore_dictf;
|
||||
}
|
||||
if ( 0 != fmtid ) {
|
||||
msg += getString( fmtid, DictLangCache.
|
||||
getLangName( this, langcode ) );
|
||||
}
|
||||
}
|
||||
|
||||
showConfirmThen( msg, R.string.button_delete, DELETE_DICT_ACTION );
|
||||
}
|
||||
showConfirmThen( msg, R.string.button_delete, DELETE_DICT_ACTION,
|
||||
(Object)items );
|
||||
} // deleteSelected
|
||||
|
||||
// MountEventReceiver.SDCardNotifiee interface
|
||||
public void cardMounted( boolean nowMounted )
|
||||
|
@ -644,12 +629,18 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
}
|
||||
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
public void dlgButtonClicked( int id, int which )
|
||||
public void dlgButtonClicked( int id, int which, Object[] params )
|
||||
{
|
||||
switch( id ) {
|
||||
case DELETE_DICT_ACTION:
|
||||
if ( DialogInterface.BUTTON_POSITIVE == which ) {
|
||||
deleteDict( m_deleteDict, m_moveFromLoc );
|
||||
XWListItem[] items = (XWListItem[])params[0];
|
||||
for ( XWListItem item : items ) {
|
||||
String name = item.getText();
|
||||
DictLoc loc = (DictLoc)item.getCached();
|
||||
deleteDict( name, loc );
|
||||
}
|
||||
clearSelections();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -711,6 +702,49 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
XWPrefs.setClosedLangs( this, asArray );
|
||||
}
|
||||
|
||||
private void clearSelections()
|
||||
{
|
||||
if ( 0 < m_selDicts.size() ) {
|
||||
XWListItem[] items = getSelItems();
|
||||
|
||||
m_selDicts.clear();
|
||||
|
||||
for ( XWListItem item : items ) {
|
||||
item.setSelected( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getJoinedNames( XWListItem[] items )
|
||||
{
|
||||
String[] names = new String[items.length];
|
||||
int ii = 0;
|
||||
for ( XWListItem item : items ) {
|
||||
names[ii++] = item.getText();
|
||||
}
|
||||
return TextUtils.join( ", ", names );
|
||||
}
|
||||
|
||||
private XWListItem[] getSelItems()
|
||||
{
|
||||
XWListItem[] items = new XWListItem[m_selDicts.size()];
|
||||
int indx = 0;
|
||||
for ( Iterator<XWListItem> iter = m_selDicts.iterator();
|
||||
iter.hasNext(); ) {
|
||||
items[indx++] = iter.next();
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private void setTitleBar()
|
||||
{
|
||||
int nSels = m_selDicts.size();
|
||||
if ( 0 < nSels ) {
|
||||
setTitle( getString( R.string.sel_dictsf, nSels ) );
|
||||
} else {
|
||||
setTitle( m_origTitle );
|
||||
}
|
||||
}
|
||||
|
||||
private String[] makeDictDirItems()
|
||||
{
|
||||
|
@ -723,9 +757,6 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
if ( !showDownload && DictLoc.DOWNLOAD == loc ) {
|
||||
continue;
|
||||
}
|
||||
if ( loc.equals( m_moveFromLoc ) ) {
|
||||
m_moveFromItem = nextI;
|
||||
}
|
||||
items[nextI++] = m_locNames[loc.ordinal()];
|
||||
}
|
||||
return items;
|
||||
|
@ -793,6 +824,32 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
}
|
||||
}
|
||||
|
||||
// SelectableItem interface
|
||||
public void itemClicked( SelectableItem.LongClickHandler clicked,
|
||||
GameSummary summary )
|
||||
{
|
||||
DbgUtils.logf( "itemClicked not implemented" );
|
||||
}
|
||||
|
||||
public void itemToggled( SelectableItem.LongClickHandler toggled,
|
||||
boolean selected )
|
||||
{
|
||||
XWListItem dictView = (XWListItem)toggled;
|
||||
if ( selected ) {
|
||||
m_selDicts.add( dictView );
|
||||
} else {
|
||||
m_selDicts.remove( dictView );
|
||||
}
|
||||
ABUtils.invalidateOptionsMenuIf( this );
|
||||
setTitleBar();
|
||||
}
|
||||
|
||||
public boolean getSelected( SelectableItem.LongClickHandler obj )
|
||||
{
|
||||
XWListItem dictView = (XWListItem)obj;
|
||||
return m_selDicts.contains( dictView );
|
||||
}
|
||||
|
||||
private static class SafePopupImpl implements SafePopup {
|
||||
public void doPopup( final Context context, View button,
|
||||
String curDict ) {
|
||||
|
@ -821,7 +878,9 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
.setOnMenuItemClickListener( listener );
|
||||
|
||||
// Add at top but save until have dal info
|
||||
MenuItem curItem = menu.add( curDict );
|
||||
MenuItem curItem =
|
||||
menu.add( context.getString( R.string.cur_menu_markerf,
|
||||
curDict ) );
|
||||
|
||||
DictAndLoc[] dals = DictUtils.dictList( context );
|
||||
for ( DictAndLoc dal : dals ) {
|
||||
|
@ -857,4 +916,4 @@ public class DictsActivity extends XWExpandableListActivity
|
|||
context.startActivity( intent );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,12 +43,13 @@ public class DlgDelegate {
|
|||
public static final int DIALOG_OKONLY = 2;
|
||||
public static final int DIALOG_NOTAGAIN = 3;
|
||||
public static final int CONFIRM_THEN = 4;
|
||||
public static final int TEXT_OR_HTML_THEN = 5;
|
||||
public static final int INVITE_CHOICES_THEN = 5;
|
||||
public static final int DLG_DICTGONE = 6;
|
||||
public static final int DIALOG_LAST = DLG_DICTGONE;
|
||||
|
||||
public static final int SMS_BTN = AlertDialog.BUTTON_POSITIVE;
|
||||
public static final int EMAIL_BTN = AlertDialog.BUTTON_NEGATIVE;
|
||||
public static final int NFC_BTN = AlertDialog.BUTTON_NEUTRAL;
|
||||
public static final int DISMISS_BUTTON = 0;
|
||||
public static final int SKIP_CALLBACK = -1;
|
||||
|
||||
|
@ -56,7 +57,7 @@ public class DlgDelegate {
|
|||
private static final String STATE_KEYF = "STATE_%d";
|
||||
|
||||
public interface DlgClickNotify {
|
||||
void dlgButtonClicked( int id, int button );
|
||||
void dlgButtonClicked( int id, int button, Object[] params );
|
||||
}
|
||||
|
||||
private Activity m_activity;
|
||||
|
@ -118,8 +119,8 @@ public class DlgDelegate {
|
|||
case CONFIRM_THEN:
|
||||
dialog = createConfirmThenDialog( state, id );
|
||||
break;
|
||||
case TEXT_OR_HTML_THEN:
|
||||
dialog = createHtmlThenDialog( state, id );
|
||||
case INVITE_CHOICES_THEN:
|
||||
dialog = createInviteChoicesDialog( state, id );
|
||||
break;
|
||||
case DLG_DICTGONE:
|
||||
dialog = createDictGoneDialog();
|
||||
|
@ -157,24 +158,45 @@ public class DlgDelegate {
|
|||
}
|
||||
|
||||
public void showNotAgainDlgThen( int msgID, int prefsKey,
|
||||
int callbackID )
|
||||
final int callbackID,
|
||||
final Object[] params )
|
||||
{
|
||||
showNotAgainDlgThen( m_activity.getString( msgID ), prefsKey,
|
||||
callbackID, params );
|
||||
}
|
||||
|
||||
public void showNotAgainDlgThen( String msg, int prefsKey,
|
||||
final int callbackID,
|
||||
final Object[] params )
|
||||
{
|
||||
if ( XWPrefs.getPrefsBoolean( m_activity, prefsKey, false ) ) {
|
||||
// If it's set, do the action without bothering with the
|
||||
// dialog
|
||||
if ( SKIP_CALLBACK != callbackID ) {
|
||||
m_clickCallback.dlgButtonClicked( callbackID,
|
||||
AlertDialog.BUTTON_POSITIVE );
|
||||
post( new Runnable() {
|
||||
public void run() {
|
||||
m_clickCallback
|
||||
.dlgButtonClicked( callbackID,
|
||||
AlertDialog.BUTTON_POSITIVE,
|
||||
params );
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
String msg = m_activity.getString( msgID );
|
||||
DlgState state =
|
||||
new DlgState( DIALOG_NOTAGAIN, msg, callbackID, prefsKey );
|
||||
new DlgState( DIALOG_NOTAGAIN, msg, callbackID, prefsKey,
|
||||
params );
|
||||
addState( state );
|
||||
m_activity.showDialog( DIALOG_NOTAGAIN );
|
||||
}
|
||||
}
|
||||
|
||||
public void showNotAgainDlgThen( int msgID, int prefsKey,
|
||||
int callbackID )
|
||||
{
|
||||
showNotAgainDlgThen( msgID, prefsKey, callbackID, null );
|
||||
}
|
||||
|
||||
public void showNotAgainDlgThen( int msgID, int prefsKey )
|
||||
{
|
||||
showNotAgainDlgThen( msgID, prefsKey, SKIP_CALLBACK );
|
||||
|
@ -182,27 +204,40 @@ public class DlgDelegate {
|
|||
|
||||
public void showConfirmThen( String msg, int callbackID )
|
||||
{
|
||||
showConfirmThen( msg, R.string.button_ok, callbackID );
|
||||
showConfirmThen( msg, R.string.button_ok, callbackID, null );
|
||||
}
|
||||
|
||||
public void showConfirmThen( String msg, int callbackID, Object[] params )
|
||||
{
|
||||
showConfirmThen( msg, R.string.button_ok, callbackID, params );
|
||||
}
|
||||
|
||||
public void showConfirmThen( String msg, int posButton, int callbackID )
|
||||
{
|
||||
showConfirmThen( msg, posButton, callbackID, null );
|
||||
}
|
||||
|
||||
public void showConfirmThen( String msg, int posButton, int callbackID,
|
||||
Object[] params )
|
||||
{
|
||||
DlgState state = new DlgState( CONFIRM_THEN, msg, posButton,
|
||||
callbackID, 0 );
|
||||
callbackID, 0, params );
|
||||
addState( state );
|
||||
m_activity.showDialog( CONFIRM_THEN );
|
||||
}
|
||||
|
||||
public void showEmailOrSMSThen( final int callbackID )
|
||||
public void showInviteChoicesThen( final int callbackID )
|
||||
{
|
||||
if ( Utils.deviceSupportsSMS( m_activity ) ) {
|
||||
DlgState state = new DlgState( TEXT_OR_HTML_THEN, callbackID );
|
||||
if ( Utils.deviceSupportsSMS( m_activity )
|
||||
|| NFCUtils.nfcAvail( m_activity )[0] ) {
|
||||
DlgState state = new DlgState( INVITE_CHOICES_THEN, callbackID );
|
||||
addState( state );
|
||||
m_activity.showDialog( TEXT_OR_HTML_THEN );
|
||||
m_activity.showDialog( INVITE_CHOICES_THEN );
|
||||
} else {
|
||||
post( new Runnable() {
|
||||
public void run() {
|
||||
m_clickCallback.dlgButtonClicked( callbackID, EMAIL_BTN );
|
||||
m_clickCallback.dlgButtonClicked( callbackID, EMAIL_BTN,
|
||||
null );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -295,7 +330,7 @@ public class DlgDelegate {
|
|||
TextView vers = (TextView)view.findViewById( R.id.version_string );
|
||||
vers.setText( String.format( m_activity.getString(R.string.about_versf),
|
||||
m_activity.getString(R.string.app_version),
|
||||
GitVersion.VERS ) );
|
||||
BuildConstants.GIT_REV ) );
|
||||
|
||||
TextView xlator = (TextView)view.findViewById( R.id.about_xlator );
|
||||
String str = m_activity.getString( R.string.xlator );
|
||||
|
@ -345,7 +380,8 @@ public class DlgDelegate {
|
|||
if ( SKIP_CALLBACK != state.m_cbckID ) {
|
||||
m_clickCallback.
|
||||
dlgButtonClicked( state.m_cbckID,
|
||||
AlertDialog.BUTTON_POSITIVE );
|
||||
AlertDialog.BUTTON_POSITIVE,
|
||||
state.m_params );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -374,17 +410,34 @@ public class DlgDelegate {
|
|||
return setCallbackDismissListener( dialog, state, id );
|
||||
}
|
||||
|
||||
private Dialog createHtmlThenDialog( DlgState state, int id )
|
||||
private Dialog createInviteChoicesDialog( DlgState state, int id )
|
||||
{
|
||||
OnClickListener lstnr = mkCallbackClickListener( state );
|
||||
Dialog dialog = new AlertDialog.Builder( m_activity )
|
||||
.setTitle( R.string.query_title )
|
||||
.setMessage( R.string.sms_or_email )
|
||||
.setPositiveButton( R.string.button_text, lstnr )
|
||||
.setNegativeButton( R.string.button_html, lstnr )
|
||||
.create();
|
||||
|
||||
return setCallbackDismissListener( dialog, state, id );
|
||||
boolean haveSMS = Utils.deviceSupportsSMS( m_activity );
|
||||
boolean haveNFC = NFCUtils.nfcAvail( m_activity )[0];
|
||||
int msgID;
|
||||
if ( haveSMS && haveNFC ) {
|
||||
msgID = R.string.nfc_or_sms_or_email;
|
||||
} else if ( haveSMS ) {
|
||||
msgID = R.string.sms_or_email;
|
||||
} else {
|
||||
msgID = R.string.nfc_or_email;
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder( m_activity )
|
||||
.setTitle( R.string.query_title )
|
||||
.setMessage( msgID )
|
||||
.setNegativeButton( R.string.button_html, lstnr );
|
||||
|
||||
if ( haveSMS ) {
|
||||
builder.setPositiveButton( R.string.button_text, lstnr );
|
||||
}
|
||||
if ( haveNFC ) {
|
||||
builder.setNeutralButton( R.string.button_nfc, lstnr );
|
||||
}
|
||||
|
||||
return setCallbackDismissListener( builder.create(), state, id );
|
||||
}
|
||||
|
||||
private Dialog createDictGoneDialog()
|
||||
|
@ -411,7 +464,8 @@ public class DlgDelegate {
|
|||
public void onClick( DialogInterface dlg, int button ) {
|
||||
if ( SKIP_CALLBACK != state.m_cbckID ) {
|
||||
m_clickCallback.dlgButtonClicked( state.m_cbckID,
|
||||
button );
|
||||
button,
|
||||
state.m_params );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -428,7 +482,8 @@ public class DlgDelegate {
|
|||
dropState( state );
|
||||
if ( SKIP_CALLBACK != state.m_cbckID ) {
|
||||
m_clickCallback.dlgButtonClicked( state.m_cbckID,
|
||||
DISMISS_BUTTON );
|
||||
DISMISS_BUTTON,
|
||||
state.m_params );
|
||||
}
|
||||
m_activity.removeDialog( id );
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public class DlgState implements Parcelable {
|
|||
public int m_posButton;
|
||||
public int m_cbckID = 0;
|
||||
public int m_prefsKey;
|
||||
public Object[] m_params;
|
||||
|
||||
public DlgState( int id, String msg, int cbckID )
|
||||
{
|
||||
|
@ -40,14 +41,28 @@ public class DlgState implements Parcelable {
|
|||
this( id, msg, R.string.button_ok, cbckID, prefsKey );
|
||||
}
|
||||
|
||||
public DlgState( int id, String msg, int cbckID, int prefsKey,
|
||||
Object[] params )
|
||||
{
|
||||
this( id, msg, R.string.button_ok, cbckID, prefsKey );
|
||||
m_params = params;
|
||||
}
|
||||
|
||||
public DlgState( int id, String msg, int posButton,
|
||||
int cbckID, int prefsKey )
|
||||
{
|
||||
this( id, msg, posButton, cbckID, prefsKey, null );
|
||||
}
|
||||
|
||||
public DlgState( int id, String msg, int posButton,
|
||||
int cbckID, int prefsKey, Object[] params )
|
||||
{
|
||||
m_id = id;
|
||||
m_msg = msg;
|
||||
m_posButton = posButton;
|
||||
m_cbckID = cbckID;
|
||||
m_prefsKey = prefsKey;
|
||||
m_params = params;
|
||||
}
|
||||
|
||||
public DlgState( int id, int cbckID )
|
||||
|
|
|
@ -26,6 +26,7 @@ import android.graphics.Color;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.view.View;
|
||||
|
@ -47,10 +48,13 @@ public class ExpiringDelegate {
|
|||
private boolean m_haveTurnLocal = false;
|
||||
private long m_startSecs;
|
||||
private Runnable m_runnable = null;
|
||||
private boolean m_selected;
|
||||
private Drawable m_origDrawable;
|
||||
// these can be static as drawing's all in same thread.
|
||||
private static Rect s_rect;
|
||||
private static Paint s_paint;
|
||||
private static float[] s_points;
|
||||
private static Drawable s_selDrawable;
|
||||
|
||||
static {
|
||||
s_rect = new Rect();
|
||||
|
@ -58,12 +62,18 @@ public class ExpiringDelegate {
|
|||
s_paint.setStyle(Paint.Style.STROKE);
|
||||
s_paint.setStrokeWidth( 1 );
|
||||
s_points = new float[4*6];
|
||||
s_selDrawable = new ColorDrawable( XWApp.SEL_COLOR );
|
||||
}
|
||||
|
||||
public ExpiringDelegate( Context context, View view, Handler handler )
|
||||
public ExpiringDelegate( Context context, View view )
|
||||
{
|
||||
m_context = context;
|
||||
m_view = view;
|
||||
m_origDrawable = view.getBackground();
|
||||
}
|
||||
|
||||
public void setHandler( Handler handler )
|
||||
{
|
||||
m_handler = handler;
|
||||
}
|
||||
|
||||
|
@ -85,9 +95,22 @@ public class ExpiringDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
public void setSelected( boolean selected )
|
||||
{
|
||||
m_selected = selected;
|
||||
if ( selected ) {
|
||||
m_origDrawable = m_view.getBackground();
|
||||
m_view.setBackgroundDrawable( s_selDrawable );
|
||||
} else {
|
||||
m_view.setBackgroundDrawable( m_origDrawable );
|
||||
}
|
||||
}
|
||||
|
||||
public void onDraw( Canvas canvas )
|
||||
{
|
||||
if ( m_active && m_doFrame ) {
|
||||
if ( m_selected ) {
|
||||
// do nothing; the drawable's set already
|
||||
} else if ( m_active && m_doFrame ) {
|
||||
Assert.assertTrue( 0 <= m_pct && m_pct <= 100 );
|
||||
m_view.getDrawingRect( s_rect );
|
||||
int width = s_rect.width();
|
||||
|
@ -178,14 +201,14 @@ public class ExpiringDelegate {
|
|||
m_pct = (int)((100 * passed) / INTERVAL_SECS);
|
||||
if ( m_pct > 100 ) {
|
||||
m_pct = 100;
|
||||
} else {
|
||||
} else if ( null != m_handler ) {
|
||||
long onePct = INTERVAL_SECS / 100;
|
||||
long lastStart = m_startSecs + (onePct * m_pct);
|
||||
Assert.assertTrue( lastStart <= now );
|
||||
long nextStartIn = lastStart + onePct - now;
|
||||
// DbgUtils.logf( "pct change %d seconds from now", nextStartIn );
|
||||
|
||||
m_handler.postDelayed( mkRunnable(), 1000 * nextStartIn );
|
||||
m_handler.postDelayed( mkRunnable(), 1000 * nextStartIn ); // NPE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,8 @@ public class ExpiringLinearLayout extends LinearLayout {
|
|||
boolean haveTurnLocal, long startSecs )
|
||||
{
|
||||
if ( null == m_delegate ) {
|
||||
m_delegate = new ExpiringDelegate( m_context, this, handler );
|
||||
m_delegate = new ExpiringDelegate( m_context, this );
|
||||
m_delegate.setHandler( handler );
|
||||
}
|
||||
m_delegate.configure( haveTurn, haveTurnLocal, startSecs );
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import android.widget.TextView;
|
|||
class ExpiringTextView extends TextView {
|
||||
private ExpiringDelegate m_delegate = null;
|
||||
private Context m_context;
|
||||
protected boolean m_selected = false;
|
||||
|
||||
public ExpiringTextView( Context context, AttributeSet attrs )
|
||||
{
|
||||
|
@ -38,9 +39,9 @@ class ExpiringTextView extends TextView {
|
|||
public void setPct( Handler handler, boolean haveTurn,
|
||||
boolean haveTurnLocal, long startSecs )
|
||||
{
|
||||
if ( null == m_delegate ) {
|
||||
m_delegate = new ExpiringDelegate( m_context, this, handler );
|
||||
}
|
||||
ExpiringDelegate delegate = getDelegate();
|
||||
delegate.setHandler( handler );
|
||||
|
||||
setPct( haveTurn, haveTurnLocal, startSecs );
|
||||
}
|
||||
|
||||
|
@ -52,6 +53,12 @@ class ExpiringTextView extends TextView {
|
|||
}
|
||||
}
|
||||
|
||||
protected void toggleSelected()
|
||||
{
|
||||
m_selected = !m_selected;
|
||||
getDelegate().setSelected( m_selected );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw( Canvas canvas )
|
||||
{
|
||||
|
@ -60,4 +67,12 @@ class ExpiringTextView extends TextView {
|
|||
m_delegate.onDraw( canvas );
|
||||
}
|
||||
}
|
||||
|
||||
private ExpiringDelegate getDelegate()
|
||||
{
|
||||
if ( null == m_delegate ) {
|
||||
m_delegate = new ExpiringDelegate( m_context, this );
|
||||
}
|
||||
return m_delegate;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -600,7 +600,7 @@ public class GameConfig extends XWActivity
|
|||
}
|
||||
|
||||
@Override
|
||||
public void dlgButtonClicked( int id, int button )
|
||||
public void dlgButtonClicked( int id, int button, Object[] params )
|
||||
{
|
||||
switch( id ) {
|
||||
case LOCKED_CHANGE_ACTION:
|
||||
|
|
|
@ -45,18 +45,12 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
private ExpandableListView m_list;
|
||||
private int m_fieldID;
|
||||
private Handler m_handler;
|
||||
private LoadItemCB m_cb;
|
||||
private SelectableItem m_cb;
|
||||
private long[] m_positions;
|
||||
|
||||
public interface LoadItemCB {
|
||||
public void itemClicked( long rowid, GameSummary summary );
|
||||
public void itemToggled( long rowid, boolean selected );
|
||||
public boolean getSelected( long rowid );
|
||||
}
|
||||
|
||||
public GameListAdapter( Context context, ExpandableListView list,
|
||||
Handler handler, LoadItemCB cb, long[] positions,
|
||||
String fieldName )
|
||||
Handler handler, SelectableItem cb,
|
||||
long[] positions, String fieldName )
|
||||
{
|
||||
m_context = context;
|
||||
m_list = list;
|
||||
|
@ -67,7 +61,7 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
m_fieldID = fieldToID( fieldName );
|
||||
}
|
||||
|
||||
public long[] getPositions()
|
||||
public long[] getGroupPositions()
|
||||
{
|
||||
Set<Long> keys = gameInfo().keySet(); // do not modify!!!!
|
||||
if ( null == m_positions || m_positions.length != keys.size() ) {
|
||||
|
@ -99,7 +93,7 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
{
|
||||
int src = getGroupPosition( groupid );
|
||||
int dest = src + moveBy;
|
||||
long[] positions = getPositions();
|
||||
long[] positions = getGroupPositions();
|
||||
boolean success = 0 <= dest && dest < positions.length;
|
||||
if ( success ) {
|
||||
long tmp = positions[src];
|
||||
|
@ -123,7 +117,7 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
public long getRowIDFor( int group, int child )
|
||||
{
|
||||
long rowid = DBUtils.ROWID_NOTFOUND;
|
||||
long[] rows = getRows( getPositions()[group] );
|
||||
long[] rows = getRows( getGroupPositions()[group] );
|
||||
if ( child < rows.length ) {
|
||||
rowid = rows[child];
|
||||
}
|
||||
|
@ -141,7 +135,7 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
|
||||
public long getGroupIDFor( int groupPos )
|
||||
{
|
||||
long id = getPositions()[groupPos];
|
||||
long id = getGroupPositions()[groupPos];
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -152,9 +146,14 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
return ggi.m_name;
|
||||
}
|
||||
|
||||
public void clearSelected( Set<Long> rowids )
|
||||
public void clearSelectedGames( long[] rowids )
|
||||
{
|
||||
deselect( rowids );
|
||||
deselectGames( rowids );
|
||||
}
|
||||
|
||||
public void clearSelectedGroups( HashSet<Long> groupIDs )
|
||||
{
|
||||
deselectGroups( groupIDs );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -178,11 +177,7 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
DBUtils.setGroupExpanded( m_context, groupid, false );
|
||||
|
||||
long[] rowids = DBUtils.getGroupGames( m_context, groupid );
|
||||
HashSet<Long> asSet = new HashSet<Long>(rowids.length);
|
||||
for ( long rowid : rowids ) {
|
||||
asSet.add( rowid );
|
||||
}
|
||||
deselect( asSet );
|
||||
deselectGames( rowids );
|
||||
}
|
||||
|
||||
public void onGroupExpanded( int groupPosition )
|
||||
|
@ -223,6 +218,7 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
GameListItem result =
|
||||
GameListItem.makeForRow( m_context, rowid, m_handler,
|
||||
groupPosition, m_fieldID, m_cb );
|
||||
result.setSelected( m_cb.getSelected( result ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -232,9 +228,10 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
// if ( null != convertView ) {
|
||||
// DbgUtils.logf( "getGroupView gave non-null convertView" );
|
||||
// }
|
||||
GameListGroup view = (GameListGroup)
|
||||
Utils.inflate(m_context, R.layout.game_list_group );
|
||||
view.setGroupPosition( groupPosition );
|
||||
long groupID = getGroupIDFor( groupPosition );
|
||||
GameListGroup view =
|
||||
GameListGroup.makeForPosition( m_context, groupPosition, groupID,
|
||||
m_cb );
|
||||
|
||||
if ( !isExpanded ) {
|
||||
GameGroupInfo ggi = getInfoForGroup( groupPosition );
|
||||
|
@ -247,6 +244,8 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
groupNames()[groupPosition], nKids );
|
||||
view.setText( name );
|
||||
|
||||
view.setSelected( m_cb.getSelected( view ) );
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -274,7 +273,12 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
|
||||
public int getChildrenCount( int groupPosition )
|
||||
{
|
||||
long[] rows = getRows( getPositions()[groupPosition] );
|
||||
return getChildrenCount( getGroupPositions()[groupPosition] );
|
||||
}
|
||||
|
||||
public int getChildrenCount( long groupID )
|
||||
{
|
||||
long[] rows = getRows( groupID );
|
||||
return rows.length;
|
||||
}
|
||||
|
||||
|
@ -321,7 +325,7 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
public String[] groupNames()
|
||||
{
|
||||
HashMap<Long,GameGroupInfo> info = gameInfo();
|
||||
long[] positions = getPositions();
|
||||
long[] positions = getGroupPositions();
|
||||
String[] names = new String[ positions.length ];
|
||||
for ( int ii = 0; ii < names.length; ++ii ) {
|
||||
names[ii] = info.get(positions[ii]).m_name;
|
||||
|
@ -332,7 +336,7 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
public int getGroupPosition( long groupid )
|
||||
{
|
||||
int result = -1;
|
||||
long[] positions = getPositions();
|
||||
long[] positions = getGroupPositions();
|
||||
for ( int pos = 0; pos < positions.length; ++pos ) {
|
||||
if ( positions[pos] == groupid ) {
|
||||
result = pos;
|
||||
|
@ -361,27 +365,47 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
|
||||
private GameGroupInfo getInfoForGroup( int groupPosition )
|
||||
{
|
||||
return gameInfo().get( getPositions()[groupPosition] );
|
||||
return gameInfo().get( getGroupPositions()[groupPosition] );
|
||||
}
|
||||
|
||||
private void deselect( Set<Long> rowids )
|
||||
private void deselectGames( long[] rowids )
|
||||
{
|
||||
GameListItem[] items = new GameListItem[rowids.size()];
|
||||
GameListItem[] items = new GameListItem[rowids.length];
|
||||
getGameItemsFor( rowids, items );
|
||||
for ( GameListItem item : items ) {
|
||||
item.setSelected( false );
|
||||
if ( null != item ) {
|
||||
item.setSelected( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getGameItemsFor( Set<Long> rowids, GameListItem[] items )
|
||||
private void deselectGroups( HashSet<Long> groupids )
|
||||
{
|
||||
groupids = (HashSet<Long>)groupids.clone();
|
||||
for ( Iterator<Long>iter = groupids.iterator();
|
||||
iter.hasNext(); ) {
|
||||
int pos = getGroupPosition( iter.next() );
|
||||
if ( 0 <= pos ) { // still exists?
|
||||
GameListGroup group = getGroupItemFor( pos );
|
||||
group.setSelected( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getGameItemsFor( long[] rowids, GameListItem[] items )
|
||||
{
|
||||
Set<Long> rowidsSet = new HashSet<Long>();
|
||||
for ( long rowid : rowids ) {
|
||||
rowidsSet.add( rowid );
|
||||
}
|
||||
|
||||
int next = 0;
|
||||
int count = m_list.getChildCount();
|
||||
for ( int ii = 0; ii < count; ++ii ) {
|
||||
View view = m_list.getChildAt( ii );
|
||||
if ( view instanceof GameListItem ) {
|
||||
GameListItem tryme = (GameListItem)view;
|
||||
if ( rowids.contains( tryme.getRowID() ) ) {
|
||||
if ( rowidsSet.contains( tryme.getRowID() ) ) {
|
||||
items[next++] = tryme;
|
||||
if ( next >= items.length ) {
|
||||
break;
|
||||
|
@ -393,8 +417,7 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
|
||||
private GameListItem getGameItemFor( long rowid )
|
||||
{
|
||||
Set<Long> rowids = new HashSet<Long>(1);
|
||||
rowids.add( rowid );
|
||||
long[] rowids = { rowid };
|
||||
GameListItem[] items = new GameListItem[1];
|
||||
getGameItemsFor( rowids, items );
|
||||
return items[0];
|
||||
|
@ -420,10 +443,12 @@ public class GameListAdapter implements ExpandableListAdapter {
|
|||
private int fieldToID( String fieldName )
|
||||
{
|
||||
int[] ids = {
|
||||
R.string.game_summary_field_empty
|
||||
,R.string.game_summary_field_language
|
||||
,R.string.game_summary_field_opponents
|
||||
,R.string.game_summary_field_state
|
||||
R.string.game_summary_field_empty,
|
||||
R.string.game_summary_field_language,
|
||||
R.string.game_summary_field_opponents,
|
||||
R.string.game_summary_field_state,
|
||||
R.string.game_summary_field_rowid,
|
||||
R.string.game_summary_field_gameid,
|
||||
};
|
||||
int result = -1;
|
||||
for ( int id : ids ) {
|
||||
|
|
|
@ -23,11 +23,30 @@ package org.eehouse.android.xw4;
|
|||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import org.eehouse.android.xw4.DBUtils.GameGroupInfo;
|
||||
|
||||
public class GameListGroup extends ExpiringTextView {
|
||||
public class GameListGroup extends ExpiringTextView
|
||||
implements SelectableItem.LongClickHandler
|
||||
{
|
||||
private int m_groupPosition;
|
||||
private long m_groupID;
|
||||
private boolean m_expanded;
|
||||
private SelectableItem m_cb;
|
||||
|
||||
public static GameListGroup makeForPosition( Context context,
|
||||
int groupPosition,
|
||||
long groupID,
|
||||
SelectableItem cb )
|
||||
{
|
||||
GameListGroup result =
|
||||
(GameListGroup)Utils.inflate( context, R.layout.game_list_group );
|
||||
result.m_cb = cb;
|
||||
result.m_groupPosition = groupPosition;
|
||||
result.m_groupID = groupID;
|
||||
return result;
|
||||
}
|
||||
|
||||
public GameListGroup( Context cx, AttributeSet as )
|
||||
{
|
||||
|
@ -43,4 +62,30 @@ public class GameListGroup extends ExpiringTextView {
|
|||
{
|
||||
return m_groupPosition;
|
||||
}
|
||||
|
||||
public long getGroupID()
|
||||
{
|
||||
return m_groupID;
|
||||
}
|
||||
|
||||
public void setSelected( boolean selected )
|
||||
{
|
||||
// If new value and state not in sync, force change in state
|
||||
if ( selected != m_selected ) {
|
||||
toggleSelected();
|
||||
}
|
||||
}
|
||||
|
||||
// GameListAdapter.ClickHandler interface
|
||||
public void longClicked()
|
||||
{
|
||||
toggleSelected();
|
||||
}
|
||||
|
||||
protected void toggleSelected()
|
||||
{
|
||||
super.toggleSelected();
|
||||
m_cb.itemToggled( this, m_selected );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
@ -43,38 +45,54 @@ import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
|
|||
import org.eehouse.android.xw4.jni.GameSummary;
|
||||
|
||||
public class GameListItem extends LinearLayout
|
||||
implements View.OnClickListener {
|
||||
implements View.OnClickListener, SelectableItem.LongClickHandler {
|
||||
|
||||
private static HashSet<Long> s_invalRows = new HashSet<Long>();
|
||||
|
||||
private Activity m_activity;
|
||||
private Context m_context;
|
||||
private boolean m_loaded;
|
||||
private long m_rowid;
|
||||
private View m_hideable;
|
||||
private ImageView m_thumb;
|
||||
private ExpiringTextView m_name;
|
||||
private boolean m_expanded, m_haveTurn, m_haveTurnLocal;
|
||||
private long m_lastMoveTime;
|
||||
private ImageButton m_expandButton;
|
||||
private Handler m_handler;
|
||||
private GameSummary m_summary;
|
||||
private GameListAdapter.LoadItemCB m_cb;
|
||||
private SelectableItem m_cb;
|
||||
private int m_fieldID;
|
||||
private int m_loadingCount;
|
||||
private int m_groupPosition;
|
||||
private Drawable m_origDrawable;
|
||||
private boolean m_selected = false;
|
||||
|
||||
public GameListItem( Context cx, AttributeSet as )
|
||||
{
|
||||
super( cx, as );
|
||||
m_context = cx;
|
||||
if ( cx instanceof Activity ) {
|
||||
m_activity = (Activity)cx;
|
||||
}
|
||||
m_loaded = false;
|
||||
m_rowid = DBUtils.ROWID_NOTFOUND;
|
||||
m_lastMoveTime = 0;
|
||||
m_loadingCount = 0;
|
||||
|
||||
setOnClickListener( new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick( View v ) {
|
||||
// if selected, just un-select
|
||||
if ( null != m_summary ) {
|
||||
m_cb.itemClicked( GameListItem.this, m_summary );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private void init( Handler handler, long rowid, int groupPosition,
|
||||
int fieldID, GameListAdapter.LoadItemCB cb )
|
||||
int fieldID, SelectableItem cb )
|
||||
{
|
||||
m_handler = handler;
|
||||
m_rowid = rowid;
|
||||
|
@ -105,7 +123,7 @@ public class GameListItem extends LinearLayout
|
|||
public void setSelected( boolean selected )
|
||||
{
|
||||
// If new value and state not in sync, force change in state
|
||||
if ( selected != (null != m_origDrawable) ) {
|
||||
if ( selected != m_selected ) {
|
||||
toggleSelected();
|
||||
}
|
||||
}
|
||||
|
@ -151,6 +169,9 @@ public class GameListItem extends LinearLayout
|
|||
public void onClick( View view ) {
|
||||
m_expanded = !m_expanded;
|
||||
DBUtils.setExpanded( m_rowid, m_expanded );
|
||||
|
||||
makeThumbnailIf( m_expanded );
|
||||
|
||||
showHide();
|
||||
}
|
||||
|
||||
|
@ -172,6 +193,11 @@ public class GameListItem extends LinearLayout
|
|||
R.drawable.expander_ic_maximized :
|
||||
R.drawable.expander_ic_minimized);
|
||||
m_hideable.setVisibility( m_expanded? View.VISIBLE : View.GONE );
|
||||
if ( BuildConstants.THUMBNAIL_SUPPORTED ) {
|
||||
int vis = m_expanded && XWPrefs.getThumbEnabled( m_context )
|
||||
? View.VISIBLE : View.GONE;
|
||||
m_thumb.setVisibility( vis );
|
||||
}
|
||||
|
||||
m_name.setBackgroundColor( android.R.color.transparent );
|
||||
m_name.setPct( m_handler, m_haveTurn && !m_expanded,
|
||||
|
@ -188,6 +214,12 @@ public class GameListItem extends LinearLayout
|
|||
switch ( m_fieldID ) {
|
||||
case R.string.game_summary_field_empty:
|
||||
break;
|
||||
case R.string.game_summary_field_gameid:
|
||||
value = String.format( "%X", m_summary.gameID );
|
||||
break;
|
||||
case R.string.game_summary_field_rowid:
|
||||
value = String.format( "%d", m_rowid );
|
||||
break;
|
||||
case R.string.game_summary_field_language:
|
||||
value =
|
||||
DictLangCache.getLangName( m_context,
|
||||
|
@ -214,19 +246,12 @@ public class GameListItem extends LinearLayout
|
|||
return state;
|
||||
}
|
||||
|
||||
private void setData( final GameSummary summary )
|
||||
private void setData( GameSummary summary, boolean expanded )
|
||||
{
|
||||
if ( null != summary ) {
|
||||
TextView tview;
|
||||
String state = setName();
|
||||
|
||||
setOnClickListener( new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick( View v ) {
|
||||
m_cb.itemClicked( m_rowid, summary );
|
||||
}
|
||||
} );
|
||||
|
||||
LinearLayout list =
|
||||
(LinearLayout)findViewById( R.id.player_list );
|
||||
list.removeAllViews();
|
||||
|
@ -283,6 +308,11 @@ public class GameListItem extends LinearLayout
|
|||
}
|
||||
} );
|
||||
|
||||
if ( BuildConstants.THUMBNAIL_SUPPORTED ) {
|
||||
m_thumb = (ImageView)findViewById( R.id.thumbnail );
|
||||
m_thumb.setImageBitmap( summary.getThumbnail() );
|
||||
}
|
||||
|
||||
tview = (TextView)findViewById( R.id.role );
|
||||
String roleSummary = summary.summarizeRole();
|
||||
if ( null != roleSummary ) {
|
||||
|
@ -291,8 +321,6 @@ public class GameListItem extends LinearLayout
|
|||
tview.setVisibility( View.GONE );
|
||||
}
|
||||
|
||||
boolean expanded = DBUtils.getExpanded( m_context, m_rowid );
|
||||
|
||||
update( expanded, summary.lastMoveTime, haveATurn,
|
||||
haveALocalTurn );
|
||||
}
|
||||
|
@ -300,14 +328,24 @@ public class GameListItem extends LinearLayout
|
|||
|
||||
private void toggleSelected()
|
||||
{
|
||||
if ( null == m_origDrawable ) {
|
||||
m_selected = !m_selected;
|
||||
if ( m_selected ) {
|
||||
m_origDrawable = getBackground();
|
||||
setBackgroundColor( XWApp.SEL_COLOR );
|
||||
} else {
|
||||
setBackgroundDrawable( m_origDrawable );
|
||||
m_origDrawable = null;
|
||||
}
|
||||
m_cb.itemToggled( m_rowid, null != m_origDrawable );
|
||||
m_cb.itemToggled( this, m_selected );
|
||||
}
|
||||
|
||||
private void makeThumbnailIf( boolean expanded )
|
||||
{
|
||||
if ( expanded && null != m_activity && null != m_summary
|
||||
&& null == m_summary.getThumbnail()
|
||||
&& XWPrefs.getThumbEnabled( m_context ) ) {
|
||||
m_summary.setThumbnail( GameUtils.loadMakeBitmap( m_activity,
|
||||
m_rowid ) );
|
||||
}
|
||||
}
|
||||
|
||||
private class LoadItemTask extends AsyncTask<Void, Void, GameSummary> {
|
||||
|
@ -322,23 +360,23 @@ public class GameListItem extends LinearLayout
|
|||
{
|
||||
if ( 0 == --m_loadingCount ) {
|
||||
m_summary = summary;
|
||||
setData( summary );
|
||||
boolean expanded = DBUtils.getExpanded( m_context, m_rowid );
|
||||
|
||||
makeThumbnailIf( expanded );
|
||||
|
||||
setData( summary, expanded );
|
||||
setLoaded( null != m_summary );
|
||||
synchronized( s_invalRows ) {
|
||||
s_invalRows.remove( m_rowid );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_cb.getSelected( m_rowid ) && null != m_origDrawable ) {
|
||||
toggleSelected();
|
||||
}
|
||||
}
|
||||
} // class LoadItemTask
|
||||
|
||||
public static GameListItem makeForRow( Context context, long rowid,
|
||||
Handler handler, int groupPosition,
|
||||
int fieldID,
|
||||
GameListAdapter.LoadItemCB cb )
|
||||
SelectableItem cb )
|
||||
{
|
||||
GameListItem result =
|
||||
(GameListItem)Utils.inflate( context, R.layout.game_list_item );
|
||||
|
@ -367,5 +405,11 @@ public class GameListItem extends LinearLayout
|
|||
// }
|
||||
// return TextUtils.join(",", strs );
|
||||
// }
|
||||
// GameListAdapter.ClickHandler interface
|
||||
|
||||
public void longClicked()
|
||||
{
|
||||
toggleSelected();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -91,7 +91,8 @@ public class GameLock {
|
|||
long sleptTime = 0;
|
||||
|
||||
if ( XWApp.DEBUG_LOCKS ) {
|
||||
DbgUtils.logf( "lock %H (rowid:%d, maxMillis=%d)", this, m_rowid, maxMillis );
|
||||
DbgUtils.logf( "lock %H (rowid:%d, maxMillis=%d)", this, m_rowid,
|
||||
maxMillis );
|
||||
}
|
||||
|
||||
for ( ; ; ) {
|
||||
|
|
|
@ -23,9 +23,13 @@ package org.eehouse.android.xw4;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Display;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Arrays;
|
||||
|
@ -46,6 +50,8 @@ public class GameUtils {
|
|||
public static final String INTENT_KEY_ROWID = "rowid";
|
||||
public static final String INTENT_FORRESULT_ROWID = "forresult";
|
||||
|
||||
private static Integer s_minScreen;
|
||||
|
||||
public static class NoSuchGameException extends RuntimeException {
|
||||
public NoSuchGameException() {
|
||||
super(); // superfluous
|
||||
|
@ -114,7 +120,8 @@ public class GameUtils {
|
|||
}
|
||||
|
||||
if ( null == lockDest ) {
|
||||
long rowid = saveNewGame( context, gamePtr, gi );
|
||||
long groupID = DBUtils.getGroupForGame( context, lockSrc.getRowid() );
|
||||
long rowid = saveNewGame( context, gamePtr, gi, groupID );
|
||||
lockDest = new GameLock( rowid, true ).lock();
|
||||
} else {
|
||||
saveGame( context, gamePtr, gi, lockDest, true );
|
||||
|
@ -180,10 +187,13 @@ public class GameUtils {
|
|||
|
||||
public static GameSummary summarize( Context context, GameLock lock )
|
||||
{
|
||||
GameSummary result = null;
|
||||
CurGameInfo gi = new CurGameInfo( context );
|
||||
int gamePtr = loadMakeGame( context, gi, lock );
|
||||
|
||||
return summarizeAndClose( context, lock, gamePtr, gi );
|
||||
if ( 0 < gamePtr ) {
|
||||
result = summarizeAndClose( context, lock, gamePtr, gi );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static long dupeGame( Context context, long rowidIn )
|
||||
|
@ -289,6 +299,58 @@ public class GameUtils {
|
|||
return gamePtr;
|
||||
}
|
||||
|
||||
public static Bitmap loadMakeBitmap( Activity activity, long rowid )
|
||||
{
|
||||
Bitmap thumb = null;
|
||||
GameLock lock = new GameLock( rowid, false );
|
||||
if ( lock.tryLock() ) {
|
||||
CurGameInfo gi = new CurGameInfo( activity );
|
||||
int gamePtr = loadMakeGame( activity, gi, lock );
|
||||
if ( 0 != gamePtr ) {
|
||||
thumb = takeSnapshot( activity, gamePtr, gi );
|
||||
XwJNI.game_dispose( gamePtr );
|
||||
DBUtils.saveThumbnail( activity, lock, thumb );
|
||||
}
|
||||
|
||||
lock.unlock();
|
||||
}
|
||||
return thumb;
|
||||
}
|
||||
|
||||
public static Bitmap takeSnapshot( Activity activity, int gamePtr,
|
||||
CurGameInfo gi )
|
||||
{
|
||||
Bitmap thumb = null;
|
||||
if ( BuildConstants.THUMBNAIL_SUPPORTED ) {
|
||||
if ( XWPrefs.getThumbEnabled( activity ) ) {
|
||||
int nCols = gi.boardSize;
|
||||
int scale = XWPrefs.getThumbScale( activity );
|
||||
Assert.assertTrue( 0 < scale );
|
||||
|
||||
if ( null == s_minScreen ) {
|
||||
Display display =
|
||||
activity.getWindowManager().getDefaultDisplay();
|
||||
int width = display.getWidth();
|
||||
int height = display.getHeight();
|
||||
s_minScreen = new Integer( Math.min( width, height ) );
|
||||
}
|
||||
int dim = s_minScreen / scale;
|
||||
int size = dim - (dim % nCols);
|
||||
|
||||
thumb = Bitmap.createBitmap( size, size, Bitmap.Config.ARGB_8888 );
|
||||
|
||||
XwJNI.board_figureLayout( gamePtr, gi, 0, 0, size, size,
|
||||
0, 0, 0, 20, 20, false, null );
|
||||
|
||||
ThumbCanvas canvas = new ThumbCanvas( activity, thumb );
|
||||
XwJNI.board_setDraw( gamePtr, canvas );
|
||||
XwJNI.board_invalAll( gamePtr );
|
||||
XwJNI.board_draw( gamePtr );
|
||||
}
|
||||
}
|
||||
return thumb;
|
||||
}
|
||||
|
||||
public static long saveGame( Context context, int gamePtr,
|
||||
CurGameInfo gi, GameLock lock,
|
||||
boolean setCreate )
|
||||
|
@ -298,10 +360,10 @@ public class GameUtils {
|
|||
}
|
||||
|
||||
public static long saveNewGame( Context context, int gamePtr,
|
||||
CurGameInfo gi )
|
||||
CurGameInfo gi, long groupID )
|
||||
{
|
||||
byte[] stream = XwJNI.game_saveToStream( gamePtr, gi );
|
||||
GameLock lock = DBUtils.saveNewGame( context, stream );
|
||||
GameLock lock = DBUtils.saveNewGame( context, stream, groupID );
|
||||
long rowid = lock.getRowid();
|
||||
lock.unlock();
|
||||
return rowid;
|
||||
|
@ -315,22 +377,33 @@ public class GameUtils {
|
|||
|
||||
public static GameLock saveNewGame( Context context, byte[] bytes )
|
||||
{
|
||||
return DBUtils.saveNewGame( context, bytes );
|
||||
return saveNewGame( context, bytes, DBUtils.GROUPID_UNSPEC );
|
||||
}
|
||||
|
||||
public static long saveNew( Context context, CurGameInfo gi )
|
||||
public static GameLock saveNewGame( Context context, byte[] bytes,
|
||||
long groupID )
|
||||
{
|
||||
return DBUtils.saveNewGame( context, bytes, groupID );
|
||||
}
|
||||
|
||||
public static long saveNew( Context context, CurGameInfo gi, long groupID )
|
||||
{
|
||||
if ( DBUtils.GROUPID_UNSPEC == groupID ) {
|
||||
groupID = XWPrefs.getDefaultNewGameGroup( context );
|
||||
}
|
||||
|
||||
long rowid = DBUtils.ROWID_NOTFOUND;
|
||||
byte[] bytes = XwJNI.gi_to_stream( gi );
|
||||
if ( null != bytes ) {
|
||||
GameLock lock = DBUtils.saveNewGame( context, bytes );
|
||||
GameLock lock = DBUtils.saveNewGame( context, bytes, groupID );
|
||||
rowid = lock.getRowid();
|
||||
lock.unlock();
|
||||
}
|
||||
return rowid;
|
||||
}
|
||||
|
||||
private static long makeNewMultiGame( Context context, CommsAddrRec addr,
|
||||
private static long makeNewMultiGame( Context context, long groupID,
|
||||
CommsAddrRec addr,
|
||||
int[] lang, String[] dict,
|
||||
int nPlayersT, int nPlayersH,
|
||||
String inviteID, int gameID,
|
||||
|
@ -338,7 +411,8 @@ public class GameUtils {
|
|||
{
|
||||
long rowid = -1;
|
||||
|
||||
CurGameInfo gi = new CurGameInfo( context, true );
|
||||
Assert.assertNotNull( inviteID ); // firing
|
||||
CurGameInfo gi = new CurGameInfo( context, inviteID );
|
||||
gi.setLang( lang[0], dict[0] );
|
||||
lang[0] = gi.dictLang;
|
||||
dict[0] = gi.dictName;
|
||||
|
@ -353,7 +427,7 @@ public class GameUtils {
|
|||
// Will need to add a setNPlayers() method to gi to make this
|
||||
// work
|
||||
Assert.assertTrue( gi.nPlayers == nPlayersT );
|
||||
rowid = saveNew( context, gi );
|
||||
rowid = saveNew( context, gi, groupID );
|
||||
|
||||
if ( DBUtils.ROWID_NOTFOUND != rowid ) {
|
||||
GameLock lock = new GameLock( rowid, true ).lock();
|
||||
|
@ -364,8 +438,8 @@ public class GameUtils {
|
|||
return rowid;
|
||||
}
|
||||
|
||||
public static long makeNewNetGame( Context context, String room,
|
||||
String inviteID, int[] lang,
|
||||
public static long makeNewNetGame( Context context, long groupID,
|
||||
String room, String inviteID, int[] lang,
|
||||
String[] dict, int nPlayersT,
|
||||
int nPlayersH )
|
||||
{
|
||||
|
@ -375,29 +449,38 @@ public class GameUtils {
|
|||
CommsAddrRec addr = new CommsAddrRec( relayName, relayPort );
|
||||
addr.ip_relay_invite = room;
|
||||
|
||||
return makeNewMultiGame( context, addr, lang, dict, nPlayersT,
|
||||
nPlayersH, inviteID, 0, false );
|
||||
return makeNewMultiGame( context, groupID, addr, lang, dict,
|
||||
nPlayersT, nPlayersH, inviteID, 0, false );
|
||||
}
|
||||
|
||||
public static long makeNewNetGame( Context context, String room,
|
||||
String inviteID, int lang, String dict,
|
||||
int nPlayers )
|
||||
public static long makeNewNetGame( Context context, long groupID,
|
||||
String room, String inviteID, int lang,
|
||||
String dict, int nPlayers )
|
||||
{
|
||||
int[] langarr = { lang };
|
||||
String[] dictArr = { dict };
|
||||
return makeNewNetGame( context, room, inviteID, langarr, dictArr,
|
||||
nPlayers, 1 );
|
||||
return makeNewNetGame( context, groupID, room, inviteID, langarr,
|
||||
dictArr, nPlayers, 1 );
|
||||
}
|
||||
|
||||
public static long makeNewNetGame( Context context, NetLaunchInfo info )
|
||||
{
|
||||
return makeNewNetGame( context, info.room, info.inviteID, info.lang,
|
||||
info.dict, info.nPlayersT );
|
||||
return makeNewNetGame( context, DBUtils.GROUPID_UNSPEC, info.room,
|
||||
info.inviteID, info.lang, info.dict,
|
||||
info.nPlayersT );
|
||||
}
|
||||
|
||||
public static long makeNewBTGame( Context context, int gameID,
|
||||
CommsAddrRec addr, int lang,
|
||||
int nPlayersT, int nPlayersH )
|
||||
{
|
||||
return makeNewBTGame( context, DBUtils.GROUPID_UNSPEC, gameID, addr,
|
||||
lang, nPlayersT, nPlayersH );
|
||||
}
|
||||
|
||||
public static long makeNewBTGame( Context context, long groupID,
|
||||
int gameID, CommsAddrRec addr, int lang,
|
||||
int nPlayersT, int nPlayersH )
|
||||
{
|
||||
long rowid = -1;
|
||||
int[] langa = { lang };
|
||||
|
@ -405,13 +488,22 @@ public class GameUtils {
|
|||
if ( isHost ) {
|
||||
addr = new CommsAddrRec( null, null );
|
||||
}
|
||||
return makeNewMultiGame( context, addr, langa, null, nPlayersT,
|
||||
nPlayersH, null, gameID, isHost );
|
||||
return makeNewMultiGame( context, groupID, addr, langa, null,
|
||||
nPlayersT, nPlayersH, null, gameID, isHost );
|
||||
}
|
||||
|
||||
public static long makeNewSMSGame( Context context, int gameID,
|
||||
CommsAddrRec addr, int lang,
|
||||
String dict, int nPlayersT,
|
||||
CommsAddrRec addr,
|
||||
int lang, String dict, int nPlayersT,
|
||||
int nPlayersH )
|
||||
{
|
||||
return makeNewSMSGame( context, DBUtils.GROUPID_UNSPEC, gameID, addr,
|
||||
lang, dict, nPlayersT, nPlayersH );
|
||||
}
|
||||
|
||||
public static long makeNewSMSGame( Context context, long groupID,
|
||||
int gameID, CommsAddrRec addr,
|
||||
int lang, String dict, int nPlayersT,
|
||||
int nPlayersH )
|
||||
{
|
||||
long rowid = -1;
|
||||
|
@ -421,64 +513,71 @@ public class GameUtils {
|
|||
if ( isHost ) {
|
||||
addr = new CommsAddrRec(CommsAddrRec.CommsConnType.COMMS_CONN_SMS);
|
||||
}
|
||||
return makeNewMultiGame( context, addr, langa, dicta, nPlayersT,
|
||||
nPlayersH, null, gameID, isHost );
|
||||
String inviteID = GameUtils.formatGameID( gameID );
|
||||
return makeNewMultiGame( context, groupID, addr, langa, dicta,
|
||||
nPlayersT, nPlayersH, inviteID, gameID,
|
||||
isHost );
|
||||
}
|
||||
|
||||
public static void launchInviteActivity( Context context,
|
||||
boolean choseEmail,
|
||||
public static void launchInviteActivity( Activity activity, int chosen,
|
||||
String room, String inviteID,
|
||||
int lang, String dict,
|
||||
int nPlayers )
|
||||
{
|
||||
if ( null == inviteID ) {
|
||||
inviteID = makeRandomID();
|
||||
}
|
||||
Uri gameUri = NetLaunchInfo.makeLaunchUri( context, room, inviteID,
|
||||
lang, dict, nPlayers );
|
||||
Assert.assertNotNull( inviteID );
|
||||
|
||||
if ( null != gameUri ) {
|
||||
int fmtId = choseEmail? R.string.invite_htmf : R.string.invite_txtf;
|
||||
int choiceID;
|
||||
String message = context.getString( fmtId, gameUri.toString() );
|
||||
if ( DlgDelegate.NFC_BTN == chosen ) {
|
||||
Utils.showToast( activity, R.string.sms_ready_text );
|
||||
} else {
|
||||
Uri gameUri = NetLaunchInfo.makeLaunchUri( activity, room, inviteID,
|
||||
lang, dict, nPlayers );
|
||||
String msgString = null == gameUri ? null : gameUri.toString();
|
||||
|
||||
Intent intent = new Intent();
|
||||
if ( choseEmail ) {
|
||||
intent.setAction( Intent.ACTION_SEND );
|
||||
String subject =
|
||||
Utils.format( context, R.string.invite_subjectf, room );
|
||||
intent.putExtra( Intent.EXTRA_SUBJECT, subject );
|
||||
intent.putExtra( Intent.EXTRA_TEXT, Html.fromHtml(message) );
|
||||
if ( null != msgString ) {
|
||||
boolean choseEmail = DlgDelegate.EMAIL_BTN == chosen;
|
||||
|
||||
File attach = null;
|
||||
File tmpdir = XWApp.ATTACH_SUPPORTED ?
|
||||
DictUtils.getDownloadDir( context ) : null;
|
||||
if ( null != tmpdir ) { // no attachment
|
||||
attach = makeJsonFor( tmpdir, room, inviteID, lang,
|
||||
dict, nPlayers );
|
||||
}
|
||||
int fmtId = choseEmail? R.string.invite_htmf : R.string.invite_txtf;
|
||||
int choiceID;
|
||||
String message = activity.getString( fmtId, msgString );
|
||||
|
||||
if ( null == attach ) { // no attachment
|
||||
intent.setType( "message/rfc822");
|
||||
Intent intent = new Intent();
|
||||
if ( choseEmail ) {
|
||||
intent.setAction( Intent.ACTION_SEND );
|
||||
String subject =
|
||||
Utils.format( activity, R.string.invite_subjectf, room );
|
||||
intent.putExtra( Intent.EXTRA_SUBJECT, subject );
|
||||
intent.putExtra( Intent.EXTRA_TEXT, Html.fromHtml(message) );
|
||||
|
||||
File attach = null;
|
||||
File tmpdir = XWApp.ATTACH_SUPPORTED ?
|
||||
DictUtils.getDownloadDir( activity ) : null;
|
||||
if ( null != tmpdir ) { // no attachment
|
||||
attach = makeJsonFor( tmpdir, room, inviteID, lang,
|
||||
dict, nPlayers );
|
||||
}
|
||||
|
||||
if ( null == attach ) { // no attachment
|
||||
intent.setType( "message/rfc822");
|
||||
} else {
|
||||
String mime = activity.getString( R.string.invite_mime );
|
||||
intent.setType( mime );
|
||||
Uri uri = Uri.fromFile( attach );
|
||||
intent.putExtra( Intent.EXTRA_STREAM, uri );
|
||||
}
|
||||
|
||||
choiceID = R.string.invite_chooser_email;
|
||||
} else {
|
||||
String mime = context.getString( R.string.invite_mime );
|
||||
intent.setType( mime );
|
||||
Uri uri = Uri.fromFile( attach );
|
||||
intent.putExtra( Intent.EXTRA_STREAM, uri );
|
||||
intent.setAction( Intent.ACTION_VIEW );
|
||||
intent.setType( "vnd.android-dir/mms-sms" );
|
||||
intent.putExtra( "sms_body", message );
|
||||
choiceID = R.string.invite_chooser_sms;
|
||||
}
|
||||
|
||||
choiceID = R.string.invite_chooser_email;
|
||||
} else {
|
||||
intent.setAction( Intent.ACTION_VIEW );
|
||||
intent.setType( "vnd.android-dir/mms-sms" );
|
||||
intent.putExtra( "sms_body", message );
|
||||
choiceID = R.string.invite_chooser_sms;
|
||||
String choiceType = activity.getString( choiceID );
|
||||
String chooserMsg =
|
||||
Utils.format( activity, R.string.invite_chooserf, choiceType );
|
||||
activity.startActivity( Intent.createChooser( intent, chooserMsg ) );
|
||||
}
|
||||
|
||||
String choiceType = context.getString( choiceID );
|
||||
String chooserMsg =
|
||||
Utils.format( context, R.string.invite_chooserf, choiceType );
|
||||
context.startActivity( Intent.createChooser( intent, chooserMsg ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -766,10 +865,17 @@ public class GameUtils {
|
|||
activity.startActivity( intent );
|
||||
}
|
||||
|
||||
public static String formatGameID( int gameID )
|
||||
{
|
||||
Assert.assertTrue( 0 != gameID );
|
||||
// substring: Keep it short so fits in SMS better
|
||||
return String.format( "%X", gameID ).substring( 0, 4 );
|
||||
}
|
||||
|
||||
public static String makeRandomID()
|
||||
{
|
||||
int rint = newGameID();
|
||||
return String.format( "%X", rint ).substring( 0, 4 );
|
||||
return formatGameID( rint );
|
||||
}
|
||||
|
||||
public static int newGameID()
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2013 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.nfc.NdefMessage;
|
||||
import android.nfc.NdefRecord;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.NfcEvent;
|
||||
import android.nfc.NfcManager;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class NFCUtils {
|
||||
|
||||
public interface NFCActor {
|
||||
String makeNFCMessage();
|
||||
}
|
||||
|
||||
private static boolean s_inSDK;
|
||||
private static boolean[] s_nfcAvail;
|
||||
private static SafeNFC s_safeNFC;
|
||||
static {
|
||||
s_inSDK = 14 <= Integer.valueOf( android.os.Build.VERSION.SDK );
|
||||
if ( s_inSDK ) {
|
||||
s_safeNFC = new SafeNFCImpl();
|
||||
}
|
||||
}
|
||||
|
||||
private static interface SafeNFC {
|
||||
public void register( Activity activity );
|
||||
}
|
||||
|
||||
private static class SafeNFCImpl implements SafeNFC {
|
||||
public void register( final Activity activity )
|
||||
{
|
||||
Assert.assertTrue( activity instanceof NFCActor );
|
||||
final NFCActor actor = (NFCActor)activity;
|
||||
NfcAdapter.CreateNdefMessageCallback cb =
|
||||
new NfcAdapter.CreateNdefMessageCallback() {
|
||||
public NdefMessage createNdefMessage( NfcEvent event ) {
|
||||
NdefMessage msg = null;
|
||||
String data = actor.makeNFCMessage();
|
||||
if ( null != data ) {
|
||||
msg = makeMessage( activity, data );
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
||||
NfcManager manager =
|
||||
(NfcManager)activity.getSystemService( Context.NFC_SERVICE );
|
||||
NfcAdapter adapter = manager.getDefaultAdapter();
|
||||
adapter.setNdefPushMessageCallback( cb, activity );
|
||||
}
|
||||
}
|
||||
|
||||
// Return array of two booleans, the first indicating whether the
|
||||
// device supports NFC and the second whether it's on. Only the
|
||||
// second can change.
|
||||
public static boolean[] nfcAvail( Context context )
|
||||
{
|
||||
if ( null == s_nfcAvail ) {
|
||||
s_nfcAvail = new boolean[] {
|
||||
s_inSDK && null != getNFCAdapter( context ),
|
||||
false
|
||||
};
|
||||
}
|
||||
if ( s_nfcAvail[0] ) {
|
||||
s_nfcAvail[1] = getNFCAdapter( context ).isEnabled();
|
||||
}
|
||||
return s_nfcAvail;
|
||||
}
|
||||
|
||||
public static String getFromIntent( Intent intent )
|
||||
{
|
||||
String result = null;
|
||||
|
||||
if ( NfcAdapter.ACTION_NDEF_DISCOVERED.equals( intent.getAction() ) ) {
|
||||
Parcelable[] rawMsgs =
|
||||
intent.getParcelableArrayExtra( NfcAdapter.EXTRA_NDEF_MESSAGES );
|
||||
// only one message sent during the beam
|
||||
NdefMessage msg = (NdefMessage)rawMsgs[0];
|
||||
// record 0 contains the MIME type, record 1 is the AAR, if present
|
||||
result = new String( msg.getRecords()[0].getPayload() );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void register( Activity activity )
|
||||
{
|
||||
if ( null != s_safeNFC ) {
|
||||
s_safeNFC.register( activity );
|
||||
}
|
||||
}
|
||||
|
||||
public static Dialog makeEnableNFCDialog( final Activity activity )
|
||||
{
|
||||
DialogInterface.OnClickListener lstnr
|
||||
= new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dialog,
|
||||
int item ) {
|
||||
activity.
|
||||
startActivity( new Intent("android.settings"
|
||||
+ ".NFC_SETTINGS" ) );
|
||||
}
|
||||
};
|
||||
return new AlertDialog.Builder( activity )
|
||||
.setTitle( R.string.info_title )
|
||||
.setMessage( R.string.enable_nfc )
|
||||
.setPositiveButton( R.string.button_cancel, null )
|
||||
.setNegativeButton( R.string.button_go_settings, lstnr )
|
||||
.create();
|
||||
}
|
||||
|
||||
private static NdefMessage makeMessage( Activity activity, String data )
|
||||
{
|
||||
String mimeType = activity.getString( R.string.xwords_nfc_mime );
|
||||
NdefMessage msg = new NdefMessage( new NdefRecord[] {
|
||||
new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
|
||||
mimeType.getBytes(), new byte[0],
|
||||
data.getBytes())
|
||||
,NdefRecord.
|
||||
createApplicationRecord( activity.getPackageName() )
|
||||
});
|
||||
return msg;
|
||||
}
|
||||
|
||||
private static NfcAdapter getNFCAdapter( Context context )
|
||||
{
|
||||
NfcManager manager =
|
||||
(NfcManager)context.getSystemService( Context.NFC_SERVICE );
|
||||
return manager.getDefaultAdapter();
|
||||
}
|
||||
|
||||
}
|
|
@ -57,6 +57,21 @@ public class NetLaunchInfo {
|
|||
bundle.putBoolean( VALID, m_valid );
|
||||
}
|
||||
|
||||
public NetLaunchInfo( String data )
|
||||
{
|
||||
try {
|
||||
JSONObject json = new JSONObject( data );
|
||||
room = json.getString( MultiService.ROOM );
|
||||
inviteID = json.getString( MultiService.INVITEID );
|
||||
lang = json.getInt( MultiService.LANG );
|
||||
dict = json.getString( MultiService.DICT );
|
||||
nPlayersT = json.getInt( MultiService.NPLAYERST );
|
||||
m_valid = true;
|
||||
} catch ( org.json.JSONException jse ) {
|
||||
m_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
public NetLaunchInfo( Bundle bundle )
|
||||
{
|
||||
lang = bundle.getInt( LANG );
|
||||
|
@ -134,6 +149,25 @@ public class NetLaunchInfo {
|
|||
return ub.build();
|
||||
}
|
||||
|
||||
public static String makeLaunchJSON( Context context, String room,
|
||||
String inviteID, int lang,
|
||||
String dict, int nPlayersT )
|
||||
{
|
||||
String result = null;
|
||||
try {
|
||||
result = new JSONObject()
|
||||
.put( MultiService.ROOM, room )
|
||||
.put( MultiService.INVITEID, inviteID )
|
||||
.put( MultiService.LANG, lang )
|
||||
.put( MultiService.DICT, dict )
|
||||
.put( MultiService.NPLAYERST, nPlayersT )
|
||||
.toString();
|
||||
} catch ( org.json.JSONException jse ) {
|
||||
DbgUtils.loge( jse );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return m_valid;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2009-2010 by Eric House (xwords@eehouse.org). All
|
||||
* Copyright 2009 - 2013 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -51,6 +51,7 @@ public class NewGameActivity extends XWActivity {
|
|||
private static final String SAVE_REMOTEGAME = "REMOTEGAME";
|
||||
private static final String SAVE_GAMEID = "GAMEID";
|
||||
private static final String SAVE_NAMEFOR = "SAVE_NAMEFOR";
|
||||
private static final String GROUPID_EXTRA = "groupid";
|
||||
private static final int CONFIG_FOR_BT = 1;
|
||||
private static final int CONFIG_FOR_SMS = 2;
|
||||
private static final int INVITE_FOR_BT = 3;
|
||||
|
@ -58,7 +59,8 @@ public class NewGameActivity extends XWActivity {
|
|||
|
||||
// Dialogs
|
||||
private static final int NAME_GAME = DlgDelegate.DIALOG_LAST + 1;
|
||||
|
||||
private static final int ENABLE_NFC = DlgDelegate.DIALOG_LAST + 2;
|
||||
|
||||
private boolean m_showsOn;
|
||||
private boolean m_nameForBT;
|
||||
private boolean m_firingPrefs = false;
|
||||
|
@ -68,6 +70,7 @@ public class NewGameActivity extends XWActivity {
|
|||
private long m_newRowID = -1;
|
||||
private String m_gameName;
|
||||
private int m_gameID;
|
||||
private long m_groupID;
|
||||
private String m_remoteDev;
|
||||
|
||||
@Override
|
||||
|
@ -76,6 +79,8 @@ public class NewGameActivity extends XWActivity {
|
|||
super.onCreate( savedInstanceState );
|
||||
getBundledData( savedInstanceState );
|
||||
|
||||
m_groupID = getIntent().getLongExtra( GROUPID_EXTRA, -1 );
|
||||
|
||||
setContentView( R.layout.new_game );
|
||||
|
||||
TextView desc = (TextView)findViewById( R.id.newgame_local_desc );
|
||||
|
@ -99,7 +104,7 @@ public class NewGameActivity extends XWActivity {
|
|||
}
|
||||
} );
|
||||
|
||||
button = (Button)findViewById( R.id.newgame_invite );
|
||||
button = (Button)findViewById( R.id.newgame_invite_net );
|
||||
button.setOnClickListener( new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick( View v ) {
|
||||
|
@ -149,12 +154,12 @@ public class NewGameActivity extends XWActivity {
|
|||
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
@Override
|
||||
public void dlgButtonClicked( int id, int which )
|
||||
public void dlgButtonClicked( int id, int which, Object[] params )
|
||||
{
|
||||
switch( id ) {
|
||||
case NEW_GAME_ACTION:
|
||||
if ( DlgDelegate.DISMISS_BUTTON != which ) {
|
||||
makeNewGame( true, true, DlgDelegate.EMAIL_BTN == which );
|
||||
makeNewGame( true, true, which );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -232,8 +237,8 @@ public class NewGameActivity extends XWActivity {
|
|||
m_gameID, m_gameName,
|
||||
m_lang, m_dict, 2, 1 );
|
||||
long rowid = GameUtils.
|
||||
makeNewSMSGame( thiz, m_gameID, null,
|
||||
m_lang, m_dict, 2, 1 );
|
||||
makeNewSMSGame( thiz, m_groupID, m_gameID,
|
||||
null, m_lang, m_dict, 2, 1 );
|
||||
DBUtils.setName( thiz, rowid, m_gameName );
|
||||
GameUtils.launchGame( thiz, rowid, true );
|
||||
finish();
|
||||
|
@ -250,6 +255,9 @@ public class NewGameActivity extends XWActivity {
|
|||
.create();
|
||||
Utils.setRemoveOnDismiss( this, dialog, id );
|
||||
|
||||
break;
|
||||
case ENABLE_NFC:
|
||||
dialog = NFCUtils.makeEnableNFCDialog( this );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -285,8 +293,8 @@ public class NewGameActivity extends XWActivity {
|
|||
public void run() {
|
||||
long rowid =
|
||||
GameUtils.makeNewBTGame( NewGameActivity.this,
|
||||
gameID, null, m_lang,
|
||||
2, 1 );
|
||||
m_groupID, gameID, null,
|
||||
m_lang, 2, 1 );
|
||||
DBUtils.setName( NewGameActivity.this,
|
||||
rowid, m_gameName );
|
||||
GameUtils.launchGame( NewGameActivity.this,
|
||||
|
@ -305,59 +313,67 @@ public class NewGameActivity extends XWActivity {
|
|||
{
|
||||
if ( launch && networked ) {
|
||||
// Let 'em cancel before we make the game
|
||||
showEmailOrSMSThen( NEW_GAME_ACTION );
|
||||
showInviteChoicesThen( NEW_GAME_ACTION );
|
||||
} else {
|
||||
makeNewGame( networked, launch, false );
|
||||
makeNewGame( networked, launch, DlgDelegate.SMS_BTN );
|
||||
}
|
||||
}
|
||||
|
||||
private void makeNewGame( boolean networked, boolean launch,
|
||||
boolean choseEmail )
|
||||
int chosen )
|
||||
{
|
||||
String room = null;
|
||||
String inviteID = null;
|
||||
long rowid;
|
||||
int[] lang = {0};
|
||||
String[] dict = {null};
|
||||
final int nPlayers = 2; // hard-coded for no-configure case
|
||||
|
||||
if ( networked ) {
|
||||
room = GameUtils.makeRandomID();
|
||||
inviteID = GameUtils.makeRandomID();
|
||||
rowid = GameUtils.makeNewNetGame( this, room, inviteID, lang,
|
||||
dict, nPlayers, 1 );
|
||||
if ( DlgDelegate.NFC_BTN == chosen
|
||||
&& !NFCUtils.nfcAvail( this )[1] ) {
|
||||
showDialog( ENABLE_NFC );
|
||||
} else {
|
||||
rowid = GameUtils.saveNew( this, new CurGameInfo( this ) );
|
||||
}
|
||||
String room = null;
|
||||
String inviteID = null;
|
||||
long rowid;
|
||||
int[] lang = {0};
|
||||
String[] dict = {null};
|
||||
final int nPlayers = 2; // hard-coded for no-configure case
|
||||
|
||||
if ( launch ) {
|
||||
GameUtils.launchGame( this, rowid, networked );
|
||||
if ( networked ) {
|
||||
GameUtils.launchInviteActivity( this, choseEmail, room,
|
||||
inviteID, lang[0], dict[0],
|
||||
nPlayers );
|
||||
room = GameUtils.makeRandomID();
|
||||
inviteID = GameUtils.makeRandomID();
|
||||
rowid = GameUtils.makeNewNetGame( this, m_groupID, room, inviteID,
|
||||
lang, dict, nPlayers, 1 );
|
||||
} else {
|
||||
rowid = GameUtils.saveNew( this, new CurGameInfo( this ),
|
||||
m_groupID );
|
||||
}
|
||||
} else {
|
||||
GameUtils.doConfig( this, rowid, GameConfig.class );
|
||||
}
|
||||
|
||||
finish();
|
||||
if ( launch ) {
|
||||
GameUtils.launchGame( this, rowid, networked );
|
||||
if ( networked ) {
|
||||
GameUtils.launchInviteActivity( this, chosen, room,
|
||||
inviteID, lang[0], dict[0],
|
||||
nPlayers );
|
||||
}
|
||||
} else {
|
||||
GameUtils.doConfig( this, rowid, GameConfig.class );
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void makeNewBTGame( boolean useDefaults )
|
||||
{
|
||||
int gameID = GameUtils.newGameID();
|
||||
if ( !useDefaults ) {
|
||||
m_newRowID = GameUtils.makeNewBTGame( NewGameActivity.this,
|
||||
gameID, null, m_lang,
|
||||
2, 1 ); // initial defaults
|
||||
Intent intent = new Intent( this, GameConfig.class );
|
||||
intent.setAction( Intent.ACTION_EDIT );
|
||||
intent.putExtra( GameUtils.INTENT_KEY_ROWID, m_newRowID );
|
||||
intent.putExtra( GameUtils.INTENT_FORRESULT_ROWID, true );
|
||||
startActivityForResult( intent, CONFIG_FOR_BT );
|
||||
} else {
|
||||
BTInviteActivity.launchForResult( this, 1, INVITE_FOR_BT );
|
||||
if ( XWApp.BTSUPPORTED ) {
|
||||
int gameID = GameUtils.newGameID();
|
||||
if ( !useDefaults ) {
|
||||
m_newRowID = GameUtils.makeNewBTGame( NewGameActivity.this,
|
||||
m_groupID, gameID, null,
|
||||
m_lang, 2, 1 );
|
||||
Intent intent = new Intent( this, GameConfig.class );
|
||||
intent.setAction( Intent.ACTION_EDIT );
|
||||
intent.putExtra( GameUtils.INTENT_KEY_ROWID, m_newRowID );
|
||||
intent.putExtra( GameUtils.INTENT_FORRESULT_ROWID, true );
|
||||
startActivityForResult( intent, CONFIG_FOR_BT );
|
||||
} else {
|
||||
BTInviteActivity.launchForResult( this, 1, INVITE_FOR_BT );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,8 +382,8 @@ public class NewGameActivity extends XWActivity {
|
|||
int gameID = GameUtils.newGameID();
|
||||
if ( !useDefaults ) {
|
||||
m_newRowID = GameUtils.makeNewSMSGame( NewGameActivity.this,
|
||||
gameID, null, m_lang,
|
||||
m_dict, 2, 1 );
|
||||
m_groupID, gameID, null,
|
||||
m_lang, m_dict, 2, 1 );
|
||||
String name = Utils.format( this, R.string.dft_sms_namef,
|
||||
gameID & 0xFFFF );
|
||||
DBUtils.setName( this, m_newRowID, name );
|
||||
|
@ -468,4 +484,11 @@ public class NewGameActivity extends XWActivity {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void startActivity( Activity parent, long groupID )
|
||||
{
|
||||
Intent intent = new Intent( parent, NewGameActivity.class );
|
||||
intent.putExtra( GROUPID_EXTRA, groupID );
|
||||
parent.startActivity( intent );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,15 @@
|
|||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
@ -37,11 +39,16 @@ public class PrefsActivity extends PreferenceActivity
|
|||
private static final int REVERT_COLORS = 1;
|
||||
private static final int REVERT_ALL = 2;
|
||||
public static final int CONFIRM_SMS = 3;
|
||||
public static final int EXPLAIN_TITLE = 4;
|
||||
|
||||
private String m_keyLogging;
|
||||
private String m_smsToasting;
|
||||
private String m_smsEnable;
|
||||
private String m_downloadPath;
|
||||
private String m_thumbEnabled;
|
||||
private String m_thumbSize;
|
||||
private String m_hideTitle;
|
||||
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog( int id )
|
||||
|
@ -97,6 +104,13 @@ public class PrefsActivity extends PreferenceActivity
|
|||
case CONFIRM_SMS:
|
||||
dialog = SMSCheckBoxPreference.onCreateDialog( this, id );
|
||||
break;
|
||||
case EXPLAIN_TITLE:
|
||||
dialog = new AlertDialog.Builder( this )
|
||||
.setMessage( R.string.no_hide_titlebar )
|
||||
.setTitle( R.string.info_title )
|
||||
.setPositiveButton( R.string.button_ok, null )
|
||||
.create();
|
||||
break;
|
||||
}
|
||||
|
||||
if ( null == dialog && null != lstnr ) {
|
||||
|
@ -123,6 +137,9 @@ public class PrefsActivity extends PreferenceActivity
|
|||
m_smsToasting = getString( R.string.key_show_sms );
|
||||
m_smsEnable = getString( R.string.key_enable_sms );
|
||||
m_downloadPath = getString( R.string.key_download_path );
|
||||
m_thumbEnabled = getString( R.string.key_thumb_enabled );
|
||||
m_thumbSize = getString( R.string.key_thumbsize );
|
||||
m_hideTitle = getString( R.string.key_hide_title );
|
||||
|
||||
Button button = (Button)findViewById( R.id.revert_colors );
|
||||
button.setOnClickListener( new View.OnClickListener() {
|
||||
|
@ -185,7 +202,18 @@ public class PrefsActivity extends PreferenceActivity
|
|||
}
|
||||
}
|
||||
DictUtils.invalDictList();
|
||||
}
|
||||
} else if ( key.equals( m_thumbEnabled )
|
||||
|| key.equals( m_thumbSize ) ) {
|
||||
DBUtils.clearThumbnails( this );
|
||||
} else if ( key.equals( m_hideTitle ) ) {
|
||||
if ( sp.getBoolean( key, false ) && ABUtils.haveActionBar() ) {
|
||||
CheckBoxPreference pref
|
||||
= (CheckBoxPreference)findPreference(key);
|
||||
pref.setChecked( false );
|
||||
pref.setEnabled( false );
|
||||
showDialog( EXPLAIN_TITLE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void relaunch()
|
||||
|
|
|
@ -367,7 +367,7 @@ public class RelayService extends XWService
|
|||
|
||||
private boolean startFetchThreadIf()
|
||||
{
|
||||
DbgUtils.logf( "startFetchThreadIf()" );
|
||||
// DbgUtils.logf( "startFetchThreadIf()" );
|
||||
boolean handled = !XWApp.UDP_ENABLED;
|
||||
if ( handled && null == m_fetchThread ) {
|
||||
m_fetchThread = new Thread( null, new Runnable() {
|
||||
|
@ -416,7 +416,7 @@ public class RelayService extends XWService
|
|||
resetExitTimer();
|
||||
gotPacket( packet );
|
||||
} catch ( java.io.InterruptedIOException iioe ) {
|
||||
DbgUtils.logf( "FYI: udp receive timeout" );
|
||||
// DbgUtils.logf( "FYI: udp receive timeout" );
|
||||
} catch( java.io.IOException ioe ) {
|
||||
break;
|
||||
}
|
||||
|
@ -675,8 +675,8 @@ public class RelayService extends XWService
|
|||
DbgUtils.logf( "registering devID \"%s\" (type=%s)", devid,
|
||||
typ.toString() );
|
||||
|
||||
out.writeShort( GitVersion.CLIENT_VERS_RELAY );
|
||||
writeVLIString( out, GitVersion.VERS );
|
||||
out.writeShort( BuildConstants.CLIENT_VERS_RELAY );
|
||||
writeVLIString( out, BuildConstants.GIT_REV );
|
||||
writeVLIString( out, Build.MODEL );
|
||||
writeVLIString( out, Build.VERSION.RELEASE );
|
||||
|
||||
|
@ -1191,7 +1191,7 @@ public class RelayService extends XWService
|
|||
long interval = Utils.getCurSeconds() - m_lastGamePacketReceived;
|
||||
result = interval < MAX_KEEPALIVE_SECS;
|
||||
}
|
||||
DbgUtils.logf( "RelayService.shouldMaintainConnection=>%b", result );
|
||||
// DbgUtils.logf( "RelayService.shouldMaintainConnection=>%b", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ public class SMSInviteActivity extends InviteActivity {
|
|||
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
@Override
|
||||
public void dlgButtonClicked( int id, int which )
|
||||
public void dlgButtonClicked( int id, int which, Object[] params )
|
||||
{
|
||||
switch( which ) {
|
||||
case AlertDialog.BUTTON_POSITIVE:
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2009-2013 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import org.eehouse.android.xw4.jni.GameSummary;
|
||||
|
||||
// Interfaces used for (list) items that are selectable via
|
||||
// long-tapping.
|
||||
|
||||
public interface SelectableItem {
|
||||
|
||||
public interface LongClickHandler {
|
||||
public void longClicked();
|
||||
}
|
||||
|
||||
public void itemClicked( LongClickHandler clicked, GameSummary summary );
|
||||
public void itemToggled( LongClickHandler toggled, boolean selected );
|
||||
public boolean getSelected( LongClickHandler obj );
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2013 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
|
||||
public class ThumbCanvas extends BoardCanvas {
|
||||
|
||||
public ThumbCanvas( Activity activity, Bitmap bitmap )
|
||||
{
|
||||
super( activity, bitmap, null, null );
|
||||
DbgUtils.logf( "creating new ThumbCanvas" );
|
||||
}
|
||||
|
||||
// These should not be needed if common code gets fixed! So the
|
||||
// whole class should go away. PENDING
|
||||
@Override
|
||||
public boolean scoreBegin( Rect rect, int numPlayers, int[] scores,
|
||||
int remCount )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trayBegin( Rect rect, int owner, int score )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -107,7 +107,8 @@ public class Toolbar {
|
|||
}
|
||||
}
|
||||
|
||||
private void setLongClickListener( int index, View.OnLongClickListener listener )
|
||||
private void setLongClickListener( int index,
|
||||
View.OnLongClickListener listener )
|
||||
{
|
||||
ImageButton button = getViewFor( index );
|
||||
if ( null != button ) {
|
||||
|
@ -126,8 +127,8 @@ public class Toolbar {
|
|||
setListener( index, listener );
|
||||
}
|
||||
|
||||
public void setLongClickListener( int index, final int msgID, final int prefsKey,
|
||||
final int callback )
|
||||
public void setLongClickListener( int index, final int msgID,
|
||||
final int prefsKey, final int callback )
|
||||
{
|
||||
View.OnLongClickListener listener = new View.OnLongClickListener() {
|
||||
public boolean onLongClick( View view ) {
|
||||
|
|
|
@ -121,7 +121,7 @@ public class UpdateCheckReceiver extends BroadcastReceiver {
|
|||
|
||||
appParams.put( k_NAME, packageName );
|
||||
appParams.put( k_AVERS, versionCode );
|
||||
appParams.put( k_GVERS, GitVersion.VERS );
|
||||
appParams.put( k_GVERS, BuildConstants.GIT_REV );
|
||||
appParams.put( k_INSTALLER, installer );
|
||||
if ( devOK( context ) ) {
|
||||
appParams.put( k_DEVOK, true );
|
||||
|
|
|
@ -28,7 +28,6 @@ import android.app.PendingIntent;
|
|||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.SharedPreferences;
|
||||
|
@ -72,24 +71,6 @@ public class Utils {
|
|||
private static Boolean s_hasSmallScreen = null;
|
||||
private static Random s_random = new Random();
|
||||
|
||||
private static interface SafeInvalOptionsMenu {
|
||||
public void doInval( Activity activity );
|
||||
}
|
||||
|
||||
private static class SafeInvalOptionsMenuImpl
|
||||
implements SafeInvalOptionsMenu {
|
||||
public void doInval( Activity activity ) {
|
||||
activity.invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
private static SafeInvalOptionsMenu s_safeInval = null;
|
||||
static {
|
||||
int sdkVersion = Integer.valueOf( android.os.Build.VERSION.SDK );
|
||||
if ( 11 <= sdkVersion ) {
|
||||
s_safeInval = new SafeInvalOptionsMenuImpl();
|
||||
}
|
||||
}
|
||||
|
||||
private Utils() {}
|
||||
|
||||
public static int nextRandomInt()
|
||||
|
@ -172,7 +153,7 @@ public class Utils {
|
|||
String[] addrs = { context.getString( R.string.email_author_email ) };
|
||||
intent.putExtra( Intent.EXTRA_EMAIL, addrs );
|
||||
String body = format( context, R.string.email_body_revf,
|
||||
GitVersion.VERS );
|
||||
BuildConstants.GIT_REV );
|
||||
intent.putExtra( Intent.EXTRA_TEXT, body );
|
||||
String chooserMsg = context.getString( R.string.email_author_chooser );
|
||||
context.startActivity( Intent.createChooser( intent, chooserMsg ) );
|
||||
|
@ -376,13 +357,6 @@ public class Utils {
|
|||
item.setEnabled( enabled );
|
||||
}
|
||||
|
||||
public static void invalidateOptionsMenuIf( Activity activity )
|
||||
{
|
||||
if ( null != s_safeInval ) {
|
||||
s_safeInval.doInval( activity );
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasSmallScreen( Context context )
|
||||
{
|
||||
if ( null == s_hasSmallScreen ) {
|
||||
|
|
|
@ -106,6 +106,12 @@ public class XWActivity extends Activity
|
|||
m_delegate.showAboutDialog();
|
||||
}
|
||||
|
||||
protected void showNotAgainDlgThen( String msg, int prefsKey,
|
||||
int action )
|
||||
{
|
||||
m_delegate.showNotAgainDlgThen( msg, prefsKey, action, null );
|
||||
}
|
||||
|
||||
protected void showNotAgainDlgThen( int msgID, int prefsKey,
|
||||
int action )
|
||||
{
|
||||
|
@ -147,9 +153,9 @@ public class XWActivity extends Activity
|
|||
m_delegate.showConfirmThen( getString(msg), posButton, action );
|
||||
}
|
||||
|
||||
public void showEmailOrSMSThen( int action )
|
||||
public void showInviteChoicesThen( int action )
|
||||
{
|
||||
m_delegate.showEmailOrSMSThen( action );
|
||||
m_delegate.showInviteChoicesThen( action );
|
||||
}
|
||||
|
||||
protected void doSyncMenuitem()
|
||||
|
@ -178,7 +184,7 @@ public class XWActivity extends Activity
|
|||
}
|
||||
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
public void dlgButtonClicked( int id, int which )
|
||||
public void dlgButtonClicked( int id, int which, Object[] params )
|
||||
{
|
||||
Assert.fail();
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public class XWApp extends Application {
|
|||
|
||||
public static final String SMS_PUBLIC_HEADER = "-XW4";
|
||||
public static final int MAX_TRAY_TILES = 7; // comtypes.h
|
||||
public static final int SEL_COLOR = Color.argb( 255, 127, 127, 255 );
|
||||
public static final int SEL_COLOR = Color.argb( 0xFF, 0x09, 0x70, 0x93 );
|
||||
|
||||
private static UUID s_UUID = null;
|
||||
private static Boolean s_onEmulator = null;
|
||||
|
|
|
@ -84,6 +84,12 @@ public class XWExpandableListActivity extends ExpandableListActivity
|
|||
m_delegate.doSyncMenuitem();
|
||||
}
|
||||
|
||||
protected void showNotAgainDlgThen( int msgID, int prefsKey,
|
||||
int action, Object... params )
|
||||
{
|
||||
m_delegate.showNotAgainDlgThen( msgID, prefsKey, action, params );
|
||||
}
|
||||
|
||||
protected void showNotAgainDlgThen( int msgID, int prefsKey,
|
||||
int action )
|
||||
{
|
||||
|
@ -111,23 +117,25 @@ public class XWExpandableListActivity extends ExpandableListActivity
|
|||
m_delegate.showOKOnlyDialog( msg );
|
||||
}
|
||||
|
||||
protected void showConfirmThen( String msg, int action )
|
||||
protected void showConfirmThen( String msg, int action, Object... params )
|
||||
{
|
||||
m_delegate.showConfirmThen( msg, action );
|
||||
m_delegate.showConfirmThen( msg, action, params );
|
||||
}
|
||||
|
||||
protected void showConfirmThen( String msg, int posButton, int action )
|
||||
protected void showConfirmThen( String msg, int posButton, int action,
|
||||
Object... params )
|
||||
{
|
||||
m_delegate.showConfirmThen( msg, posButton, action );
|
||||
m_delegate.showConfirmThen( msg, posButton, action, params );
|
||||
}
|
||||
|
||||
protected void showConfirmThen( int msg, int posButton, int action )
|
||||
protected void showConfirmThen( int msg, int posButton, int action,
|
||||
Object... params )
|
||||
{
|
||||
m_delegate.showConfirmThen( getString(msg), posButton, action );
|
||||
m_delegate.showConfirmThen( getString(msg), posButton, action, params );
|
||||
}
|
||||
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
public void dlgButtonClicked( int id, int which )
|
||||
public void dlgButtonClicked( int id, int which, Object[] params )
|
||||
{
|
||||
Assert.fail();
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ public class XWListActivity extends ListActivity
|
|||
}
|
||||
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
public void dlgButtonClicked( int id, int which )
|
||||
public void dlgButtonClicked( int id, int which, Object[] params )
|
||||
{
|
||||
Assert.fail();
|
||||
}
|
||||
|
|
|
@ -20,19 +20,25 @@
|
|||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ImageButton;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class XWListItem extends LinearLayout {
|
||||
|
||||
public class XWListItem extends LinearLayout
|
||||
implements SelectableItem.LongClickHandler {
|
||||
private int m_position;
|
||||
private Context m_context;
|
||||
private Object m_cached;
|
||||
private DeleteCallback m_cb;
|
||||
private DeleteCallback m_delCb;
|
||||
private Drawable m_origDrawable;
|
||||
private boolean m_selected = false;
|
||||
private SelectableItem m_selCb;
|
||||
|
||||
public interface DeleteCallback {
|
||||
void deleteCalled( XWListItem item );
|
||||
|
@ -69,17 +75,29 @@ public class XWListItem extends LinearLayout {
|
|||
|
||||
public void setDeleteCallback( DeleteCallback cb )
|
||||
{
|
||||
m_cb = cb;
|
||||
m_delCb = cb;
|
||||
ImageButton button = (ImageButton)findViewById( R.id.del );
|
||||
button.setOnClickListener( new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick( View view ) {
|
||||
m_cb.deleteCalled( XWListItem.this );
|
||||
m_delCb.deleteCalled( XWListItem.this );
|
||||
}
|
||||
} );
|
||||
button.setVisibility( View.VISIBLE );
|
||||
}
|
||||
|
||||
public void setSelCB( SelectableItem selCB )
|
||||
{
|
||||
m_selCb = selCB;
|
||||
}
|
||||
|
||||
public void setSelected( boolean selected )
|
||||
{
|
||||
if ( selected != m_selected ) {
|
||||
toggleSelected();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled( boolean enabled )
|
||||
{
|
||||
|
@ -105,4 +123,21 @@ public class XWListItem extends LinearLayout {
|
|||
return m_cached;
|
||||
}
|
||||
|
||||
// SelectableItem.LongClickHandler interface
|
||||
public void longClicked()
|
||||
{
|
||||
toggleSelected();
|
||||
}
|
||||
|
||||
private void toggleSelected()
|
||||
{
|
||||
m_selected = !m_selected;
|
||||
if ( m_selected ) {
|
||||
m_origDrawable = getBackground();
|
||||
setBackgroundColor( XWApp.SEL_COLOR );
|
||||
} else {
|
||||
setBackgroundDrawable( m_origDrawable );
|
||||
}
|
||||
m_selCb.itemToggled( this, m_selected );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,12 @@ import android.util.AttributeSet;
|
|||
import junit.framework.Assert;
|
||||
|
||||
public class XWListPreference extends ListPreference {
|
||||
protected Context m_context;
|
||||
|
||||
public XWListPreference( Context context, AttributeSet attrs )
|
||||
{
|
||||
super( context, attrs );
|
||||
m_context = context;
|
||||
}
|
||||
|
||||
protected void onAttachedToActivity()
|
||||
|
|
|
@ -27,6 +27,8 @@ import android.text.TextUtils;
|
|||
import com.google.android.gcm.GCMRegistrar;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class XWPrefs {
|
||||
|
||||
public static boolean getSMSEnabled( Context context )
|
||||
|
@ -39,6 +41,11 @@ public class XWPrefs {
|
|||
return getPrefsBoolean( context, R.string.key_enable_debug, false );
|
||||
}
|
||||
|
||||
public static boolean getSecondInviteAllowed( Context context )
|
||||
{
|
||||
return getPrefsBoolean( context, R.string.key_enable_dup_invite, false );
|
||||
}
|
||||
|
||||
public static String getDefaultRelayHost( Context context )
|
||||
{
|
||||
return getPrefsString( context, R.string.key_relay_host );
|
||||
|
@ -296,12 +303,19 @@ public class XWPrefs {
|
|||
|
||||
public static long getDefaultNewGameGroup( Context context )
|
||||
{
|
||||
return getPrefsLong( context, R.string.key_default_group,
|
||||
DBUtils.ROWID_NOTFOUND );
|
||||
long groupID = getPrefsLong( context, R.string.key_default_group,
|
||||
DBUtils.GROUPID_UNSPEC );
|
||||
if ( DBUtils.GROUPID_UNSPEC == groupID ) {
|
||||
groupID = DBUtils.getAnyGroup( context );
|
||||
setPrefsLong( context, R.string.key_default_group, groupID );
|
||||
}
|
||||
Assert.assertTrue( DBUtils.GROUPID_UNSPEC != groupID );
|
||||
return groupID;
|
||||
}
|
||||
|
||||
public static void setDefaultNewGameGroup( Context context, long val )
|
||||
{
|
||||
Assert.assertTrue( DBUtils.GROUPID_UNSPEC != val );
|
||||
setPrefsLong( context, R.string.key_default_group, val );
|
||||
}
|
||||
|
||||
|
@ -328,6 +342,32 @@ public class XWPrefs {
|
|||
return posns;
|
||||
}
|
||||
|
||||
public static boolean getThumbEnabled( Context context )
|
||||
{
|
||||
return getPrefsBoolean( context, R.string.key_thumb_enabled, false );
|
||||
}
|
||||
|
||||
public static int getThumbScale( Context context )
|
||||
{
|
||||
String scale = getPrefsString( context, R.string.key_thumbsize );
|
||||
int result = -1;
|
||||
final int[][] data = {
|
||||
{ R.string.game_thumb_half, 2 }
|
||||
,{ R.string.game_thumb_third, 3 }
|
||||
,{ R.string.game_thumb_quarter, 4 }
|
||||
,{ R.string.game_thumb_fifth, 5 }
|
||||
,{ R.string.game_thumb_sixth, 6 }
|
||||
};
|
||||
|
||||
for ( int[] datum : data ) {
|
||||
if ( context.getString(datum[0]).equals(scale) ) {
|
||||
result = datum[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected static String getPrefsString( Context context, int keyID )
|
||||
{
|
||||
String key = context.getString( keyID );
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2010 - 2011 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
public class XWSumListPreference extends XWListPreference {
|
||||
|
||||
private static final int[] s_ADDROWS = {
|
||||
R.string.game_summary_field_rowid,
|
||||
R.string.game_summary_field_gameid,
|
||||
};
|
||||
|
||||
public XWSumListPreference( Context context, AttributeSet attrs )
|
||||
{
|
||||
super( context, attrs );
|
||||
}
|
||||
|
||||
// Why I exist: insert the rowid and gameid lines if debug is on
|
||||
protected void onAttachedToActivity()
|
||||
{
|
||||
super.onAttachedToActivity();
|
||||
|
||||
if ( BuildConstants.IS_DEBUG_BUILD ||
|
||||
XWPrefs.getDebugEnabled( m_context ) ) {
|
||||
CharSequence[] entries = getEntries();
|
||||
CharSequence lastRow = entries[entries.length - 1];
|
||||
boolean done = false;
|
||||
|
||||
String[] addRows = new String[s_ADDROWS.length];
|
||||
for ( int ii = 0; !done && ii < s_ADDROWS.length; ++ii ) {
|
||||
String addRow = m_context.getString( s_ADDROWS[ii] );
|
||||
done = lastRow.equals( addRow );
|
||||
addRows[ii] = addRow;
|
||||
}
|
||||
|
||||
if ( !done ) {
|
||||
CharSequence[] newEntries =
|
||||
new CharSequence[entries.length + addRows.length];
|
||||
System.arraycopy( entries, 0, newEntries, 0,
|
||||
entries.length );
|
||||
System.arraycopy( addRows, 0, newEntries, entries.length,
|
||||
addRows.length );
|
||||
setEntries( newEntries );
|
||||
|
||||
setEntryValues( newEntries );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -24,7 +24,9 @@ import android.content.Context;
|
|||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.XWPrefs;
|
||||
|
@ -239,7 +241,9 @@ public class CommonPrefs extends XWPrefs {
|
|||
|
||||
public static boolean getHideTitleBar( Context context )
|
||||
{
|
||||
return getPrefsBoolean( context, R.string.key_hide_title, false );
|
||||
boolean hideByDefault = 11 > Integer.valueOf( Build.VERSION.SDK );
|
||||
return getPrefsBoolean( context, R.string.key_hide_title,
|
||||
hideByDefault );
|
||||
}
|
||||
|
||||
public static boolean getSoundNotify( Context context )
|
||||
|
@ -252,11 +256,6 @@ public class CommonPrefs extends XWPrefs {
|
|||
return getPrefsBoolean( context, R.string.key_notify_vibrate, false );
|
||||
}
|
||||
|
||||
public static boolean getHideIntro( Context context )
|
||||
{
|
||||
return getPrefsBoolean( context, R.string.key_hide_intro, false );
|
||||
}
|
||||
|
||||
public static boolean getKeepScreenOn( Context context )
|
||||
{
|
||||
return getPrefsBoolean( context, R.string.key_keep_screenon, false );
|
||||
|
|
|
@ -60,11 +60,12 @@ public class CurGameInfo {
|
|||
|
||||
public CurGameInfo( Context context )
|
||||
{
|
||||
this( context, false );
|
||||
this( context, (String)null );
|
||||
}
|
||||
|
||||
public CurGameInfo( Context context, boolean isNetworked )
|
||||
public CurGameInfo( Context context, String inviteID )
|
||||
{
|
||||
boolean isNetworked = null != inviteID;
|
||||
m_context = context;
|
||||
nPlayers = 2;
|
||||
gameSeconds = 60 * nPlayers *
|
||||
|
@ -81,6 +82,11 @@ public class CurGameInfo {
|
|||
allowHintRect = false;
|
||||
m_smartness = 0; // needs to be set from players
|
||||
|
||||
try {
|
||||
gameID = (null == inviteID) ? 0 : Integer.parseInt( inviteID, 16 );
|
||||
} catch ( Exception ex ) {
|
||||
}
|
||||
|
||||
// Always create MAX_NUM_PLAYERS so jni code doesn't ever have
|
||||
// to cons up a LocalPlayer instance.
|
||||
for ( int ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) {
|
||||
|
|
|
@ -63,10 +63,10 @@ public interface DrawCtx {
|
|||
void drawBoardArrow ( Rect rect, int bonus, boolean vert, int hintAtts,
|
||||
int flags );
|
||||
boolean trayBegin ( Rect rect, int owner, int score );
|
||||
void drawTile( Rect rect, String text, int val, int flags );
|
||||
void drawTileMidDrag ( Rect rect, String text, int val, int owner,
|
||||
int flags );
|
||||
void drawTileBack( Rect rect, int flags );
|
||||
boolean drawTile( Rect rect, String text, int val, int flags );
|
||||
boolean drawTileMidDrag ( Rect rect, String text, int val, int owner,
|
||||
int flags );
|
||||
boolean drawTileBack( Rect rect, int flags );
|
||||
void drawTrayDivider( Rect rect, int flags );
|
||||
void score_pendingScore( Rect rect, int score, int playerNum, int curTurn,
|
||||
int flags );
|
||||
|
|
|
@ -21,11 +21,14 @@
|
|||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.DbgUtils;
|
||||
import org.eehouse.android.xw4.R;
|
||||
import org.eehouse.android.xw4.Utils;
|
||||
import org.eehouse.android.xw4.DbgUtils;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
|
||||
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
|
||||
|
||||
|
@ -66,6 +69,7 @@ public class GameSummary {
|
|||
private CurGameInfo m_gi;
|
||||
private Context m_context;
|
||||
private String[] m_remotePhones;
|
||||
private Bitmap m_thumb;
|
||||
|
||||
private GameSummary() {}
|
||||
|
||||
|
@ -85,6 +89,16 @@ public class GameSummary {
|
|||
m_gi = gi;
|
||||
}
|
||||
|
||||
public void setThumbnail( Bitmap thumb )
|
||||
{
|
||||
m_thumb = thumb;
|
||||
}
|
||||
|
||||
public Bitmap getThumbnail()
|
||||
{
|
||||
return m_thumb;
|
||||
}
|
||||
|
||||
public boolean inNetworkGame()
|
||||
{
|
||||
return null != relayID;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
|
@ -31,21 +32,25 @@ import java.util.Arrays;
|
|||
import java.util.Iterator;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.eehouse.android.xw4.R;
|
||||
import org.eehouse.android.xw4.DbgUtils;
|
||||
import org.eehouse.android.xw4.ConnStatusHandler;
|
||||
import org.eehouse.android.xw4.BoardDims;
|
||||
import org.eehouse.android.xw4.ConnStatusHandler;
|
||||
import org.eehouse.android.xw4.DBUtils;
|
||||
import org.eehouse.android.xw4.DbgUtils;
|
||||
import org.eehouse.android.xw4.GameLock;
|
||||
import org.eehouse.android.xw4.GameUtils;
|
||||
import org.eehouse.android.xw4.DBUtils;
|
||||
import org.eehouse.android.xw4.R;
|
||||
import org.eehouse.android.xw4.Toolbar;
|
||||
import org.eehouse.android.xw4.XWPrefs;
|
||||
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
|
||||
import org.eehouse.android.xw4.jni.DrawCtx;
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class JNIThread extends Thread {
|
||||
|
||||
public enum JNICmd { CMD_NONE,
|
||||
// CMD_RUN,
|
||||
CMD_DRAW,
|
||||
CMD_SETDRAW,
|
||||
CMD_INVALALL,
|
||||
CMD_LAYOUT,
|
||||
CMD_START,
|
||||
|
@ -91,12 +96,11 @@ public class JNIThread extends Thread {
|
|||
};
|
||||
|
||||
public static final int RUNNING = 1;
|
||||
public static final int DRAW = 2;
|
||||
public static final int DIALOG = 3;
|
||||
public static final int QUERY_ENDGAME = 4;
|
||||
public static final int TOOLBAR_STATES = 5;
|
||||
public static final int GOT_WORDS = 6;
|
||||
public static final int GAME_OVER = 7;
|
||||
public static final int DIALOG = 2;
|
||||
public static final int QUERY_ENDGAME = 3;
|
||||
public static final int TOOLBAR_STATES = 4;
|
||||
public static final int GOT_WORDS = 5;
|
||||
public static final int GAME_OVER = 6;
|
||||
|
||||
public class GameStateInfo implements Cloneable {
|
||||
public int visTileCount;
|
||||
|
@ -108,6 +112,7 @@ public class JNIThread extends Thread {
|
|||
public boolean canChat;
|
||||
public boolean canShuffle;
|
||||
public boolean curTurnSelected;
|
||||
public boolean canHideRack;
|
||||
public GameStateInfo clone() {
|
||||
GameStateInfo obj = null;
|
||||
try {
|
||||
|
@ -230,32 +235,25 @@ public class JNIThread extends Thread {
|
|||
Message.obtain( m_handler, DIALOG, titleArg, 0, text ).sendToTarget();
|
||||
}
|
||||
|
||||
private void doLayout( BoardDims dims )
|
||||
private void doLayout( int width, int height, int fontWidth,
|
||||
int fontHeight )
|
||||
{
|
||||
int scoreWidth = dims.width - dims.cellSize;
|
||||
ConnStatusHandler.setRect( scoreWidth, 0, scoreWidth + dims.cellSize,
|
||||
dims.scoreHt );
|
||||
BoardDims dims = new BoardDims();
|
||||
|
||||
if ( m_gi.timerEnabled ) {
|
||||
scoreWidth -= dims.timerWidth;
|
||||
XwJNI.board_setTimerLoc( m_jniGamePtr, scoreWidth, 0,
|
||||
dims.timerWidth, dims.scoreHt );
|
||||
}
|
||||
XwJNI.board_setScoreboardLoc( m_jniGamePtr, 0, 0, scoreWidth,
|
||||
dims.scoreHt, true );
|
||||
boolean squareTiles = XWPrefs.getSquareTiles( m_context );
|
||||
int statusWidth = width / 15;
|
||||
int scoreWidth = width - statusWidth;
|
||||
XwJNI.board_figureLayout( m_jniGamePtr, m_gi, 0, 0, width, height,
|
||||
150, 200, scoreWidth, fontWidth,
|
||||
fontHeight, squareTiles, dims );
|
||||
|
||||
// Have no idea why I was doing -1 below, but it breaks layout
|
||||
// for small (QVGA) boards. If it needs to be done, do it
|
||||
// early in figureBoardDims so the calculations that follow
|
||||
// are consistent.
|
||||
XwJNI.board_setPos( m_jniGamePtr, 0, dims.scoreHt,
|
||||
dims.width/*-1*/, dims.boardHt, dims.maxCellSize,
|
||||
false );
|
||||
ConnStatusHandler.setRect( dims.left + scoreWidth, dims.top,
|
||||
dims.left + scoreWidth + statusWidth,
|
||||
dims.top + dims.scoreHt );
|
||||
|
||||
XwJNI.board_setTrayLoc( m_jniGamePtr, 0, dims.trayTop,
|
||||
dims.width/*-1*/, dims.trayHt, kMinDivWidth );
|
||||
XwJNI.board_applyLayout( m_jniGamePtr, dims );
|
||||
|
||||
XwJNI.board_invalAll( m_jniGamePtr );
|
||||
m_drawer.dimsChanged( dims );
|
||||
}
|
||||
|
||||
private boolean nextSame( JNICmd cmd )
|
||||
|
@ -329,6 +327,11 @@ public class JNIThread extends Thread {
|
|||
args = elem.m_args;
|
||||
switch( elem.m_cmd ) {
|
||||
|
||||
// case CMD_RUN:
|
||||
// Runnable proc = (Runnable)args[0];
|
||||
// proc.run();
|
||||
// break;
|
||||
|
||||
case CMD_SAVE:
|
||||
if ( nextSame( JNICmd.CMD_SAVE ) ) {
|
||||
continue;
|
||||
|
@ -348,13 +351,26 @@ public class JNIThread extends Thread {
|
|||
draw = true;
|
||||
break;
|
||||
|
||||
case CMD_SETDRAW:
|
||||
XwJNI.board_setDraw( m_jniGamePtr, (DrawCtx)args[0] );
|
||||
XwJNI.board_invalAll( m_jniGamePtr );
|
||||
break;
|
||||
|
||||
case CMD_INVALALL:
|
||||
XwJNI.board_invalAll( m_jniGamePtr );
|
||||
draw = true;
|
||||
break;
|
||||
|
||||
case CMD_LAYOUT:
|
||||
doLayout( (BoardDims)args[0] );
|
||||
Object args0 = args[0];
|
||||
BoardDims dims = null;
|
||||
if ( args0 instanceof BoardDims ) {
|
||||
dims = (BoardDims)args0;
|
||||
XwJNI.board_applyLayout( m_jniGamePtr, dims );
|
||||
} else {
|
||||
doLayout( (Integer)args0, (Integer)args[1],
|
||||
(Integer)args[2], (Integer)args[3] );
|
||||
}
|
||||
draw = true;
|
||||
// check and disable zoom button at limit
|
||||
handle( JNICmd.CMD_ZOOM, 0 );
|
||||
|
@ -615,10 +631,6 @@ public class JNIThread extends Thread {
|
|||
// of the same bitmap for blitting.
|
||||
m_drawer.doJNIDraw();
|
||||
|
||||
// main UI thread has to invalidate view as it created
|
||||
// it.
|
||||
Message.obtain( m_handler, DRAW ).sendToTarget();
|
||||
|
||||
checkButtons();
|
||||
}
|
||||
} // for
|
||||
|
@ -640,6 +652,17 @@ public class JNIThread extends Thread {
|
|||
{
|
||||
QueueElem elem = new QueueElem( cmd, true, args );
|
||||
m_queue.add( elem );
|
||||
if ( m_stopped && ! JNICmd.CMD_NONE.equals(cmd) ) {
|
||||
DbgUtils.logf( "WARNING: adding %s to stopped thread!!!",
|
||||
cmd.toString() );
|
||||
DbgUtils.printStack();
|
||||
}
|
||||
}
|
||||
|
||||
// public void run( boolean isUI, Runnable runnable )
|
||||
// {
|
||||
// Object[] args = { runnable };
|
||||
// QueueElem elem = new QueueElem( JNICmd.CMD_RUN, isUI, args );
|
||||
// m_queue.add( elem );
|
||||
// }
|
||||
}
|
||||
|
|