Initial commit

This commit is contained in:
2025-08-28 22:38:53 +02:00
commit f15208fe6d
232 changed files with 16821 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ch.gtache.fro.gui</groupId>
<artifactId>gui</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gui-api</artifactId>
<dependencies>
<dependency>
<groupId>ch.gtache.fro</groupId>
<artifactId>fro-api</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,14 @@
package ch.gtache.fro.gui;
/**
* Represents a GUI controller
*/
public interface Controller {
/**
* Returns the model for this controller
*
* @return The model
*/
Model model();
}
@@ -0,0 +1,21 @@
package ch.gtache.fro.gui;
/**
* Controller for the fetch view
*/
public interface FetchController extends Controller {
/**
* Fetches the data for the currently selected bird
*
*/
void fetch();
/**
* Fetches all the data
*/
void fetchAll();
@Override
FetchModel model();
}
@@ -0,0 +1,7 @@
package ch.gtache.fro.gui;
/**
* Model for the fetch view
*/
public interface FetchModel extends Model {
}
@@ -0,0 +1,10 @@
package ch.gtache.fro.gui;
/**
* Controller for the main view
*/
public interface MainController extends Controller {
@Override
MainModel model();
}
@@ -0,0 +1,7 @@
package ch.gtache.fro.gui;
/**
* Model for the main view
*/
public interface MainModel extends Model {
}
@@ -0,0 +1,7 @@
package ch.gtache.fro.gui;
/**
* Represents a GUI model
*/
public interface Model {
}
@@ -0,0 +1,10 @@
package ch.gtache.fro.gui;
/**
* Controller for the settings view
*/
public interface SettingsController extends Controller {
@Override
SettingsModel model();
}
@@ -0,0 +1,7 @@
package ch.gtache.fro.gui;
/**
* Model for the settings view
*/
public interface SettingsModel extends Model {
}
@@ -0,0 +1,12 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.gui.Controller;
/**
* Controller for the practice view
*/
public interface PracticeController extends Controller {
@Override
PracticeModel model();
}
@@ -0,0 +1,23 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.gui.Model;
/**
* Model for the practice view - exact guess
*/
public interface PracticeExactModel extends Model {
/**
* Returns the user's current guess
*
* @return The user's current guess
*/
String guess();
/**
* Sets the guess
*
* @param guess The guess
*/
void guess(String guess);
}
@@ -0,0 +1,14 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.gui.Controller;
/**
* Controller for a guess practice view
*/
public interface PracticeGuessController extends Controller {
/**
* Confirms the current guess
*/
void confirm();
}
@@ -0,0 +1,11 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.gui.Model;
/**
* Model for the practice view
*/
public interface PracticeModel extends Model {
}
@@ -0,0 +1,33 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.Bird;
import ch.gtache.fro.gui.Model;
import java.util.List;
/**
* Model for the practice view - multichoice guess
*/
public interface PracticeMultichoiceModel extends Model {
/**
* Returns the suggestions
*
* @return The suggestions
*/
List<Bird> suggestions();
/**
* Returns the selected suggestion
*
* @return The selected bird
*/
Bird selected();
/**
* Sets the selected suggestion
*
* @param selected The selected bird
*/
void selected(Bird selected);
}
@@ -0,0 +1,11 @@
package ch.gtache.fro.practice.gui;
/**
* Controller for the practice view - exact picture
*/
public interface PracticePictureExactController extends PracticeGuessController {
@Override
PracticePictureExactModel model();
}
@@ -0,0 +1,8 @@
package ch.gtache.fro.practice.gui;
/**
* Model for the practice view - exact picture
*/
public interface PracticePictureExactModel extends PracticePictureModel, PracticeExactModel {
}
@@ -0,0 +1,24 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.Picture;
import ch.gtache.fro.gui.Model;
/**
* Represents a model for a practice view with a picture
*/
public interface PracticePictureModel extends Model {
/**
* Returns the picture to guess
*
* @return The picture
*/
Picture picture();
/**
* Sets the picture
*
* @param picture The picture
*/
void picture(Picture picture);
}
@@ -0,0 +1,11 @@
package ch.gtache.fro.practice.gui;
/**
* Controller for the practice view - multichoice picture
*/
public interface PracticePictureMultichoiceController extends PracticeGuessController {
@Override
PracticePictureMultichoiceModel model();
}
@@ -0,0 +1,8 @@
package ch.gtache.fro.practice.gui;
/**
* Model for the practice view - multichoice picture
*/
public interface PracticePictureMultichoiceModel extends PracticePictureModel, PracticeMultichoiceModel {
}
@@ -0,0 +1,12 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.gui.Controller;
/**
* Controller for the practice result view
*/
public interface PracticeResultController extends Controller {
@Override
PracticeResultModel model();
}
@@ -0,0 +1,9 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.gui.Model;
/**
* Model for the practice result view
*/
public interface PracticeResultModel extends Model {
}
@@ -0,0 +1,17 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.gui.Controller;
/**
* Controller for the practice settings view
*/
public interface PracticeSettingsController extends Controller {
/**
* Starts a practice
*/
void startPractice();
@Override
PracticeSettingsModel model();
}
@@ -0,0 +1,54 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.gui.Model;
import ch.gtache.fro.practice.PracticeType;
import java.util.List;
/**
* Model for the practice settings view
*/
public interface PracticeSettingsModel extends Model {
/**
* Returns the list of practice types
*
* @return The list of practice types
*/
List<PracticeType> practiceTypes();
/**
* Returns the currently selected practice type
*
* @return The practice type
*/
PracticeType practiceType();
/**
* Sets the practice type
*
* @param practiceType The practice type
*/
void practiceType(PracticeType practiceType);
/**
* Returns true if the practice type has suggestions
*
* @return True if the practice type has suggestions
*/
boolean hasSuggestions();
/**
* Returns the currently selected number of suggestions
*
* @return The number of suggestions
*/
int suggestionsNumber();
/**
* Sets the number of suggestions
*
* @param suggestionsNumber The number of suggestions
*/
void suggestionsNumber(int suggestionsNumber);
}
@@ -0,0 +1,11 @@
package ch.gtache.fro.practice.gui;
/**
* Controller for the practice view - exact sound
*/
public interface PracticeSoundExactController extends PracticeGuessController {
@Override
PracticeSoundExactModel model();
}
@@ -0,0 +1,8 @@
package ch.gtache.fro.practice.gui;
/**
* Model for the practice view - exact sound
*/
public interface PracticeSoundExactModel extends PracticeSoundModel, PracticeExactModel {
}
@@ -0,0 +1,24 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.Sound;
import ch.gtache.fro.gui.Model;
/**
* Represents a model for a practice view with a sound
*/
public interface PracticeSoundModel extends Model {
/**
* Returns the sound to guess
*
* @return The sound
*/
Sound sound();
/**
* Sets the sound
*
* @param sound The sound
*/
void sound(Sound sound);
}
@@ -0,0 +1,11 @@
package ch.gtache.fro.practice.gui;
/**
* Controller for the practice view - multichoice sound
*/
public interface PracticeSoundMultichoiceController extends PracticeGuessController {
@Override
PracticeSoundMultichoiceModel model();
}
@@ -0,0 +1,8 @@
package ch.gtache.fro.practice.gui;
/**
* Model for the practice view - multichoice sound
*/
public interface PracticeSoundMultichoiceModel extends PracticeSoundModel, PracticeMultichoiceModel {
}
@@ -0,0 +1,10 @@
package ch.gtache.fro.practice.gui;
/**
* Controller for the practice view - multipicture choice sound
*/
public interface PracticeSoundMultichoicePictureController extends PracticeGuessController {
@Override
PracticeSoundMultichoicePictureModel model();
}
@@ -0,0 +1,32 @@
package ch.gtache.fro.practice.gui;
import ch.gtache.fro.Picture;
import java.util.List;
/**
* Model for the practice view - multipicture choice sound
*/
public interface PracticeSoundMultichoicePictureModel extends PracticeSoundModel {
/**
* Returns the suggestions
*
* @return The suggestions
*/
List<Picture> suggestions();
/**
* Returns the selected suggestion
*
* @return The selected picture
*/
Picture selected();
/**
* Sets the selected suggestion
*
* @param selected The selected picture
*/
void selected(Picture selected);
}
+9
View File
@@ -0,0 +1,9 @@
/**
* GUI API module for the FRO project
*/
module ch.gtache.fro.gui.api {
requires transitive ch.gtache.fro.api;
exports ch.gtache.fro.gui;
exports ch.gtache.fro.practice.gui;
}
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ch.gtache.fro.gui</groupId>
<artifactId>gui</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gui-core</artifactId>
<dependencies>
<dependency>
<groupId>ch.gtache.fro.gui</groupId>
<artifactId>gui-api</artifactId>
</dependency>
<dependency>
<groupId>ch.gtache.fro</groupId>
<artifactId>fro-core</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,41 @@
package ch.gtache.fro.gui.impl;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Combination of multiple resource bundles
*/
@Singleton
public class CombinedResourceBundle extends ResourceBundle {
private final Map<String, String> entries;
@Inject
CombinedResourceBundle(final Set<ResourceBundle> resourceBundles) {
this.entries = resourceBundles.stream()
.flatMap(r -> r.keySet().stream().map(k -> new KeyValue(k, r.getString(k))))
.collect(Collectors.toUnmodifiableMap(KeyValue::key, KeyValue::value));
}
@Override
protected Object handleGetObject(final String key) {
return entries.get(key);
}
@Override
public Enumeration<String> getKeys() {
return Collections.enumeration(entries.keySet());
}
private record KeyValue(String key, String value) {
}
}
@@ -0,0 +1,34 @@
package ch.gtache.fro.modules.gui.impl;
import ch.gtache.fro.modules.practice.gui.impl.GuiPracticeCoreModule;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoSet;
import java.util.ResourceBundle;
@Module(includes = GuiPracticeCoreModule.class)
public abstract class GuiCoreModule {
private GuiCoreModule() {
}
@Provides
@IntoSet
static ResourceBundle providesFetchBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.gui.impl.FetchBundle");
}
@Provides
@IntoSet
static ResourceBundle providesMainBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.gui.impl.MainBundle");
}
@Provides
@IntoSet
static ResourceBundle providesSettingsBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.gui.impl.SettingsBundle");
}
}
@@ -0,0 +1,63 @@
package ch.gtache.fro.modules.practice.gui.impl;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoSet;
import java.util.ResourceBundle;
@Module
public abstract class GuiPracticeCoreModule {
private GuiPracticeCoreModule() {
}
@Provides
@IntoSet
static ResourceBundle providesPracticeBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.practice.gui.impl.PracticeBundle");
}
@Provides
@IntoSet
static ResourceBundle providesPracticePictureExactBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.practice.gui.impl.PracticePictureExactBundle");
}
@Provides
@IntoSet
static ResourceBundle providesPracticePictureMultichoiceBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.practice.gui.impl.PracticePictureMultichoiceBundle");
}
@Provides
@IntoSet
static ResourceBundle providesPracticeResultBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.practice.gui.impl.PracticeResultBundle");
}
@Provides
@IntoSet
static ResourceBundle providesPracticeSettingsBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.practice.gui.impl.PracticeSettingsBundle");
}
@Provides
@IntoSet
static ResourceBundle providesPracticeSoundExactBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.practice.gui.impl.PracticeSoundExactBundle");
}
@Provides
@IntoSet
static ResourceBundle providesPracticeSoundMultichoiceBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.practice.gui.impl.PracticeSoundMultichoiceBundle");
}
@Provides
@IntoSet
static ResourceBundle providesPracticeSoundMultichoicePictureBundle() {
return ResourceBundle.getBundle("ch.gtache.fro.practice.gui.impl.PracticeSoundMultichoicePictureBundle");
}
}
+13
View File
@@ -0,0 +1,13 @@
/**
* GUI core module for the FRO project
*/
module ch.gtache.fro.gui.core {
requires transitive ch.gtache.fro.gui.api;
requires ch.gtache.fro.core;
requires jakarta.inject;
requires dagger;
exports ch.gtache.fro.gui.impl;
exports ch.gtache.fro.modules.gui.impl;
exports ch.gtache.fro.modules.practice.gui.impl;
}
@@ -0,0 +1,3 @@
fetch.button.all.label=Fetch all
fetch.button.fetch.label=Fetch
fetch.providers.label=Providers
@@ -0,0 +1,3 @@
fetch.button.all.label=Fetch all
fetch.button.fetch.label=Fetch
fetch.providers.label=Providers
@@ -0,0 +1,3 @@
fetch.button.all.label=Télécharger tous
fetch.button.fetch.label=Télécharger
fetch.providers.label=Sources
@@ -0,0 +1,3 @@
main.tab.fetch.label=Fetch
main.tab.practice.label=Practice
main.tab.settings.label=Settings
@@ -0,0 +1,3 @@
main.tab.fetch.label=Fetch
main.tab.practice.label=Practice
main.tab.settings.label=Settings
@@ -0,0 +1,3 @@
main.tab.fetch.label=Téléchargement
main.tab.practice.label=Entraînement
main.tab.settings.label=Paramètres
@@ -0,0 +1,5 @@
settings.table.column.bird=Bird
settings.table.column.enabled=Enabled
settings.table.column.fetchers=Fetchers
settings.table.column.pictures=Pictures
settings.table.column.sounds=Sounds
@@ -0,0 +1,5 @@
settings.table.column.bird=Bird
settings.table.column.enabled=Enabled
settings.table.column.fetchers=Fetchers
settings.table.column.pictures=Pictures
settings.table.column.sounds=Sounds
@@ -0,0 +1,5 @@
settings.table.column.bird=Oiseau
settings.table.column.enabled=Activé
settings.table.column.fetchers=Fournisseurs
settings.table.column.pictures=Images
settings.table.column.sounds=Sons
@@ -0,0 +1 @@
practice.picture.exact.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.picture.exact.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.picture.exact.validate.button.label=Confirmer
@@ -0,0 +1 @@
practice.picture.multichoice.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.picture.multichoice.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.picture.multichoice.validate.button.label=Confirmer
@@ -0,0 +1,3 @@
practice.result.failure.label=Failed guesses
practice.result.label=Practice result
practice.result.success.label=Correct guesses
@@ -0,0 +1,3 @@
practice.result.failure.label=Failed guesses
practice.result.label=Practice result
practice.result.success.label=Correct guesses
@@ -0,0 +1,3 @@
practice.result.failure.label=Choix incorrects
practice.result.label=Résultat
practice.result.success.label=Choix corrects
@@ -0,0 +1,3 @@
practice.settings.start.button.label=Start
practice.settings.suggestions.number.label=Number of suggestions
practice.settings.type.label=Practice type
@@ -0,0 +1,3 @@
practice.settings.start.button.label=Start
practice.settings.suggestions.number.label=Number of suggestions
practice.settings.type.label=Practice type
@@ -0,0 +1,3 @@
practice.settings.start.button.label=Démarrer
practice.settings.suggestions.number.label=Nombre de suggestions
practice.settings.type.label=Type d'entraînement
@@ -0,0 +1 @@
practice.sound.exact.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.sound.exact.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.sound.exact.validate.button.label=Confirmer
@@ -0,0 +1 @@
practice.sound.multichoice.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.sound.multichoice.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.sound.multichoice.validate.button.label=Confirmer
@@ -0,0 +1 @@
practice.sound.multichoice.picture.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.sound.multichoice.picture.validate.button.label=Confirm
@@ -0,0 +1 @@
practice.sound.multichoice.picture.validate.button.label=Confirmer
+50
View File
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ch.gtache.fro.gui</groupId>
<artifactId>gui</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gui-fx</artifactId>
<properties>
<javafx.version>24.0.2</javafx.version>
<controlsfx.version>11.2.2</controlsfx.version>
</properties>
<dependencies>
<dependency>
<groupId>ch.gtache.fro.gui</groupId>
<artifactId>gui-core</artifactId>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>${controlsfx.version}</version>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,61 @@
package ch.gtache.fro.gui.fx;
import ch.gtache.fro.Bird;
import ch.gtache.fro.Fetcher;
import ch.gtache.fro.gui.FetchController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import org.controlsfx.control.CheckComboBox;
import org.controlsfx.control.PrefixSelectionComboBox;
import java.util.Objects;
/**
* FX implementation of {@link FetchController}
*/
@Singleton
public final class FXFetchController implements FetchController {
private final FXFetchModel model;
@FXML
private PrefixSelectionComboBox<Bird> birdCombobox;
@FXML
private Button fetchButton;
@FXML
private Button fetchAllButton;
@FXML
private CheckComboBox<Fetcher> providersCombobox;
@Inject
FXFetchController(final FXFetchModel model) {
this.model = Objects.requireNonNull(model);
}
@Override
public void fetch() {
throw new UnsupportedOperationException();
}
@Override
public void fetchAll() {
throw new UnsupportedOperationException();
}
@Override
public FXFetchModel model() {
return model;
}
@FXML
private void fetchBirdPressed() {
fetch();
}
@FXML
private void fetchAllPressed() {
fetchAll();
}
}
@@ -0,0 +1,17 @@
package ch.gtache.fro.gui.fx;
import ch.gtache.fro.gui.FetchModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
/**
* FX implementation of {@link FetchModel}
*/
@Singleton
public final class FXFetchModel implements FetchModel {
@Inject
FXFetchModel() {
}
}
@@ -0,0 +1,35 @@
package ch.gtache.fro.gui.fx;
import ch.gtache.fro.gui.MainController;
import ch.gtache.fro.practice.gui.fx.FXPracticeController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import java.util.Objects;
/**
* FX implementation of {@link MainController}
*/
@Singleton
public final class FXMainController implements MainController {
@FXML
private FXFetchController fetchController;
@FXML
private FXSettingsController settingsController;
@FXML
private FXPracticeController practiceController;
private final FXMainModel model;
@Inject
FXMainController(final FXMainModel model) {
this.model = Objects.requireNonNull(model);
}
@Override
public FXMainModel model() {
return model;
}
}
@@ -0,0 +1,17 @@
package ch.gtache.fro.gui.fx;
import ch.gtache.fro.gui.MainModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
/**
* FX implementation of {@link MainModel}
*/
@Singleton
public final class FXMainModel implements MainModel {
@Inject
FXMainModel() {
}
}
@@ -0,0 +1,32 @@
package ch.gtache.fro.gui.fx;
import ch.gtache.fro.Bird;
import ch.gtache.fro.gui.SettingsController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.control.TableView;
import java.util.Objects;
/**
* FX implementation of {@link SettingsController}
*/
@Singleton
public final class FXSettingsController implements SettingsController {
private final FXSettingsModel model;
@FXML
private TableView<Bird> table;
@Inject
FXSettingsController(final FXSettingsModel model) {
this.model = Objects.requireNonNull(model);
}
@Override
public FXSettingsModel model() {
return model;
}
}
@@ -0,0 +1,16 @@
package ch.gtache.fro.gui.fx;
import ch.gtache.fro.gui.SettingsModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
/**
* FX implementation of {@link SettingsModel}
*/
@Singleton
public final class FXSettingsModel implements SettingsModel {
@Inject
FXSettingsModel() {
}
}
@@ -0,0 +1,104 @@
package ch.gtache.fro.modules.gui.fx;
import ch.gtache.fro.gui.FetchController;
import ch.gtache.fro.gui.FetchModel;
import ch.gtache.fro.gui.MainController;
import ch.gtache.fro.gui.MainModel;
import ch.gtache.fro.gui.SettingsController;
import ch.gtache.fro.gui.SettingsModel;
import ch.gtache.fro.gui.fx.FXFetchController;
import ch.gtache.fro.gui.fx.FXFetchModel;
import ch.gtache.fro.gui.fx.FXMainController;
import ch.gtache.fro.gui.fx.FXMainModel;
import ch.gtache.fro.gui.fx.FXSettingsController;
import ch.gtache.fro.gui.fx.FXSettingsModel;
import ch.gtache.fro.gui.impl.CombinedResourceBundle;
import ch.gtache.fro.modules.practice.gui.fx.FXPracticeModule;
import ch.gtache.fro.practice.gui.fx.FXPracticeController;
import ch.gtache.fro.practice.gui.fx.FXPracticePictureExactController;
import ch.gtache.fro.practice.gui.fx.FXPracticePictureMultichoiceController;
import ch.gtache.fro.practice.gui.fx.FXPracticeResultController;
import ch.gtache.fro.practice.gui.fx.FXPracticeSettingsController;
import ch.gtache.fro.practice.gui.fx.FXPracticeSoundExactController;
import ch.gtache.fro.practice.gui.fx.FXPracticeSoundMultichoiceController;
import ch.gtache.fro.practice.gui.fx.FXPracticeSoundMultichoicePictureController;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import jakarta.inject.Singleton;
import javafx.fxml.FXMLLoader;
/**
* Dagger module for the FX GUI package
*/
@Module(includes = FXPracticeModule.class)
public abstract class FXModule {
private FXModule() {
//Empty constructor
}
@Provides
@Singleton
static FXMLLoader providesFXMLLoader(final FXFetchController fetchController,
final FXMainController mainController,
final FXSettingsController settingsController,
final FXPracticeController practiceController,
final FXPracticeResultController practiceResultController,
final FXPracticeSettingsController practiceSettingsController,
final FXPracticePictureExactController practicePictureExactController,
final FXPracticePictureMultichoiceController practicePictureMultichoiceController,
final FXPracticeSoundExactController practiceSoundExactController,
final FXPracticeSoundMultichoiceController practiceSoundMultichoiceController,
final FXPracticeSoundMultichoicePictureController practiceSoundMultichoicePictureController,
final CombinedResourceBundle combinedResourceBundle) {
final var loader = new FXMLLoader(FXModule.class.getResource("/ch/gtache/fro/gui/fx/mainView.fxml"));
loader.setResources(combinedResourceBundle);
loader.setControllerFactory(c -> {
if (c == FXFetchController.class) {
return fetchController;
} else if (c == FXMainController.class) {
return mainController;
} else if (c == FXSettingsController.class) {
return settingsController;
} else if (c == FXPracticeController.class) {
return practiceController;
} else if (c == FXPracticeResultController.class) {
return practiceResultController;
} else if (c == FXPracticeSettingsController.class) {
return practiceSettingsController;
} else if (c == FXPracticePictureExactController.class) {
return practicePictureExactController;
} else if (c == FXPracticePictureMultichoiceController.class) {
return practicePictureMultichoiceController;
} else if (c == FXPracticeSoundExactController.class) {
return practiceSoundExactController;
} else if (c == FXPracticeSoundMultichoiceController.class) {
return practiceSoundMultichoiceController;
} else if (c == FXPracticeSoundMultichoicePictureController.class) {
return practiceSoundMultichoicePictureController;
} else {
throw new IllegalArgumentException("Unknown controller class " + c);
}
});
return loader;
}
@Binds
abstract FetchController bindsFetchController(final FXFetchController fetchController);
@Binds
abstract FetchModel bindsFetchModel(final FXFetchModel fetchModel);
@Binds
abstract MainController bindsMainController(final FXMainController mainController);
@Binds
abstract MainModel bindsMainModel(final FXMainModel mainModel);
@Binds
abstract SettingsController bindsSettingsController(final FXSettingsController settingsController);
@Binds
abstract SettingsModel bindsSettingsModel(final FXSettingsModel settingsModel);
}
@@ -0,0 +1,59 @@
package ch.gtache.fro.modules.practice.gui.fx;
import ch.gtache.fro.practice.gui.*;
import ch.gtache.fro.practice.gui.fx.*;
import dagger.Binds;
import dagger.Module;
/**
* Dagger module for the FX practice package
*/
@Module
public abstract class FXPracticeModule {
private FXPracticeModule() {
//Empty constructor
}
@Binds
abstract PracticeController bindsPracticeController(final FXPracticeController practiceController);
@Binds
abstract PracticeModel bindsPracticeModel(final FXPracticeModel practiceModel);
@Binds
abstract PracticeSettingsController bindsPracticeSettingsController(final FXPracticeSettingsController practiceSettingsController);
@Binds
abstract PracticeSettingsModel bindsPracticeSettingsModel(final FXPracticeSettingsModel practiceSettingsModel);
@Binds
abstract PracticePictureExactController bindsPracticePictureExactController(final FXPracticePictureExactController practicePictureExactController);
@Binds
abstract PracticePictureExactModel bindsPracticePictureExactModel(final FXPracticePictureExactModel practicePictureExactModel);
@Binds
abstract PracticePictureMultichoiceController bindsPracticePictureMultichoiceController(final FXPracticePictureMultichoiceController practicePictureMultichoiceController);
@Binds
abstract PracticePictureMultichoiceModel bindsPracticePictureMultichoiceModel(final FXPracticePictureMultichoiceModel practicePictureMultichoiceModel);
@Binds
abstract PracticeSoundExactController bindsPracticeSoundExactController(final FXPracticeSoundExactController practiceSoundExactController);
@Binds
abstract PracticeSoundExactModel bindsPracticeSoundExactModel(final FXPracticeSoundExactModel practiceSoundExactModel);
@Binds
abstract PracticeSoundMultichoiceController bindsPracticeSoundMultichoiceController(final FXPracticeSoundMultichoiceController practiceSoundMultichoiceController);
@Binds
abstract PracticeSoundMultichoiceModel bindsPracticeSoundMultichoiceModel(final FXPracticeSoundMultichoiceModel practiceSoundMultichoiceModel);
@Binds
abstract PracticeSoundMultichoicePictureController bindsPracticeSoundMultichoicePictureController(final FXPracticeSoundMultichoicePictureController practiceSoundMultichoicePictureController);
@Binds
abstract PracticeSoundMultichoicePictureModel bindsPracticeSoundMultichoicePictureModel(final FXPracticeSoundMultichoicePictureModel practiceSoundMultichoicePictureModel);
}
@@ -0,0 +1,56 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.practice.gui.PracticeController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.layout.Pane;
import java.util.Objects;
/**
* FX implementation of {@link PracticeController}
*/
@Singleton
public final class FXPracticeController implements PracticeController {
@FXML
private Pane practiceSettings;
@FXML
private Pane practiceResult;
@FXML
private Pane practicePictureExact;
@FXML
private Pane practicePictureMultichoice;
@FXML
private Pane practiceSoundExact;
@FXML
private Pane practiceSoundMultichoice;
@FXML
private Pane practiceSoundMultichoicePicture;
private final FXPracticeModel model;
@Inject
FXPracticeController(final FXPracticeModel model) {
this.model = Objects.requireNonNull(model);
}
@FXML
private void initialize() {
model.panes().addAll(practiceSettings, practiceResult, practicePictureExact, practicePictureMultichoice,
practiceSoundExact, practiceSoundMultichoice, practiceSoundMultichoicePicture);
model.selectedPaneProperty().addListener((_, _, newValue) -> {
for (final var pane : model.panes()) {
pane.setManaged(pane == newValue);
pane.setVisible(pane == newValue);
}
});
model.setSelectedPane(practiceSettings);
}
@Override
public FXPracticeModel model() {
return model;
}
}
@@ -0,0 +1,42 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.practice.gui.PracticeModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.layout.Pane;
/**
* FX implementation of {@link PracticeModel}
*/
@Singleton
public final class FXPracticeModel implements PracticeModel {
private final ObservableList<Pane> panes;
private final ObjectProperty<Pane> selectedPane;
@Inject
FXPracticeModel() {
this.panes = FXCollections.observableArrayList();
this.selectedPane = new SimpleObjectProperty<>();
}
ObservableList<Pane> panes() {
return panes;
}
Pane selectedPane() {
return selectedPane.get();
}
void setSelectedPane(final Pane pane) {
selectedPane.set(pane);
}
ObjectProperty<Pane> selectedPaneProperty() {
return selectedPane;
}
}
@@ -0,0 +1,56 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.PictureType;
import ch.gtache.fro.practice.gui.PracticePictureExactController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import org.controlsfx.control.PrefixSelectionComboBox;
import org.controlsfx.control.textfield.CustomTextField;
import java.util.Objects;
/**
* FX implementation of {@link PracticePictureExactController}
*/
@Singleton
public final class FXPracticePictureExactController implements PracticePictureExactController {
private final FXPracticePictureExactModel model;
@FXML
private ImageView pictureView;
@FXML
private CustomTextField nameField;
@FXML
private PrefixSelectionComboBox<PictureType> typeCombobox;
@FXML
private Button validateButton;
@Inject
FXPracticePictureExactController(final FXPracticePictureExactModel model) {
this.model = Objects.requireNonNull(model);
}
@Override
public void confirm() {
throw new UnsupportedOperationException();
}
@Override
public FXPracticePictureExactModel model() {
return model;
}
@FXML
private void enterPressed() {
confirm();
}
@FXML
private void validatePressed() {
confirm();
}
}
@@ -0,0 +1,65 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.Picture;
import ch.gtache.fro.practice.gui.PracticePictureExactModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* FX implementation of {@link PracticePictureExactModel}
*/
@Singleton
public final class FXPracticePictureExactModel implements PracticePictureExactModel {
private final StringProperty guess;
private final ObjectProperty<Picture> picture;
@Inject
FXPracticePictureExactModel() {
this.guess = new SimpleStringProperty();
this.picture = new SimpleObjectProperty<>();
}
@Override
public String guess() {
return guess.get();
}
@Override
public void guess(final String guess) {
this.guess.set(guess);
}
/**
* Returns the property for the user guess
*
* @return the property for the user guess
*/
StringProperty guessProperty() {
return guess;
}
@Override
public Picture picture() {
return picture.get();
}
@Override
public void picture(final Picture picture) {
this.picture.set(picture);
}
/**
* Returns the property for the picture
*
* @return the property for the picture
*/
ObjectProperty<Picture> pictureProperty() {
return picture;
}
}
@@ -0,0 +1,45 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.practice.gui.PracticePictureMultichoiceController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import java.util.Objects;
/**
* FX implementation of {@link PracticePictureMultichoiceController}
*/
@Singleton
public final class FXPracticePictureMultichoiceController implements PracticePictureMultichoiceController {
private final FXPracticePictureMultichoiceModel model;
@FXML
private GridPane grid;
@FXML
private Button validateButton;
@Inject
FXPracticePictureMultichoiceController(final FXPracticePictureMultichoiceModel model) {
this.model = Objects.requireNonNull(model);
}
@Override
public FXPracticePictureMultichoiceModel model() {
return model;
}
@Override
public void confirm() {
throw new UnsupportedOperationException();
}
@FXML
private void validatePressed() {
confirm();
}
}
@@ -0,0 +1,73 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.Bird;
import ch.gtache.fro.Picture;
import ch.gtache.fro.practice.gui.PracticePictureMultichoiceModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
/**
* FX implementation of {@link PracticePictureMultichoiceModel}
*/
@Singleton
public final class FXPracticePictureMultichoiceModel implements PracticePictureMultichoiceModel {
private final ObjectProperty<Picture> picture;
private final ObservableList<Bird> suggestions;
private final ObjectProperty<Bird> selected;
@Inject
FXPracticePictureMultichoiceModel() {
this.picture = new SimpleObjectProperty<>();
this.suggestions = FXCollections.observableArrayList();
this.selected = new SimpleObjectProperty<>();
}
@Override
public ObservableList<Bird> suggestions() {
return suggestions;
}
@Override
public Bird selected() {
return selected.get();
}
@Override
public void selected(final Bird selected) {
this.selected.set(selected);
}
/**
* Returns the property for the selected bird
*
* @return the property for the selected bird
*/
ObjectProperty<Bird> selectedProperty() {
return selected;
}
@Override
public Picture picture() {
return picture.get();
}
@Override
public void picture(final Picture picture) {
this.picture.set(picture);
}
/**
* Returns the property for the picture
*
* @return the property for the picture
*/
ObjectProperty<Picture> pictureProperty() {
return picture;
}
}
@@ -0,0 +1,36 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.practice.gui.PracticeResultController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import java.util.Objects;
/**
* FX implementation of {@link PracticeResultController}
*/
@Singleton
public final class FXPracticeResultController implements PracticeResultController {
private final FXPracticeResultModel model;
@FXML
private Label successNumberLabel;
@FXML
private Label failureNumberLabel;
@FXML
private Label successListLabel;
@FXML
private Label failureListLabel;
@Inject
FXPracticeResultController(final FXPracticeResultModel model) {
this.model = Objects.requireNonNull(model);
}
@Override
public FXPracticeResultModel model() {
return model;
}
}
@@ -0,0 +1,18 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.practice.gui.PracticeResultModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
/**
* FX implementation of {@link PracticeResultModel}
*/
@Singleton
public final class FXPracticeResultModel implements PracticeResultModel {
@Inject
FXPracticeResultModel() {
}
}
@@ -0,0 +1,61 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.practice.PracticeType;
import ch.gtache.fro.practice.gui.PracticeSettingsController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import org.controlsfx.control.PrefixSelectionComboBox;
import static java.util.Objects.requireNonNull;
/**
* FX implementation of {@link PracticeSettingsController}
*/
@Singleton
public final class FXPracticeSettingsController implements PracticeSettingsController {
private final FXPracticeSettingsModel model;
private final PracticeTypeConverter practiceTypeConverter;
@FXML
private PrefixSelectionComboBox<PracticeType> practiceTypeCombobox;
@FXML
private Label suggestionsNumberLabel;
@FXML
private Spinner<Integer> suggestionsNumberSpinner;
@Inject
FXPracticeSettingsController(final FXPracticeSettingsModel model, final PracticeTypeConverter practiceTypeConverter) {
this.model = requireNonNull(model);
this.practiceTypeConverter = requireNonNull(practiceTypeConverter);
}
@FXML
private void initialize() {
practiceTypeCombobox.setItems(model.practiceTypes());
practiceTypeCombobox.valueProperty().bindBidirectional(model.practiceTypeProperty());
practiceTypeCombobox.setConverter(practiceTypeConverter);
suggestionsNumberLabel.visibleProperty().bind(model.hasSuggestionsProperty());
suggestionsNumberSpinner.visibleProperty().bind(model.hasSuggestionsProperty());
suggestionsNumberSpinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 8, model.suggestionsNumber()));
suggestionsNumberSpinner.getValueFactory().valueProperty().bindBidirectional(model.suggestionsNumberProperty().asObject());
}
@Override
public void startPractice() {
throw new UnsupportedOperationException();
}
@FXML
private void startPressed() {
startPractice();
}
@Override
public FXPracticeSettingsModel model() {
return model;
}
}
@@ -0,0 +1,94 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.practice.PracticeType;
import ch.gtache.fro.practice.gui.PracticeSettingsModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyBooleanWrapper;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
/**
* FX implementation of {@link PracticeSettingsModel}
*/
@Singleton
public final class FXPracticeSettingsModel implements PracticeSettingsModel {
private static final int DEFAULT_SUGGESTIONS_NUMBER = 4;
private final ObservableList<PracticeType> practiceTypes;
private final ObjectProperty<PracticeType> practiceType;
private final ReadOnlyBooleanWrapper hasSuggestions;
private final IntegerProperty suggestionsNumber;
@Inject
FXPracticeSettingsModel() {
this.practiceTypes = FXCollections.observableArrayList(PracticeType.values());
this.practiceType = new SimpleObjectProperty<>(PracticeType.PICTURE_EXACT);
this.hasSuggestions = new ReadOnlyBooleanWrapper(true);
hasSuggestions.bind(practiceType.isEqualTo(PracticeType.PICTURE_EXACT).or(practiceType.isEqualTo(PracticeType.SOUND_EXACT)));
this.suggestionsNumber = new SimpleIntegerProperty(DEFAULT_SUGGESTIONS_NUMBER);
}
@Override
public ObservableList<PracticeType> practiceTypes() {
return practiceTypes;
}
@Override
public PracticeType practiceType() {
return practiceType.get();
}
@Override
public void practiceType(final PracticeType practiceType) {
this.practiceType.set(practiceType);
}
/**
* Returns the practice type property
*
* @return The practice type property
*/
ObjectProperty<PracticeType> practiceTypeProperty() {
return practiceType;
}
@Override
public boolean hasSuggestions() {
return hasSuggestions.get();
}
/**
* Returns the has suggestions property
*
* @return The has suggestions property
*/
ReadOnlyBooleanProperty hasSuggestionsProperty() {
return hasSuggestions.getReadOnlyProperty();
}
@Override
public int suggestionsNumber() {
return suggestionsNumber.get();
}
@Override
public void suggestionsNumber(final int suggestionsNumber) {
this.suggestionsNumber.set(suggestionsNumber);
}
/**
* Returns the suggestions number property
*
* @return The suggestions number property
*/
IntegerProperty suggestionsNumberProperty() {
return suggestionsNumber;
}
}
@@ -0,0 +1,57 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.SoundType;
import ch.gtache.fro.practice.gui.PracticeSoundExactController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.media.MediaView;
import org.controlsfx.control.PrefixSelectionComboBox;
import java.util.Objects;
/**
* FX implementation of {@link PracticeSoundExactController}
*/
@Singleton
public final class FXPracticeSoundExactController implements PracticeSoundExactController {
private final FXPracticeSoundExactModel model;
@FXML
private Button validateButton;
@FXML
private TextField inputField;
@FXML
private MediaView mediaView;
@FXML
private PrefixSelectionComboBox<SoundType> typeCombobox;
@Inject
FXPracticeSoundExactController(final FXPracticeSoundExactModel model) {
this.model = Objects.requireNonNull(model);
}
@Override
public FXPracticeSoundExactModel model() {
return model;
}
@Override
public void confirm() {
throw new UnsupportedOperationException();
}
@FXML
private void validatePressed() {
confirm();
}
@FXML
private void enterPressed() {
confirm();
}
}
@@ -0,0 +1,65 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.Sound;
import ch.gtache.fro.practice.gui.PracticeSoundExactModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* FX implementation of {@link PracticeSoundExactModel}
*/
@Singleton
public final class FXPracticeSoundExactModel implements PracticeSoundExactModel {
private final StringProperty guess;
private final ObjectProperty<Sound> sound;
@Inject
FXPracticeSoundExactModel() {
this.guess = new SimpleStringProperty();
this.sound = new SimpleObjectProperty<>();
}
@Override
public String guess() {
return guess.get();
}
@Override
public void guess(final String guess) {
this.guess.set(guess);
}
/**
* Returns the property for the user guess
*
* @return the property for the user guess
*/
StringProperty guessProperty() {
return guess;
}
@Override
public Sound sound() {
return sound.get();
}
@Override
public void sound(final Sound sound) {
this.sound.set(sound);
}
/**
* Returns the property for the sound
*
* @return the property for the sound
*/
ObjectProperty<Sound> soundProperty() {
return sound;
}
}
@@ -0,0 +1,48 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.practice.gui.PracticeSoundMultichoiceController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.media.MediaView;
import java.util.Objects;
/**
* FX implementation of {@link PracticeSoundMultichoiceController}
*/
@Singleton
public final class FXPracticeSoundMultichoiceController implements PracticeSoundMultichoiceController {
private final FXPracticeSoundMultichoiceModel model;
@FXML
private GridPane grid;
@FXML
private MediaView mediaView;
@FXML
private Button validateButton;
@Inject
FXPracticeSoundMultichoiceController(final FXPracticeSoundMultichoiceModel model) {
this.model = Objects.requireNonNull(model);
}
@Override
public FXPracticeSoundMultichoiceModel model() {
return model;
}
@Override
public void confirm() {
throw new UnsupportedOperationException();
}
@FXML
private void validatePressed() {
confirm();
}
}
@@ -0,0 +1,73 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.Bird;
import ch.gtache.fro.Sound;
import ch.gtache.fro.practice.gui.PracticeSoundMultichoiceModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
/**
* FX implementation of {@link PracticeSoundMultichoiceModel}
*/
@Singleton
public final class FXPracticeSoundMultichoiceModel implements PracticeSoundMultichoiceModel {
private final ObservableList<Bird> suggestions;
private final ObjectProperty<Bird> selected;
private final ObjectProperty<Sound> sound;
@Inject
FXPracticeSoundMultichoiceModel() {
this.suggestions = FXCollections.observableArrayList();
this.selected = new SimpleObjectProperty<>();
this.sound = new SimpleObjectProperty<>();
}
@Override
public ObservableList<Bird> suggestions() {
return suggestions;
}
@Override
public Bird selected() {
return selected.get();
}
@Override
public void selected(final Bird selected) {
this.selected.set(selected);
}
/**
* Returns the property for the selected bird
*
* @return the property for the selected bird
*/
ObjectProperty<Bird> selectedProperty() {
return selected;
}
@Override
public Sound sound() {
return sound.get();
}
@Override
public void sound(final Sound sound) {
this.sound.set(sound);
}
/**
* Returns the property for the sound
*
* @return the property for the sound
*/
ObjectProperty<Sound> soundProperty() {
return sound;
}
}
@@ -0,0 +1,48 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.practice.gui.PracticeSoundMultichoicePictureController;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.media.MediaView;
import java.util.Objects;
/**
* FX implementation of {@link PracticeSoundMultichoicePictureController}
*/
@Singleton
public final class FXPracticeSoundMultichoicePictureController implements PracticeSoundMultichoicePictureController {
private final FXPracticeSoundMultichoicePictureModel model;
@FXML
private GridPane grid;
@FXML
private MediaView mediaView;
@FXML
private Button validateButton;
@Inject
FXPracticeSoundMultichoicePictureController(final FXPracticeSoundMultichoicePictureModel model) {
this.model = Objects.requireNonNull(model);
}
@Override
public FXPracticeSoundMultichoicePictureModel model() {
return model;
}
@Override
public void confirm() {
throw new UnsupportedOperationException();
}
@FXML
private void validatePressed() {
confirm();
}
}
@@ -0,0 +1,73 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.Picture;
import ch.gtache.fro.Sound;
import ch.gtache.fro.practice.gui.PracticeSoundMultichoicePictureModel;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
/**
* FX implementation of {@link PracticeSoundMultichoicePictureModel}
*/
@Singleton
public final class FXPracticeSoundMultichoicePictureModel implements PracticeSoundMultichoicePictureModel {
private final ObservableList<Picture> suggestions;
private final ObjectProperty<Picture> selected;
private final ObjectProperty<Sound> sound;
@Inject
FXPracticeSoundMultichoicePictureModel() {
this.suggestions = FXCollections.observableArrayList();
this.selected = new SimpleObjectProperty<>();
this.sound = new SimpleObjectProperty<>();
}
@Override
public ObservableList<Picture> suggestions() {
return suggestions;
}
@Override
public Picture selected() {
return selected.get();
}
@Override
public void selected(final Picture selected) {
this.selected.set(selected);
}
/**
* Returns the property for the selected picture
*
* @return the property for the selected picture
*/
ObjectProperty<Picture> selectedProperty() {
return selected;
}
@Override
public Sound sound() {
return sound.get();
}
@Override
public void sound(final Sound sound) {
this.sound.set(sound);
}
/**
* Returns the property for the sound
*
* @return the property for the sound
*/
ObjectProperty<Sound> soundProperty() {
return sound;
}
}
@@ -0,0 +1,33 @@
package ch.gtache.fro.practice.gui.fx;
import ch.gtache.fro.TranslationException;
import ch.gtache.fro.practice.PracticeType;
import ch.gtache.fro.practice.PracticeTypeTranslator;
import jakarta.inject.Inject;
import javafx.util.StringConverter;
import java.util.Objects;
public class PracticeTypeConverter extends StringConverter<PracticeType> {
private final PracticeTypeTranslator translator;
@Inject
PracticeTypeConverter(final PracticeTypeTranslator translator) {
this.translator = Objects.requireNonNull(translator);
}
@Override
public String toString(final PracticeType object) {
try {
return translator.translate(object);
} catch (final TranslationException e) {
return object.name();
}
}
@Override
public PracticeType fromString(final String string) {
return null;
}
}
+22
View File
@@ -0,0 +1,22 @@
/**
* GUI FX module for the FRO project
*/
module ch.gtache.fro.gui.fx {
requires transitive ch.gtache.fro.gui.api;
requires ch.gtache.fro.gui.core;
requires dagger;
requires jakarta.inject;
requires javafx.fxml;
requires javafx.graphics;
requires javafx.media;
requires org.controlsfx.controls;
exports ch.gtache.fro.gui.fx;
exports ch.gtache.fro.practice.gui.fx;
exports ch.gtache.fro.modules.gui.fx;
exports ch.gtache.fro.modules.practice.gui.fx;
opens ch.gtache.fro.gui.fx to javafx.fxml;
opens ch.gtache.fro.practice.gui.fx to javafx.fxml;
}
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.*?>
<?import org.controlsfx.control.CheckComboBox?>
<?import org.controlsfx.control.PrefixSelectionComboBox?>
<GridPane hgap="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" vgap="10.0"
xmlns="http://javafx.com/javafx/24.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="ch.gtache.fro.gui.fx.FXFetchController">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES"/>
<ColumnConstraints hgrow="SOMETIMES"/>
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="SOMETIMES"/>
<RowConstraints vgrow="SOMETIMES"/>
<RowConstraints vgrow="SOMETIMES"/>
</rowConstraints>
<children>
<PrefixSelectionComboBox fx:id="birdCombobox" GridPane.rowIndex="1"/>
<Button fx:id="fetchButton" mnemonicParsing="false" onAction="#fetchBirdPressed"
text="%fetch.button.fetch.label" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<Button fx:id="fetchAllButton" mnemonicParsing="false" onAction="#fetchAllPressed"
text="%fetch.button.all.label" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<Label text="%fetch.providers.label"/>
<CheckComboBox fx:id="providersCombobox" GridPane.columnIndex="1"/>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</GridPane>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<TabPane maxHeight="-Infinity" maxWidth="-Infinity" tabClosingPolicy="UNAVAILABLE" xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/24.0.1" fx:controller="ch.gtache.fro.gui.fx.FXMainController">
<tabs>
<Tab closable="false" text="%main.tab.practice.label">
<fx:include source="../../practice/gui/fx/practiceView.fxml" fx:id="practice"/>
</Tab>
<Tab closable="false" text="%main.tab.settings.label">
<fx:include source="settingsView.fxml" fx:id="settings"/>
</Tab>
<Tab closable="false" text="%main.tab.fetch.label">
<fx:include source="fetchView.fxml" fx:id="fetch"/>
</Tab>
</tabs>
</TabPane>
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" xmlns="http://javafx.com/javafx/24.0.1"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.gtache.fro.gui.fx.FXSettingsController">
<children>
<TableView fx:id="table" layoutX="200.0" layoutY="68.0" AnchorPane.bottomAnchor="10.0"
AnchorPane.leftAnchor="10.0"
AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
<columns>
<TableColumn maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="75.0"
text="%settings.table.column.enabled"/>
<TableColumn maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="75.0"
text="%settings.table.column.bird"/>
<TableColumn maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="75.0"
text="%settings.table.column.fetchers"/>
<TableColumn maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="75.0"
text="%settings.table.column.pictures"/>
<TableColumn maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="75.0"
text="%settings.table.column.sounds"/>
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
</columnResizePolicy>
</TableView>
</children>
</AnchorPane>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.*?>
<?import org.controlsfx.control.PrefixSelectionComboBox?>
<?import org.controlsfx.control.textfield.CustomTextField?>
<GridPane hgap="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" vgap="10.0"
xmlns="http://javafx.com/javafx/24.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="ch.gtache.fro.practice.gui.fx.FXPracticePictureExactController">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS"/>
<ColumnConstraints hgrow="SOMETIMES"/>
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="ALWAYS"/>
<RowConstraints vgrow="SOMETIMES"/>
<RowConstraints vgrow="SOMETIMES"/>
</rowConstraints>
<children>
<ImageView fx:id="pictureView" fitHeight="300.0" fitWidth="300.0" pickOnBounds="true" preserveRatio="true"
GridPane.columnSpan="2147483647"/>
<CustomTextField fx:id="nameField" onAction="#enterPressed" GridPane.rowIndex="1"/>
<PrefixSelectionComboBox fx:id="typeCombobox" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<Button fx:id="validateButton" mnemonicParsing="false" onAction="#validatePressed"
text="%practice.picture.exact.validate.button.label" GridPane.columnSpan="2147483647"
GridPane.halignment="CENTER" GridPane.rowIndex="2"/>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</GridPane>

Some files were not shown because too many files have changed in this diff Show More