Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion app/src/main/kotlin/org/carstenf/wordfinder/GameState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.carstenf.wordfinder.dictionary.Dictionary
import org.carstenf.wordfinder.letters.LANGUAGE
import org.carstenf.wordfinder.letters.pickRandomLetter
import org.carstenf.wordfinder.util.CountUpTimer
import org.carstenf.wordfinder.util.Result
import org.carstenf.wordfinder.util.SolveTask
import java.util.Arrays
import java.util.Locale

Expand Down Expand Up @@ -55,7 +59,12 @@ class GameState : ViewModel() {
Log.d(WordFinder.TAG, "Letter selector: ${letterRandomDistCur.name}") // NON-NLS

for (i in 0..15) {
board[i] = pickRandomLetter(letterRandomDistCur, letterCounts, dictionaryCountryCode(), i).uppercaseChar()
board[i] = pickRandomLetter(
letterRandomDistCur,
letterCounts,
dictionaryCountryCode(),
i
).uppercaseChar()
}

board.shuffle()
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/kotlin/org/carstenf/wordfinder/WordFinder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import org.carstenf.wordfinder.gui.AppCompatLetterButton
import org.carstenf.wordfinder.gui.BackGestureBlockingTableLayout
import org.carstenf.wordfinder.gui.ComputerResultListAdapter
import org.carstenf.wordfinder.gui.drawConnectionsBetweenButtons
import org.carstenf.wordfinder.util.Result
import org.carstenf.wordfinder.util.addGestureHandler
import org.carstenf.wordfinder.util.isGestureNavigationEnabled
import org.carstenf.wordfinder.util.parseTime
Expand Down Expand Up @@ -654,7 +655,7 @@ class WordFinder : AppCompatActivity(), OnSharedPreferenceChangeListener {
private fun insertPlayerResult(guess: Dictionary.WordInfoData) {
playerResultList.insert(Result(guess), 0)
playerResultList.sort {
object1: Result, object2: Result ->
object1: Result, object2: Result ->
val s1 = object1.toString()
val s2 = object2.toString()
s1.compareTo(s2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.widget.Toast
import androidx.lifecycle.MutableLiveData
import org.carstenf.wordfinder.GameState
import org.carstenf.wordfinder.R
import org.carstenf.wordfinder.Result
import org.carstenf.wordfinder.util.Result
import org.carstenf.wordfinder.WordFinder
import org.carstenf.wordfinder.util.isNetworkAvailable
import org.carstenf.wordfinder.util.showHyperlinkDialog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import org.carstenf.wordfinder.R
import org.carstenf.wordfinder.Result
import org.carstenf.wordfinder.util.Result

open class ComputerResultListAdapter(context: Context) :
ArrayAdapter<Result>(context, R.layout.list_item, R.id.resultText) {
Expand Down
102 changes: 65 additions & 37 deletions app/src/main/kotlin/org/carstenf/wordfinder/gui/InfoDialogFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
package org.carstenf.wordfinder.gui

import android.app.Dialog
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
Expand All @@ -23,13 +22,17 @@ import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import org.carstenf.wordfinder.BuildConfig
import org.carstenf.wordfinder.GameState
import org.carstenf.wordfinder.R
import org.carstenf.wordfinder.gui.InfoDialogFragment.Companion.TAG
import java.io.InputStream
import java.util.Locale
import kotlin.math.min
import android.content.res.Configuration

class InfoDialogFragment : DialogFragment() {

Expand All @@ -44,20 +47,28 @@ class InfoDialogFragment : DialogFragment() {
rawText.replace("X.X", BuildConfig.VERSION_NAME)
} catch (e: Exception) {
Log.e(TAG, e.message,e )
"Error loading HTML content: ${e.message}"
getString(R.string.error_loading_html_content, e.message)
}
}
private var dialogView : View? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Obtain the GameState ViewModel scoped to the hosting Activity
// This ensures the same instance is used across configuration changes
// and is shared with the Activity.
gameState = ViewModelProvider(requireActivity())[GameState::class.java]
}

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(requireContext(), android.R.style.Theme_Black_NoTitleBar_Fullscreen)
val lDialogView = requireActivity().layoutInflater.inflate(org.carstenf.wordfinder.R.layout.dialog_info, null)
val lDialogView = requireActivity().layoutInflater.inflate(R.layout.dialog_info, null)
builder.setView(lDialogView)

val viewPager: ViewPager2 = lDialogView.findViewById(org.carstenf.wordfinder.R.id.view_pager)
val prevButton: Button = lDialogView.findViewById(org.carstenf.wordfinder.R.id.prev_button)
val nextButton: Button = lDialogView.findViewById(org.carstenf.wordfinder.R.id.next_button)
val closeButton: Button = lDialogView.findViewById(org.carstenf.wordfinder.R.id.close_button)
val viewPager: ViewPager2 = lDialogView.findViewById(R.id.view_pager)
val prevButton: Button = lDialogView.findViewById(R.id.prev_button)
val nextButton: Button = lDialogView.findViewById(R.id.next_button)
val closeButton: Button = lDialogView.findViewById(R.id.close_button)

dialogView = lDialogView
val locale = Locale.getDefault().language
Expand Down Expand Up @@ -107,10 +118,6 @@ class InfoDialogFragment : DialogFragment() {
override fun onPageSelected(position: Int) {
prevButton.isEnabled = position > 0
nextButton.isEnabled = position < pages.size - 1
// val scrollView = viewPager.findViewById<ScrollView>(R.id.info_scrollview)
// scrollView.post {
// scrollView.smoothScrollBy(0, 50) // Subtle nudge down
// }
}
})

Expand All @@ -120,39 +127,59 @@ class InfoDialogFragment : DialogFragment() {

override fun onDetach() {
super.onDetach()
gameState.onResume()
}

override fun onResume() {
super.onResume()
val height = (resources.displayMetrics.heightPixels * 0.8).toInt()
val lDialogView = dialogView
if(lDialogView != null) {
lDialogView.layoutParams.height = height
lDialogView.requestLayout()
lDialogView.invalidate()
lDialogView.forceLayout()
lDialogView.bringToFront()
gameState?.onResume()
if(gameState==null) {
Log.e(TAG, "gameState is null in InfoDialogFragment#onDetach") // NON-NLS
}
}


override fun onStart() {
super.onStart()
val height = (resources.displayMetrics.heightPixels * 0.8).toInt()
val lWindow = dialog?.window
if( lWindow !=null ){
lWindow.setLayout((resources.displayMetrics.widthPixels * 0.95).toInt(), height)
lWindow.setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND)
dialog?.window?.let { window ->
// It's best to get insets on the decorView
val decorView = window.decorView
androidx.core.view.ViewCompat.setOnApplyWindowInsetsListener(decorView) { v, insets ->
val systemBars = insets.getInsets(
androidx.core.view.WindowInsetsCompat.Type.systemBars() or
androidx.core.view.WindowInsetsCompat.Type.displayCutout()
)

val displayMetrics = resources.displayMetrics
val availableWidth = displayMetrics.widthPixels - systemBars.left - systemBars.right
val availableHeight = displayMetrics.heightPixels - systemBars.top - systemBars.bottom

val currentOrientation = resources.configuration.orientation
var dialogWidth = (availableWidth * 0.95).toInt()

if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
dialogWidth = (availableWidth * 0.90).toInt()
}
val dialogHeight = (availableHeight * 0.80).toInt()

window.setLayout(dialogWidth, dialogHeight)
window.setGravity(android.view.Gravity.CENTER)
window.setFlags(
WindowManager.LayoutParams.FLAG_DIM_BEHIND,
WindowManager.LayoutParams.FLAG_DIM_BEHIND
)

// If you only need to apply once, you can remove the listener
// androidx.core.view.ViewCompat.setOnApplyWindowInsetsListener(v, null)

insets // Return the insets
}
// Request insets to trigger the listener
androidx.core.view.ViewCompat.requestApplyInsets(decorView)
}
}
private lateinit var gameState: GameState
private var gameState: GameState? = null

companion object {
const val TAG = "WordFinder InfoDialog" // NON-NLS

fun showInfo(fragmentManager: FragmentManager, state: GameState) {
val dialogFragment = InfoDialogFragment()
dialogFragment.gameState = state
state.onPause()
dialogFragment.show(fragmentManager, TAG)
}
Expand All @@ -165,7 +192,7 @@ class InfoPagerAdapter(private val pages: List<PageData>) :
RecyclerView.Adapter<InfoPagerAdapter.PageViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PageViewHolder {
val view = LayoutInflater.from(parent.context).inflate(org.carstenf.wordfinder.R.layout.item_info_page, parent, false)
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_info_page, parent, false)
return PageViewHolder(view)
}

Expand All @@ -176,7 +203,7 @@ class InfoPagerAdapter(private val pages: List<PageData>) :
override fun getItemCount(): Int = pages.size

class PageViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val textView: TextView = view.findViewById(org.carstenf.wordfinder.R.id.info_text)
private val textView: TextView = view.findViewById(R.id.info_text)

fun bind(page: PageData) {
// Use the newer Html.fromHtml method with FROM_HTML_MODE_LEGACY
Expand Down Expand Up @@ -210,11 +237,12 @@ class DialogImageHandler(private val page: PageData, private val textView: TextV
val originalWidth = drawable.intrinsicWidth
val originalHeight = drawable.intrinsicHeight

val screenWidth = Resources.getSystem().displayMetrics.widthPixels // Get the width of the TextView
var desiredWidth = originalWidth * 4
val metrics = textView.resources.displayMetrics
val screenWidth = metrics.widthPixels // Get the width of the TextView
val density = metrics.density
val maxWidth = (500 * density).toInt() // Convert dp to px. We want the dialog to be at least 300dp

if(desiredWidth> screenWidth*0.8)
desiredWidth = (screenWidth*0.8).toInt()
val desiredWidth = min ((screenWidth*0.8).toInt(), maxWidth)

// Calculate the height to maintain the aspect ratio
val desiredHeight = originalHeight * ( desiredWidth*1.0 / originalWidth)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
package org.carstenf.wordfinder.dictionary

import org.carstenf.wordfinder.LANGUAGE
package org.carstenf.wordfinder.letters

//fun pickRandomLetter2DDistribution(letterCounts: IntArray, languageCode: LANGUAGE) : Char {
// return pickRandomLetter2DDistributionF(letterCounts, languageCode) { it }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
package org.carstenf.wordfinder.dictionary

import org.carstenf.wordfinder.LANGUAGE
package org.carstenf.wordfinder.letters

fun pickRandomLetterDice(fieldNumber: Int, countryCode: LANGUAGE): Char {
val r = Math.random()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
package org.carstenf.wordfinder.dictionary

import org.carstenf.wordfinder.LANGUAGE
package org.carstenf.wordfinder.letters

fun pickRandomLetterDictionary(countryCode: LANGUAGE): Char {
val r = Math.random()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.carstenf.wordfinder
package org.carstenf.wordfinder.letters

import org.carstenf.wordfinder.dictionary.pickRandomLetter2DDistributionF
import org.carstenf.wordfinder.dictionary.pickRandomLetterDice
import org.carstenf.wordfinder.dictionary.pickRandomLetterDictionary
import org.carstenf.wordfinder.GameState
import kotlin.math.pow


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* License: GNU GENERAL PUBLIC LICENSE 3.0 (https://www.gnu.org/copyleft/gpl.html)
*
*/
package org.carstenf.wordfinder
package org.carstenf.wordfinder.util

import org.carstenf.wordfinder.dictionary.Dictionary

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
* License: GNU GENERAL PUBLIC LICENSE 3.0 (https://www.gnu.org/copyleft/gpl.html)
*
*/
package org.carstenf.wordfinder
package org.carstenf.wordfinder.util

import android.util.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import org.carstenf.wordfinder.GameState
import org.carstenf.wordfinder.WordFinder
import org.carstenf.wordfinder.dictionary.Dictionary

class SolveTask(private val gameState: GameState) {
Expand Down Expand Up @@ -54,7 +56,7 @@ class SolveTask(private val gameState: GameState) {
prefixes.add(""+prefix[0]+prefix[1]+'U')
}
} else {
for (next in WordFinder.MOVES[move]) {
for (next in WordFinder.Companion.MOVES[move]) {
if (!taken[next]) {
findAnyWord(next, taken, depth - 1, res + gameState.getBoard(move), prefixes)
}
Expand All @@ -69,7 +71,7 @@ class SolveTask(private val gameState: GameState) {
for (result in resultList) {
val minLength = if (gameState.isAllow3LetterWords) 3 else 4
if (result.text.length >= minLength && gameState.findWord(result.text)) {
Log.d(WordFinder.TAG, "Found: $result") // NON-NLS
Log.d(WordFinder.Companion.TAG, "Found: $result") // NON-NLS
publishProgress(result)
}
}
Expand Down
6 changes: 0 additions & 6 deletions app/src/main/res/layout/dialog_info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:translationZ="8dp"
android:background="@drawable/listview_border"
android:padding="8dp">

Expand All @@ -14,14 +13,12 @@
android:layout_height="0dp"
android:layout_weight="1"
android:background="@drawable/listview_border"
android:translationZ="8dp"
/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:translationZ="8dp"
android:gravity="center">

<androidx.appcompat.widget.AppCompatButton
Expand All @@ -32,7 +29,6 @@
android:enabled="false"
android:minWidth="48dp"
android:minHeight="48dp"
android:translationZ="8dp"
android:background="@drawable/listview_border"
tools:ignore="HardcodedText" />

Expand All @@ -43,7 +39,6 @@
android:text="&gt;&gt;"
android:minWidth="48dp"
android:minHeight="48dp"
android:translationZ="8dp"
android:background="@drawable/listview_border"
tools:ignore="HardcodedText" />

Expand All @@ -59,7 +54,6 @@
android:minWidth="48dp"
android:minHeight="48dp"
android:text="X"
android:translationZ="8dp"
android:background="@drawable/listview_border"
tools:ignore="HardcodedText" />
</LinearLayout>
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Word Finder</string>
<string name="info">Info</string>
<string name="info">Hilfe</string>
<string name="prefs">Einstellungen</string>
<string name="set_preferences">Einstellungen</string>
<string name="shuffle">Würfeln</string>
Expand Down Expand Up @@ -56,4 +56,5 @@
<string name="letter_button">Disabled Letter Button %1$s</string>
<string name="current_guess">Derzeitiges wort ist %1$s</string>
<string name="current_guess_empty">Derzeitiges Wort ist leer</string>
<string name="error_loading_html_content">Bild konnte nicht geladen werden: %1$s</string>
</resources>
Loading