Remember last played playlist and positions
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									c01b36b772
								
							
						
					
					
						commit
						f0068ae4c3
					
				
					 15 changed files with 288 additions and 206 deletions
				
			
		| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    Copyright 2018-2021 Dmitry Isaenko
 | 
					    Copyright 2018-2023 Dmitry Isaenko
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This file is part of mplayer4anime.
 | 
					    This file is part of mplayer4anime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,8 +22,8 @@ import java.util.prefs.Preferences;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Rule application settings
 | 
					// Rule application settings
 | 
				
			||||||
public class AppPreferences {
 | 
					public class AppPreferences {
 | 
				
			||||||
    private static AppPreferences INSTANCE = new AppPreferences();
 | 
					    private static final AppPreferences INSTANCE = new AppPreferences();
 | 
				
			||||||
    private Preferences preferences = Preferences.userRoot().node("mplayer4anime");
 | 
					    private final Preferences preferences = Preferences.userRoot().node("mplayer4anime");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private AppPreferences(){}
 | 
					    private AppPreferences(){}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,7 +99,7 @@ public class AppPreferences {
 | 
				
			||||||
    /** Return recently opened elements */
 | 
					    /** Return recently opened elements */
 | 
				
			||||||
    public String[] getRecentPlaylists(){
 | 
					    public String[] getRecentPlaylists(){
 | 
				
			||||||
        String[] recentPlaylists = new String[10];
 | 
					        String[] recentPlaylists = new String[10];
 | 
				
			||||||
        for (int i=0; i<10; i++)
 | 
					        for (int i = 0; i < 10; i++)
 | 
				
			||||||
            recentPlaylists[i] = preferences.get("RECENT_PLS_" + i, "");
 | 
					            recentPlaylists[i] = preferences.get("RECENT_PLS_" + i, "");
 | 
				
			||||||
        return recentPlaylists;
 | 
					        return recentPlaylists;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -112,7 +112,7 @@ public class AppPreferences {
 | 
				
			||||||
                    preferences.put("RECENT_PLS_" + i, recentPlaylists[i]);
 | 
					                    preferences.put("RECENT_PLS_" + i, recentPlaylists[i]);
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    preferences.put("RECENT_PLS_" + i, "");
 | 
					                    preferences.put("RECENT_PLS_" + i, "");
 | 
				
			||||||
            for (;i<10;i++)                                             // Not needed. Logic may handle received String to be less or greater then String[10], but it never happened.
 | 
					            for (;i < 10; i++)                                             // Not needed. Logic may handle received String to be less or greater then String[10], but it never happened.
 | 
				
			||||||
                preferences.put("RECENT_PLS_" + i, "");
 | 
					                preferences.put("RECENT_PLS_" + i, "");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -125,4 +125,23 @@ public class AppPreferences {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public int getBackendEngineIndexId(){ return preferences.getInt("backend_player", 0); }
 | 
					    public int getBackendEngineIndexId(){ return preferences.getInt("backend_player", 0); }
 | 
				
			||||||
    public void setBackendEngineIndexId(int value){ preferences.putInt("backend_player", value); }
 | 
					    public void setBackendEngineIndexId(int value){ preferences.putInt("backend_player", value); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getRecentPlaylist(){
 | 
				
			||||||
 | 
					        return preferences.get("RECENT_PLS_0", "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public boolean getOpenLatestPlaylistOnStart(){ return preferences.getBoolean("open_latest_playlist", true); }
 | 
				
			||||||
 | 
					    public void setOpenLatestPlaylistOnStart(boolean value){ preferences.putBoolean("open_latest_playlist" , value); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public int getLatestPositionVideo(){ return preferences.getInt("latest_video_pos", 1); }
 | 
				
			||||||
 | 
					    public void setLatestPositionVideo(int value){
 | 
				
			||||||
 | 
					        preferences.putInt("latest_video_pos", Math.max(value, 0));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public int getLatestPositionAudio(){ return preferences.getInt("latest_audio_pos", 1); }
 | 
				
			||||||
 | 
					    public void setLatestPositionAudio(int value){
 | 
				
			||||||
 | 
					        preferences.putInt("latest_audio_pos", Math.max(value, 0));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public int getLatestPositionSubs(){ return preferences.getInt("latest_subs_pos", 1); }
 | 
				
			||||||
 | 
					    public void setLatestPositionSubs(int value){
 | 
				
			||||||
 | 
					        preferences.putInt("latest_subs_pos", Math.max(value, 0));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    Copyright 2018-2021 Dmitry Isaenko
 | 
					    Copyright 2018-2023 Dmitry Isaenko
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
    This file is part of mplayer4anime.
 | 
					    This file is part of mplayer4anime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package mplayer4anime;
 | 
					package mplayer4anime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public interface ISlaveModeAppOrchestration {
 | 
					public interface IPlayer {
 | 
				
			||||||
    void subtitlesSwitch();
 | 
					    void subtitlesSwitch();
 | 
				
			||||||
    void fullscreenSwitch();
 | 
					    void fullscreenSwitch();
 | 
				
			||||||
    void mute();
 | 
					    void mute();
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    Copyright 2018-2021 Dmitry Isaenko
 | 
					    Copyright 2018-2023 Dmitry Isaenko
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
    This file is part of mplayer4anime.
 | 
					    This file is part of mplayer4anime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,14 +18,14 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package mplayer4anime.mplayer;
 | 
					package mplayer4anime.mplayer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import mplayer4anime.ISlaveModeAppOrchestration;
 | 
					import mplayer4anime.IPlayer;
 | 
				
			||||||
import mplayer4anime.ui.ServiceWindow;
 | 
					import mplayer4anime.ui.ServiceWindow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.*;
 | 
					import java.io.*;
 | 
				
			||||||
import java.util.ResourceBundle;
 | 
					import java.util.ResourceBundle;
 | 
				
			||||||
import java.util.concurrent.TimeUnit;
 | 
					import java.util.concurrent.TimeUnit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class MplayerSlave implements ISlaveModeAppOrchestration {
 | 
					public class MplayerSlave implements IPlayer {
 | 
				
			||||||
    private Process player;
 | 
					    private Process player;
 | 
				
			||||||
    private PrintStream playerIn;
 | 
					    private PrintStream playerIn;
 | 
				
			||||||
    private BufferedReader playerOutErr;
 | 
					    private BufferedReader playerOutErr;
 | 
				
			||||||
| 
						 | 
					@ -37,14 +37,14 @@ public class MplayerSlave implements ISlaveModeAppOrchestration {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean playerSingleCommand(String command){
 | 
					    private boolean playerSingleCommand(String command){
 | 
				
			||||||
        if (player != null && player.isAlive()) {
 | 
					        if (player == null || ! player.isAlive())
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        playerIn.print(command);
 | 
					        playerIn.print(command);
 | 
				
			||||||
        playerIn.print("\n");
 | 
					        playerIn.print("\n");
 | 
				
			||||||
        playerIn.flush();
 | 
					        playerIn.flush();
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void subtitlesSwitch(){
 | 
					    public void subtitlesSwitch(){
 | 
				
			||||||
        if (! playerSingleCommand("get_sub_visibility"))
 | 
					        if (! playerSingleCommand("get_sub_visibility"))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    Copyright 2018-2021 Dmitry Isaenko
 | 
					    Copyright 2018-2023 Dmitry Isaenko
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
    This file is part of mplayer4anime.
 | 
					    This file is part of mplayer4anime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,11 +18,11 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package mplayer4anime.mpv;
 | 
					package mplayer4anime.mpv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import mplayer4anime.ISlaveModeAppOrchestration;
 | 
					import mplayer4anime.IPlayer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ResourceBundle;
 | 
					import java.util.ResourceBundle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class MpvSlave implements ISlaveModeAppOrchestration {
 | 
					public class MpvSlave implements IPlayer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public MpvSlave(ResourceBundle resourceBundle){
 | 
					    public MpvSlave(ResourceBundle resourceBundle){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    Copyright 2018-2021 Dmitry Isaenko
 | 
					    Copyright 2018-2023 Dmitry Isaenko
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This file is part of mplayer4anime.
 | 
					    This file is part of mplayer4anime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,7 @@ import mplayer4anime.ui.ServiceWindow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.*;
 | 
					import java.io.*;
 | 
				
			||||||
import java.nio.charset.StandardCharsets;
 | 
					import java.nio.charset.StandardCharsets;
 | 
				
			||||||
 | 
					import java.nio.file.Files;
 | 
				
			||||||
import java.util.ResourceBundle;
 | 
					import java.util.ResourceBundle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Playlists {
 | 
					public class Playlists {
 | 
				
			||||||
| 
						 | 
					@ -31,23 +32,22 @@ public class Playlists {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //TODO: Show popUp if unable to write! Or nothing to write! Or overwrite!
 | 
					    //TODO: Show popUp if unable to write! Or nothing to write! Or overwrite!
 | 
				
			||||||
    //TODO: Disable 'Save' button if no files added
 | 
					    //TODO: Disable 'Save' button if no files added
 | 
				
			||||||
    public static boolean SaveAs(ResourceBundle resourceBundle, JsonStorage jStorage){
 | 
					    public static boolean saveAs(ResourceBundle resourceBundle, JsonStorage jStorage){
 | 
				
			||||||
        File playlistFile;
 | 
					 | 
				
			||||||
        FileChooser fileChooser = new FileChooser();
 | 
					        FileChooser fileChooser = new FileChooser();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fileChooser.setTitle(resourceBundle.getString("SelectFile"));
 | 
					        fileChooser.setTitle(resourceBundle.getString("SelectFile"));
 | 
				
			||||||
        fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
 | 
					        fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
 | 
				
			||||||
        fileChooser.setInitialFileName("MyPlaylist.alpr");
 | 
					        fileChooser.setInitialFileName("MyPlaylist.alpr");
 | 
				
			||||||
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
 | 
					        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
 | 
				
			||||||
        playlistFile = fileChooser.showSaveDialog(null);
 | 
					        File playlistFile = fileChooser.showSaveDialog(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return writeFile(resourceBundle, playlistFile, jStorage);
 | 
					        return writeFile(resourceBundle, playlistFile, jStorage);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static boolean SaveCurrent(ResourceBundle resourceBundle, JsonStorage jStorage) {
 | 
					    public static boolean saveCurrent(ResourceBundle resourceBundle, JsonStorage jStorage) {
 | 
				
			||||||
        if (playlistLocation == null || playlistLocation.equals("")){
 | 
					        if (playlistLocation == null || playlistLocation.equals(""))
 | 
				
			||||||
            return Playlists.SaveAs(resourceBundle, jStorage);
 | 
					            return Playlists.saveAs(resourceBundle, jStorage);
 | 
				
			||||||
        }
 | 
					
 | 
				
			||||||
        return writeFile(resourceBundle, new File(playlistLocation), jStorage);
 | 
					        return writeFile(resourceBundle, new File(playlistLocation), jStorage);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,7 +91,7 @@ public class Playlists {
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Interface for Opening playlists via FileChooser
 | 
					     * Interface for Opening playlists via FileChooser
 | 
				
			||||||
     **/
 | 
					     **/
 | 
				
			||||||
    public static JsonStorage OpenPlaylistFileChooser(ResourceBundle resourceBundle){
 | 
					    public static JsonStorage openPlaylistFileChooser(ResourceBundle resourceBundle){
 | 
				
			||||||
        File playlistFile;
 | 
					        File playlistFile;
 | 
				
			||||||
        FileChooser fileChooser = new FileChooser();
 | 
					        FileChooser fileChooser = new FileChooser();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,12 +101,12 @@ public class Playlists {
 | 
				
			||||||
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
 | 
					        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
 | 
				
			||||||
        playlistFile = fileChooser.showOpenDialog(null);
 | 
					        playlistFile = fileChooser.showOpenDialog(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return ReadByPath(resourceBundle, playlistFile);
 | 
					        return readByPath(resourceBundle, playlistFile);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Interface for Opening playlists using file itself
 | 
					     * Interface for Opening playlists using file itself
 | 
				
			||||||
     * */
 | 
					     * */
 | 
				
			||||||
    public static JsonStorage ReadByPath(ResourceBundle resourceBundle, File playlistFile){
 | 
					    public static JsonStorage readByPath(ResourceBundle resourceBundle, File playlistFile){
 | 
				
			||||||
        if (playlistFile == null) {
 | 
					        if (playlistFile == null) {
 | 
				
			||||||
            ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
 | 
					            ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
 | 
				
			||||||
                    "Playlist file not selected");// TODO: translate
 | 
					                    "Playlist file not selected");// TODO: translate
 | 
				
			||||||
| 
						 | 
					@ -132,6 +132,17 @@ public class Playlists {
 | 
				
			||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static JsonStorage readByPathSilent(File playlistFile){
 | 
				
			||||||
 | 
					        try (Reader reader = new InputStreamReader(Files.newInputStream(playlistFile.toPath()))) {
 | 
				
			||||||
 | 
					            JsonStorage jStorage = new Gson().fromJson(reader, JsonStorage.class);
 | 
				
			||||||
 | 
					            if (jStorage != null){
 | 
				
			||||||
 | 
					                playlistLocation = playlistFile.getAbsolutePath();
 | 
				
			||||||
 | 
					                return jStorage;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception ignore){}
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Return path to file opened */
 | 
					    /** Return path to file opened */
 | 
				
			||||||
    public static String getPlaylistLocation(){
 | 
					    public static String getPlaylistLocation(){
 | 
				
			||||||
        return playlistLocation;
 | 
					        return playlistLocation;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    Copyright 2018-2021 Dmitry Isaenko
 | 
					    Copyright 2018-2023 Dmitry Isaenko
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This file is part of mplayer4anime.
 | 
					    This file is part of mplayer4anime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ import javafx.scene.control.*;
 | 
				
			||||||
import javafx.stage.Stage;
 | 
					import javafx.stage.Stage;
 | 
				
			||||||
import mplayer4anime.ui.about.AboutWindow;
 | 
					import mplayer4anime.ui.about.AboutWindow;
 | 
				
			||||||
import mplayer4anime.AppPreferences;
 | 
					import mplayer4anime.AppPreferences;
 | 
				
			||||||
import mplayer4anime.ISlaveModeAppOrchestration;
 | 
					import mplayer4anime.IPlayer;
 | 
				
			||||||
import mplayer4anime.MediatorControl;
 | 
					import mplayer4anime.MediatorControl;
 | 
				
			||||||
import mplayer4anime.playlists.JsonStorage;
 | 
					import mplayer4anime.playlists.JsonStorage;
 | 
				
			||||||
import mplayer4anime.playlists.Playlists;
 | 
					import mplayer4anime.playlists.Playlists;
 | 
				
			||||||
| 
						 | 
					@ -45,9 +45,9 @@ import java.util.ResourceBundle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class LandingController implements Initializable {
 | 
					public class LandingController implements Initializable {
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    ControllerPane mkvPaneController, mkaPaneController;
 | 
					    private ControllerPane mkvPaneController, mkaPaneController;
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    ControllerPaneSubtitles subPaneController;
 | 
					    private ControllerPaneSubtitles subPaneController;
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private PlayerToolbarController playerToolbarController;
 | 
					    private PlayerToolbarController playerToolbarController;
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
| 
						 | 
					@ -65,16 +65,17 @@ public class LandingController implements Initializable {
 | 
				
			||||||
    private String currentPlaylistLocation;
 | 
					    private String currentPlaylistLocation;
 | 
				
			||||||
    private String backend;
 | 
					    private String backend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ISlaveModeAppOrchestration player;
 | 
					    private IPlayer player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If application started with playlist passed as an argument, then we'll try to load it (if it's valid).
 | 
					    // If application started with playlist passed as an argument, then we'll try to load it (if it's valid).
 | 
				
			||||||
    public void setPlaylistAsArgument(String playlist) {
 | 
					    public void setPlaylistAsArgument(String playlist) {
 | 
				
			||||||
        JsonStorage jsonStorage = Playlists.ReadByPath(resourceBundle, new File(playlist));
 | 
					        JsonStorage jsonStorage = Playlists.readByPath(resourceBundle, new File(playlist));
 | 
				
			||||||
        setAllLists(jsonStorage);
 | 
					        setAllLists(jsonStorage);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void initialize(URL url, ResourceBundle rb) {
 | 
					    public void initialize(URL url, ResourceBundle resourceBundle) {
 | 
				
			||||||
 | 
					        this.resourceBundle = resourceBundle;
 | 
				
			||||||
        // Register this controller in mediator
 | 
					        // Register this controller in mediator
 | 
				
			||||||
        MediatorControl.getInstance().registerMainController(this);
 | 
					        MediatorControl.getInstance().registerMainController(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,8 +83,6 @@ public class LandingController implements Initializable {
 | 
				
			||||||
        mkaPaneController.setPaneType("Audio");
 | 
					        mkaPaneController.setPaneType("Audio");
 | 
				
			||||||
        subPaneController.setPaneType("Subtitles");
 | 
					        subPaneController.setPaneType("Subtitles");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resourceBundle = rb;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Set default list of encodings of the subtitles files:
 | 
					        // Set default list of encodings of the subtitles files:
 | 
				
			||||||
        subPaneController.setEncoding(appPreferences.getSubsEncodingList(), appPreferences.getLastTimeUsedSubsEncoding());
 | 
					        subPaneController.setEncoding(appPreferences.getSubsEncodingList(), appPreferences.getLastTimeUsedSubsEncoding());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,13 +106,27 @@ public class LandingController implements Initializable {
 | 
				
			||||||
            player = new MpvSlave(resourceBundle);
 | 
					            player = new MpvSlave(resourceBundle);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        playerToolbarController.initializeMainUiController(this);
 | 
					        playerToolbarController.initializeMainUiController(player, mkvPaneController, mkaPaneController, subPaneController);
 | 
				
			||||||
        /*
 | 
					
 | 
				
			||||||
        Playlists.ReadByPath(resourceBundle, playListFile);
 | 
					        if (appPreferences.getOpenLatestPlaylistOnStart())
 | 
				
			||||||
        * */
 | 
					            loadLatestPlaylist();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    private void loadLatestPlaylist(){
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            String recentPlaylist = appPreferences.getRecentPlaylist();
 | 
				
			||||||
 | 
					            if ("".equals(recentPlaylist))
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            // TODO: IF video set, if playlist has been opened before
 | 
				
			||||||
 | 
					            JsonStorage jsonStorage = Playlists.readByPathSilent(new File(recentPlaylist));
 | 
				
			||||||
 | 
					            setAllLists(jsonStorage);
 | 
				
			||||||
 | 
					            mkvPaneController.setElementSelectedByIndex(appPreferences.getLatestPositionVideo());
 | 
				
			||||||
 | 
					            mkaPaneController.setElementSelectedByIndex(appPreferences.getLatestPositionAudio());
 | 
				
			||||||
 | 
					            subPaneController.setElementSelectedByIndex(appPreferences.getLatestPositionSubs());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch (Exception ignore){}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void setHostServices(HostServices hostServices) {
 | 
					    public void setHostServices(HostServices hostServices){
 | 
				
			||||||
        this.hostServices = hostServices;
 | 
					        this.hostServices = hostServices;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -130,16 +143,21 @@ public class LandingController implements Initializable {
 | 
				
			||||||
        playerToolbarController.shutdown();
 | 
					        playerToolbarController.shutdown();
 | 
				
			||||||
        // TODO: remove from here; too sophisticated
 | 
					        // TODO: remove from here; too sophisticated
 | 
				
			||||||
        String[] storeRecentArr = new String[10];
 | 
					        String[] storeRecentArr = new String[10];
 | 
				
			||||||
        for (int i =0; i < recentlyOpenedMenu.getItems().size() - 2 && !(i > 9); i++) {       // Don't take separator and Clean button
 | 
					        for (int i = 0; i < recentlyOpenedMenu.getItems().size() - 2 && !(i > 9); i++) {       // Don't take separator and Clean button
 | 
				
			||||||
            storeRecentArr[i] = (String) recentlyOpenedMenu.getItems().get(i).getUserData();
 | 
					            storeRecentArr[i] = (String) recentlyOpenedMenu.getItems().get(i).getUserData();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        appPreferences.setRecentPlaylists(storeRecentArr);
 | 
					        appPreferences.setRecentPlaylists(storeRecentArr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        appPreferences.setLatestPositionVideo(mkvPaneController.getElementSelectedIndex());
 | 
				
			||||||
 | 
					        appPreferences.setLatestPositionAudio(mkaPaneController.getElementSelectedIndex());
 | 
				
			||||||
 | 
					        appPreferences.setLatestPositionSubs(subPaneController.getElementSelectedIndex());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Platform.exit();
 | 
					        Platform.exit();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private void infoBtn(){
 | 
					    private void infoBtn(){
 | 
				
			||||||
        new AboutWindow(this.hostServices);
 | 
					        new AboutWindow(hostServices);
 | 
				
			||||||
    } // TODO: fix this shit with hostSerivces that doesn't work @ linux
 | 
					    } // TODO: fix this shit with hostSerivces that doesn't work @ linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**             SETTINGS HANDLE          */
 | 
					    /**             SETTINGS HANDLE          */
 | 
				
			||||||
| 
						 | 
					@ -170,7 +188,7 @@ public class LandingController implements Initializable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private void openBtn() {
 | 
					    private void openBtn() {
 | 
				
			||||||
        JsonStorage jsonStorage = Playlists.OpenPlaylistFileChooser(resourceBundle);
 | 
					        JsonStorage jsonStorage = Playlists.openPlaylistFileChooser(resourceBundle);
 | 
				
			||||||
        setAllLists(jsonStorage);
 | 
					        setAllLists(jsonStorage);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    private void setAllLists(JsonStorage jsonStorage){
 | 
					    private void setAllLists(JsonStorage jsonStorage){
 | 
				
			||||||
| 
						 | 
					@ -197,7 +215,7 @@ public class LandingController implements Initializable {
 | 
				
			||||||
                mkaPaneController.getElementsAll(),
 | 
					                mkaPaneController.getElementsAll(),
 | 
				
			||||||
                subPaneController.getElementsAll(),
 | 
					                subPaneController.getElementsAll(),
 | 
				
			||||||
                subPaneController.getSelectedEncoding());
 | 
					                subPaneController.getSelectedEncoding());
 | 
				
			||||||
        if (Playlists.SaveCurrent(resourceBundle, jsonStorage)) {
 | 
					        if (Playlists.saveCurrent(resourceBundle, jsonStorage)) {
 | 
				
			||||||
            this.currentPlaylistLocation = Playlists.getPlaylistLocation();
 | 
					            this.currentPlaylistLocation = Playlists.getPlaylistLocation();
 | 
				
			||||||
            this.statusLbl.setText(currentPlaylistLocation);    //TODO: update header of the application to include this?
 | 
					            this.statusLbl.setText(currentPlaylistLocation);    //TODO: update header of the application to include this?
 | 
				
			||||||
            addRecentlyOpened(currentPlaylistLocation);
 | 
					            addRecentlyOpened(currentPlaylistLocation);
 | 
				
			||||||
| 
						 | 
					@ -216,7 +234,7 @@ public class LandingController implements Initializable {
 | 
				
			||||||
                mkaPaneController.getElementsAll(),
 | 
					                mkaPaneController.getElementsAll(),
 | 
				
			||||||
                subPaneController.getElementsAll(),
 | 
					                subPaneController.getElementsAll(),
 | 
				
			||||||
                subPaneController.getSelectedEncoding());
 | 
					                subPaneController.getSelectedEncoding());
 | 
				
			||||||
        if (Playlists.SaveAs(resourceBundle, jsonStorage)) {
 | 
					        if (Playlists.saveAs(resourceBundle, jsonStorage)) {
 | 
				
			||||||
            this.currentPlaylistLocation = Playlists.getPlaylistLocation();
 | 
					            this.currentPlaylistLocation = Playlists.getPlaylistLocation();
 | 
				
			||||||
            this.statusLbl.setText(currentPlaylistLocation);    //TODO: update header of the application to include this?
 | 
					            this.statusLbl.setText(currentPlaylistLocation);    //TODO: update header of the application to include this?
 | 
				
			||||||
            addRecentlyOpened(currentPlaylistLocation);
 | 
					            addRecentlyOpened(currentPlaylistLocation);
 | 
				
			||||||
| 
						 | 
					@ -246,7 +264,7 @@ public class LandingController implements Initializable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        menuItem.setUserData(playlistPath);
 | 
					        menuItem.setUserData(playlistPath);
 | 
				
			||||||
        menuItem.setOnAction(actionEvent -> {
 | 
					        menuItem.setOnAction(actionEvent -> {
 | 
				
			||||||
            JsonStorage jsonStorage = Playlists.ReadByPath(resourceBundle, new File(playlistPath));
 | 
					            JsonStorage jsonStorage = Playlists.readByPath(resourceBundle, new File(playlistPath));
 | 
				
			||||||
            setAllLists(jsonStorage);
 | 
					            setAllLists(jsonStorage);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        // Limit list to 13 elements (2 in the end are separator and clear button)
 | 
					        // Limit list to 13 elements (2 in the end are separator and clear button)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,27 +1,34 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    Copyright 2018-2021 Dmitry Isaenko
 | 
					    Copyright 2018-2023 Dmitry Isaenko
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
    This file is part of mcontroller.player.anime.
 | 
					    This file is part of mplayer4anime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mcontroller.player.anime is free software: you can redistribute it and/or modify
 | 
					    mplayer4anime is free software: you can redistribute it and/or modify
 | 
				
			||||||
    it under the terms of the GNU General Public License as published by
 | 
					    it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation, either version 3 of the License, or
 | 
					    the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mcontroller.player.anime is distributed in the hope that it will be useful,
 | 
					    mplayer4anime is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License
 | 
					    You should have received a copy of the GNU General Public License
 | 
				
			||||||
    along with mcontroller.player.anime.  If not, see <https://www.gnu.org/licenses/>.
 | 
					    along with mplayer4anime.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package mplayer4anime.ui.landing;
 | 
					package mplayer4anime.ui.landing;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javafx.beans.binding.Bindings;
 | 
				
			||||||
import javafx.fxml.FXML;
 | 
					import javafx.fxml.FXML;
 | 
				
			||||||
import javafx.fxml.Initializable;
 | 
					import javafx.fxml.Initializable;
 | 
				
			||||||
 | 
					import javafx.scene.control.Button;
 | 
				
			||||||
 | 
					import javafx.scene.control.ButtonBase;
 | 
				
			||||||
import javafx.scene.control.CheckMenuItem;
 | 
					import javafx.scene.control.CheckMenuItem;
 | 
				
			||||||
 | 
					import javafx.scene.control.SplitMenuButton;
 | 
				
			||||||
import mplayer4anime.AppPreferences;
 | 
					import mplayer4anime.AppPreferences;
 | 
				
			||||||
 | 
					import mplayer4anime.IPlayer;
 | 
				
			||||||
 | 
					import mplayer4anime.ui.landing.panes.ControllerPane;
 | 
				
			||||||
 | 
					import mplayer4anime.ui.landing.panes.ControllerPaneSubtitles;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.net.URL;
 | 
					import java.net.URL;
 | 
				
			||||||
import java.util.ResourceBundle;
 | 
					import java.util.ResourceBundle;
 | 
				
			||||||
| 
						 | 
					@ -31,9 +38,15 @@ public class PlayerToolbarController implements Initializable {
 | 
				
			||||||
    private CheckMenuItem fullScreen;
 | 
					    private CheckMenuItem fullScreen;
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private CheckMenuItem subsHide;
 | 
					    private CheckMenuItem subsHide;
 | 
				
			||||||
 | 
					    @FXML
 | 
				
			||||||
 | 
					    private Button muteBtn, playPrevTrackBtn, playNextTrackBtn, playBtn, stopBtn, volumeUpBtn, volumeDownBtn;
 | 
				
			||||||
 | 
					    @FXML
 | 
				
			||||||
 | 
					    private SplitMenuButton subsTriggerBtn, fullscreenBtn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private AppPreferences appPreferences;
 | 
					    private AppPreferences appPreferences;
 | 
				
			||||||
    private LandingController landingController;
 | 
					    private IPlayer player;
 | 
				
			||||||
 | 
					    private ControllerPane mkvPaneController, mkaPaneController;
 | 
				
			||||||
 | 
					    private ControllerPaneSubtitles subPaneController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void initialize(URL url, ResourceBundle resourceBundle) {
 | 
					    public void initialize(URL url, ResourceBundle resourceBundle) {
 | 
				
			||||||
| 
						 | 
					@ -41,89 +54,111 @@ public class PlayerToolbarController implements Initializable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fullScreen.setSelected(appPreferences.getFullScreenSelected());
 | 
					        fullScreen.setSelected(appPreferences.getFullScreenSelected());
 | 
				
			||||||
        subsHide.setSelected(appPreferences.getSubtitlesHideSelected());
 | 
					        subsHide.setSelected(appPreferences.getSubtitlesHideSelected());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        stopBtn.setOnAction(event -> player.stop());
 | 
				
			||||||
 | 
					        volumeUpBtn.setOnAction(event -> player.volumeUp());
 | 
				
			||||||
 | 
					        volumeDownBtn.setOnAction(event -> player.volumeDown());
 | 
				
			||||||
 | 
					        muteBtn.setOnAction(event -> player.mute());
 | 
				
			||||||
 | 
					        playBtn.setOnAction(event -> play());
 | 
				
			||||||
 | 
					        playPrevTrackBtn.setOnAction(event -> playPrevTrack());
 | 
				
			||||||
 | 
					        playNextTrackBtn.setOnAction(event -> playNextTrack());
 | 
				
			||||||
 | 
					        subsTriggerBtn.setOnAction(event -> player.subtitlesSwitch());
 | 
				
			||||||
 | 
					        fullscreenBtn.setOnAction(event -> player.fullscreenSwitch());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public void initializeMainUiController(LandingController landingController){
 | 
					    public void initializeMainUiController(IPlayer player,
 | 
				
			||||||
        this.landingController = landingController;
 | 
					                                           ControllerPane mkvPaneController,
 | 
				
			||||||
 | 
					                                           ControllerPane  mkaPaneController,
 | 
				
			||||||
 | 
					                                           ControllerPaneSubtitles subPaneController){
 | 
				
			||||||
 | 
					        this.player = player;
 | 
				
			||||||
 | 
					        this.mkvPaneController = mkvPaneController;
 | 
				
			||||||
 | 
					        this.mkaPaneController = mkaPaneController;
 | 
				
			||||||
 | 
					        this.subPaneController = subPaneController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bindButtonToEmptyList(stopBtn);
 | 
				
			||||||
 | 
					        bindButtonToEmptyList(volumeUpBtn);
 | 
				
			||||||
 | 
					        bindButtonToEmptyList(volumeDownBtn);
 | 
				
			||||||
 | 
					        bindButtonToEmptyList(muteBtn);
 | 
				
			||||||
 | 
					        bindButtonToEmptyList(playBtn);
 | 
				
			||||||
 | 
					        bindButtonToEmptyList(subsTriggerBtn);
 | 
				
			||||||
 | 
					        bindButtonToEmptyList(fullscreenBtn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        playPrevTrackBtn.disableProperty().bind(
 | 
				
			||||||
 | 
					                Bindings.isEmpty(mkvPaneController.getPaneFileList()).or(
 | 
				
			||||||
 | 
					                Bindings.equal(mkvPaneController.getSelectedIndexProperty(), 0)
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        playNextTrackBtn.disableProperty().bind(
 | 
				
			||||||
 | 
					                Bindings.isEmpty(mkvPaneController.getPaneFileList()).or(
 | 
				
			||||||
 | 
					                Bindings.equal(mkvPaneController.getSelectedIndexProperty(),
 | 
				
			||||||
 | 
					                        Bindings.subtract(Bindings.size(mkvPaneController.getPaneFileList()), 1))
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    private void bindButtonToEmptyList(ButtonBase button){
 | 
				
			||||||
 | 
					        button.disableProperty().bind(Bindings.isEmpty(mkvPaneController.getPaneFileList()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @FXML
 | 
					    private void play(){
 | 
				
			||||||
    private void subsTriggerBtn(){
 | 
					        if (mkvPaneController.getElementSelected() == null)
 | 
				
			||||||
        landingController.player.subtitlesSwitch();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    @FXML
 | 
					 | 
				
			||||||
    private void fullscreenBtn(){
 | 
					 | 
				
			||||||
        landingController.player.fullscreenSwitch();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    @FXML
 | 
					 | 
				
			||||||
    private void muteBtn(){
 | 
					 | 
				
			||||||
        landingController.player.mute();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    @FXML
 | 
					 | 
				
			||||||
    private void playPrevTrackBtn(){
 | 
					 | 
				
			||||||
        int index = landingController.mkvPaneController.getElementSelectedIndex();
 | 
					 | 
				
			||||||
        if (index <= 0)
 | 
					 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        landingController.mkvPaneController.setElementSelectedByIndex(index-1);
 | 
					        player.playPause(appPreferences.getPath(),
 | 
				
			||||||
        landingController.player.forcePlay(appPreferences.getPath(),
 | 
					                mkvPaneController.getElementSelected(),
 | 
				
			||||||
                landingController.mkvPaneController.getElementSelected(),
 | 
					                mkaPaneController.getElementSelected(),
 | 
				
			||||||
                landingController.mkaPaneController.getElementSelected(),
 | 
					                subPaneController.getElementSelected(),
 | 
				
			||||||
                landingController.subPaneController.getElementSelected(),
 | 
					                subPaneController.getSelectedEncoding(),
 | 
				
			||||||
                landingController.subPaneController.getSelectedEncoding(),
 | 
					 | 
				
			||||||
                subsHide.isSelected(),
 | 
					                subsHide.isSelected(),
 | 
				
			||||||
                fullScreen.isSelected()
 | 
					                fullScreen.isSelected()
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    @FXML
 | 
					 | 
				
			||||||
    private void playNextTrackBtn(){
 | 
					 | 
				
			||||||
        int index = landingController.mkvPaneController.getElementSelectedIndex();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (index + 1 < landingController.mkvPaneController.getElementsCount()) {
 | 
					    private void playPrevTrack(){
 | 
				
			||||||
            landingController.mkvPaneController.setElementSelectedByIndex(index + 1);
 | 
					        int index = mkvPaneController.getElementSelectedIndex() - 1;
 | 
				
			||||||
        }
 | 
					        if (index < 0)
 | 
				
			||||||
        index = landingController.mkaPaneController.getElementSelectedIndex();
 | 
					 | 
				
			||||||
        if (index + 1 < landingController.mkaPaneController.getElementsCount()) {
 | 
					 | 
				
			||||||
            landingController.mkaPaneController.setElementSelectedByIndex(index + 1);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        index = landingController.subPaneController.getElementSelectedIndex();
 | 
					 | 
				
			||||||
        if (index + 1 < landingController.subPaneController.getElementsCount()) {
 | 
					 | 
				
			||||||
            landingController.subPaneController.setElementSelectedByIndex(index + 1);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        landingController.player.forcePlay(appPreferences.getPath(),
 | 
					 | 
				
			||||||
                landingController.mkvPaneController.getElementSelected(),
 | 
					 | 
				
			||||||
                landingController.mkaPaneController.getElementSelected(),
 | 
					 | 
				
			||||||
                landingController.subPaneController.getElementSelected(),
 | 
					 | 
				
			||||||
                landingController.subPaneController.getSelectedEncoding(),
 | 
					 | 
				
			||||||
                subsHide.isSelected(),
 | 
					 | 
				
			||||||
                fullScreen.isSelected()
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    @FXML
 | 
					 | 
				
			||||||
    private void playBtn(){
 | 
					 | 
				
			||||||
        if (landingController.mkvPaneController.getElementSelected() == null)
 | 
					 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        landingController.player.playPause(appPreferences.getPath(),
 | 
					        mkvPaneController.setElementSelectedByIndex(index);
 | 
				
			||||||
                landingController.mkvPaneController.getElementSelected(),
 | 
					
 | 
				
			||||||
                landingController.mkaPaneController.getElementSelected(),
 | 
					        index = mkaPaneController.getElementSelectedIndex();
 | 
				
			||||||
                landingController.subPaneController.getElementSelected(),
 | 
					        if (index > 0)
 | 
				
			||||||
                landingController.subPaneController.getSelectedEncoding(),
 | 
					            mkaPaneController.setElementSelectedByIndex(index - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        index = subPaneController.getElementSelectedIndex();
 | 
				
			||||||
 | 
					        if (index > 0)
 | 
				
			||||||
 | 
					            subPaneController.setElementSelectedByIndex(index - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        player.forcePlay(appPreferences.getPath(),
 | 
				
			||||||
 | 
					                mkvPaneController.getElementSelected(),
 | 
				
			||||||
 | 
					                mkaPaneController.getElementSelected(),
 | 
				
			||||||
 | 
					                subPaneController.getElementSelected(),
 | 
				
			||||||
 | 
					                subPaneController.getSelectedEncoding(),
 | 
				
			||||||
                subsHide.isSelected(),
 | 
					                subsHide.isSelected(),
 | 
				
			||||||
                fullScreen.isSelected()
 | 
					                fullScreen.isSelected()
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    @FXML
 | 
					
 | 
				
			||||||
    private void stopBtn(){
 | 
					    private void playNextTrack(){
 | 
				
			||||||
        landingController.player.stop();
 | 
					        int index = mkvPaneController.getElementSelectedIndex() + 1;
 | 
				
			||||||
    }
 | 
					        if (index >= mkvPaneController.getElementsCount())
 | 
				
			||||||
    @FXML
 | 
					            return;
 | 
				
			||||||
    private void volumeUpBtn(){
 | 
					
 | 
				
			||||||
        landingController.player.volumeUp();
 | 
					        mkvPaneController.setElementSelectedByIndex(index);
 | 
				
			||||||
    }
 | 
					
 | 
				
			||||||
    @FXML
 | 
					        index = mkaPaneController.getElementSelectedIndex() + 1;
 | 
				
			||||||
    private void volumeDownBtn(){
 | 
					        if (index < mkaPaneController.getElementsCount())
 | 
				
			||||||
        landingController.player.volumeDown();
 | 
					            mkaPaneController.setElementSelectedByIndex(index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        index = subPaneController.getElementSelectedIndex() + 1;
 | 
				
			||||||
 | 
					        if (index < subPaneController.getElementsCount())
 | 
				
			||||||
 | 
					            subPaneController.setElementSelectedByIndex(index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        player.forcePlay(appPreferences.getPath(),
 | 
				
			||||||
 | 
					                mkvPaneController.getElementSelected(),
 | 
				
			||||||
 | 
					                mkaPaneController.getElementSelected(),
 | 
				
			||||||
 | 
					                subPaneController.getElementSelected(),
 | 
				
			||||||
 | 
					                subPaneController.getSelectedEncoding(),
 | 
				
			||||||
 | 
					                subsHide.isSelected(),
 | 
				
			||||||
 | 
					                fullScreen.isSelected()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void shutdown(){
 | 
					    void shutdown(){
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    Copyright 2018-2021 Dmitry Isaenko
 | 
					    Copyright 2018-2023 Dmitry Isaenko
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This file is part of mplayer4anime.
 | 
					    This file is part of mplayer4anime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package mplayer4anime.ui.landing.panes;
 | 
					package mplayer4anime.ui.landing.panes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javafx.beans.property.ReadOnlyIntegerProperty;
 | 
				
			||||||
import javafx.collections.FXCollections;
 | 
					import javafx.collections.FXCollections;
 | 
				
			||||||
import javafx.collections.ObservableList;
 | 
					import javafx.collections.ObservableList;
 | 
				
			||||||
import javafx.fxml.FXML;
 | 
					import javafx.fxml.FXML;
 | 
				
			||||||
| 
						 | 
					@ -50,7 +51,6 @@ public class ControllerPane implements Initializable {
 | 
				
			||||||
    private Label paneLbl;
 | 
					    private Label paneLbl;
 | 
				
			||||||
    private String paneType;
 | 
					    private String paneType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void initialize(URL url, ResourceBundle resBundle) {
 | 
					    public void initialize(URL url, ResourceBundle resBundle) {
 | 
				
			||||||
        SetCellFactory(paneListView);
 | 
					        SetCellFactory(paneListView);
 | 
				
			||||||
| 
						 | 
					@ -58,10 +58,14 @@ public class ControllerPane implements Initializable {
 | 
				
			||||||
        appPreferences = AppPreferences.getINSTANCE();
 | 
					        appPreferences = AppPreferences.getINSTANCE();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ObservableList<File> getPaneFileList() {
 | 
				
			||||||
 | 
					        return paneFileList;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void setPaneType(String paneType){
 | 
					    public void setPaneType(String paneType){
 | 
				
			||||||
        this.paneType = paneType;
 | 
					        this.paneType = paneType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        switch (paneType) {
 | 
					        switch (paneType){
 | 
				
			||||||
            case "Video":
 | 
					            case "Video":
 | 
				
			||||||
                paneLbl.setText(resourceBundle.getString("lbl_VideoPane"));
 | 
					                paneLbl.setText(resourceBundle.getString("lbl_VideoPane"));
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
| 
						 | 
					@ -73,7 +77,6 @@ public class ControllerPane implements Initializable {
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                paneLbl.setText(resourceBundle.getString("?"));
 | 
					                paneLbl.setText(resourceBundle.getString("?"));
 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,23 +94,20 @@ public class ControllerPane implements Initializable {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /** Select element in pane using index recieved */
 | 
					    /** Select element in pane using index recieved */
 | 
				
			||||||
    public void setElementSelectedByIndex(int index){
 | 
					    public void setElementSelectedByIndex(int index){
 | 
				
			||||||
        this.paneListView.getSelectionModel().select(index);
 | 
					        paneListView.getSelectionModel().select(index);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /** Get number of elements loaded into the pane */
 | 
					    /** Get number of elements loaded into the pane */
 | 
				
			||||||
    public int getElementsCount(){
 | 
					    public int getElementsCount(){
 | 
				
			||||||
        return this.paneFileList.size();
 | 
					        return paneFileList.size();
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /** Check if there are any elements loaded */
 | 
					 | 
				
			||||||
    public boolean isElementsListEmpty(){
 | 
					 | 
				
			||||||
        return paneFileList.isEmpty();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /** Get all elements
 | 
					    /** Get all elements
 | 
				
			||||||
     * Used in Json playlist writer only */
 | 
					     * Used in Json playlist writer only */
 | 
				
			||||||
    public String[] getElementsAll(){
 | 
					    public String[] getElementsAll(){
 | 
				
			||||||
        String[] elementsArray = new String[this.getElementsCount()];
 | 
					        String[] elementsArray = new String[this.getElementsCount()];
 | 
				
			||||||
        for (int i = 0; i < elementsArray.length; i++){
 | 
					
 | 
				
			||||||
 | 
					        for (int i = 0; i < elementsArray.length; i++)
 | 
				
			||||||
            elementsArray[i] = paneFileList.get(i).toString();
 | 
					            elementsArray[i] = paneFileList.get(i).toString();
 | 
				
			||||||
        }
 | 
					
 | 
				
			||||||
        return  elementsArray;
 | 
					        return  elementsArray;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -239,61 +239,63 @@ public class ControllerPane implements Initializable {
 | 
				
			||||||
     * */
 | 
					     * */
 | 
				
			||||||
    public void setFilesFromList(String[] fileLocations){
 | 
					    public void setFilesFromList(String[] fileLocations){
 | 
				
			||||||
        cleanList();
 | 
					        cleanList();
 | 
				
			||||||
        if (fileLocations != null && fileLocations.length != 0) {
 | 
					
 | 
				
			||||||
 | 
					        if (fileLocations == null || fileLocations.length == 0)
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        File[] files = new File[fileLocations.length];
 | 
					        File[] files = new File[fileLocations.length];
 | 
				
			||||||
            for (int i=0; i < fileLocations.length; i++)
 | 
					        for (int i = 0; i < fileLocations.length; i++)
 | 
				
			||||||
            files[i] = new File(fileLocations[i]);
 | 
					            files[i] = new File(fileLocations[i]);
 | 
				
			||||||
        displayFiles(files);
 | 
					        displayFiles(files);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void displayFiles(File[] files){
 | 
					    private void displayFiles(File[] files){
 | 
				
			||||||
        if (files != null && files.length > 0) {
 | 
					        if (files == null || files.length == 0)
 | 
				
			||||||
            // spiced java magic
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Arrays.sort(files);
 | 
					        Arrays.sort(files);
 | 
				
			||||||
        // Remember the folder used for MKV and reuse it when user opens MKA/subs folder (as new default path instead of user.home)
 | 
					        // Remember the folder used for MKV and reuse it when user opens MKA/subs folder (as new default path instead of user.home)
 | 
				
			||||||
        folderToOpen = files[0].getParent();
 | 
					        folderToOpen = files[0].getParent();
 | 
				
			||||||
            //System.out.println(folderToOpen);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        paneFileList.addAll(files);
 | 
					        paneFileList.addAll(files);
 | 
				
			||||||
        paneListView.setItems(paneFileList);
 | 
					        paneListView.setItems(paneFileList);
 | 
				
			||||||
        paneListView.getSelectionModel().select(0);
 | 
					        paneListView.getSelectionModel().select(0);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            System.out.println("\tNo files in this folder");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    public void cleanList(){
 | 
					    public void cleanList(){
 | 
				
			||||||
        paneListView.getItems().clear(); // wipe elements from ListView
 | 
					        paneListView.getItems().clear();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private void Up(){
 | 
					    private void up(){
 | 
				
			||||||
        int index;
 | 
					        int index = paneListView.getSelectionModel().getSelectedIndex();
 | 
				
			||||||
        index = paneListView.getSelectionModel().getSelectedIndex();
 | 
					        if (index > 0){
 | 
				
			||||||
        if (index >0){
 | 
					            paneFileList.add(index - 1, paneListView.getSelectionModel().getSelectedItem());
 | 
				
			||||||
            paneFileList.add(index-1, paneListView.getSelectionModel().getSelectedItem());
 | 
					            paneFileList.remove(index + 1);
 | 
				
			||||||
            paneFileList.remove(index+1);
 | 
					            paneListView.getSelectionModel().select(index - 1);
 | 
				
			||||||
            paneListView.getSelectionModel().select(index-1);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private void Down(){
 | 
					    private void down(){
 | 
				
			||||||
        int index;
 | 
					        int index = paneListView.getSelectionModel().getSelectedIndex();
 | 
				
			||||||
        index = paneListView.getSelectionModel().getSelectedIndex();
 | 
					        if (index + 1 < paneFileList.size() ){
 | 
				
			||||||
        if (index+1 < paneFileList.size() ){
 | 
					            paneFileList.add(index + 2, paneListView.getSelectionModel().getSelectedItem());
 | 
				
			||||||
            paneFileList.add(index+2, paneListView.getSelectionModel().getSelectedItem());
 | 
					 | 
				
			||||||
            paneFileList.remove(index);
 | 
					            paneFileList.remove(index);
 | 
				
			||||||
            paneListView.getSelectionModel().select(index+1);
 | 
					            paneListView.getSelectionModel().select(index + 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private void Del(){ paneFileList.remove(paneListView.getSelectionModel().getSelectedItem()); }
 | 
					    private void delete(){
 | 
				
			||||||
 | 
					        paneFileList.remove(paneListView.getSelectionModel().getSelectedItem());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private void KeyPressed(KeyEvent event){
 | 
					    private void keyPressed(KeyEvent event){
 | 
				
			||||||
        if (event.getCode().toString().equals("DELETE"))
 | 
					        if (event.getCode().toString().equals("DELETE"))
 | 
				
			||||||
            Del();
 | 
					            delete();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ReadOnlyIntegerProperty getSelectedIndexProperty(){
 | 
				
			||||||
 | 
					        return paneListView.getSelectionModel().selectedIndexProperty();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    Copyright 2018-2021 Dmitry Isaenko
 | 
					    Copyright 2018-2023 Dmitry Isaenko
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This file is part of mplayer4anime.
 | 
					    This file is part of mplayer4anime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ public class SettingsController implements Initializable {
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private Label pathToMplayerLbl;
 | 
					    private Label pathToMplayerLbl;
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private CheckBox subtitlesFirstCheckBox;
 | 
					    private CheckBox subtitlesFirstCheckBox, openLatestPlaylistCheckBox;
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private ChoiceBox<String> backEndEngineChoiceBox;
 | 
					    private ChoiceBox<String> backEndEngineChoiceBox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,6 +59,7 @@ public class SettingsController implements Initializable {
 | 
				
			||||||
        audioExtensionListController.setList(appPreferences.getAudioExtensionsList(), true);
 | 
					        audioExtensionListController.setList(appPreferences.getAudioExtensionsList(), true);
 | 
				
			||||||
        backEndEngineChoiceBox.getItems().addAll("mplayer", "mpv");
 | 
					        backEndEngineChoiceBox.getItems().addAll("mplayer", "mpv");
 | 
				
			||||||
        backEndEngineChoiceBox.getSelectionModel().select(appPreferences.getBackendEngineIndexId());
 | 
					        backEndEngineChoiceBox.getSelectionModel().select(appPreferences.getBackendEngineIndexId());
 | 
				
			||||||
 | 
					        openLatestPlaylistCheckBox.setSelected(appPreferences.getOpenLatestPlaylistOnStart());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
| 
						 | 
					@ -67,18 +68,14 @@ public class SettingsController implements Initializable {
 | 
				
			||||||
        fileChooser.setTitle("mplayer");
 | 
					        fileChooser.setTitle("mplayer");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // In case we use Windows, limit selectable file to .exe
 | 
					        // In case we use Windows, limit selectable file to .exe
 | 
				
			||||||
        if (System.getProperty("os.name").contains("Windows")) {
 | 
					        if (System.getProperty("os.name").contains("Windows"))
 | 
				
			||||||
            fileChooser.getExtensionFilters().setAll(
 | 
					            fileChooser.getExtensionFilters().setAll(new FileChooser.ExtensionFilter("mplayer", "*.exe"));
 | 
				
			||||||
                    new FileChooser.ExtensionFilter("mplayer", "*.exe")
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        File mplayerExecutableFile = fileChooser.showOpenDialog(null);
 | 
					        File mplayerExecutableFile = fileChooser.showOpenDialog(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (mplayerExecutableFile != null) {
 | 
					        if (mplayerExecutableFile != null)
 | 
				
			||||||
            pathToMplayerLbl.setText(mplayerExecutableFile.toString());
 | 
					            pathToMplayerLbl.setText(mplayerExecutableFile.toString());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @FXML
 | 
					    @FXML
 | 
				
			||||||
    private void clearPath(){
 | 
					    private void clearPath(){
 | 
				
			||||||
| 
						 | 
					@ -108,6 +105,7 @@ public class SettingsController implements Initializable {
 | 
				
			||||||
        appPreferences.setVideoExtensionsList(videoExtensionListController.getList());
 | 
					        appPreferences.setVideoExtensionsList(videoExtensionListController.getList());
 | 
				
			||||||
        appPreferences.setAudioExtensionsList(audioExtensionListController.getList());
 | 
					        appPreferences.setAudioExtensionsList(audioExtensionListController.getList());
 | 
				
			||||||
        appPreferences.setBackendEngineIndexId(backEndEngineChoiceBox.getSelectionModel().getSelectedIndex());
 | 
					        appPreferences.setBackendEngineIndexId(backEndEngineChoiceBox.getSelectionModel().getSelectedIndex());
 | 
				
			||||||
 | 
					        appPreferences.setOpenLatestPlaylistOnStart(openLatestPlaylistCheckBox.isSelected());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MediatorControl.getInstance().updateAfterSettingsChanged();    // TODO: implement list to track what should be updated
 | 
					        MediatorControl.getInstance().updateAfterSettingsChanged();    // TODO: implement list to track what should be updated
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,26 +10,26 @@
 | 
				
			||||||
<?import javafx.scene.layout.Pane?>
 | 
					<?import javafx.scene.layout.Pane?>
 | 
				
			||||||
<?import javafx.scene.shape.SVGPath?>
 | 
					<?import javafx.scene.shape.SVGPath?>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<AnchorPane xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mplayer4anime.ui.landing.PlayerToolbarController">
 | 
					<AnchorPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mplayer4anime.ui.landing.PlayerToolbarController">
 | 
				
			||||||
    <ToolBar styleClass="topToolBar" stylesheets="@res/landing.css" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
 | 
					    <ToolBar styleClass="topToolBar" stylesheets="@res/landing.css" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
 | 
				
			||||||
        <items>
 | 
					        <items>
 | 
				
			||||||
            <HBox>
 | 
					            <HBox>
 | 
				
			||||||
                <children>
 | 
					                <children>
 | 
				
			||||||
                    <Button minHeight="28.0" mnemonicParsing="false" onAction="#playPrevTrackBtn" styleClass="btnLeft" stylesheets="@res/landing.css">
 | 
					                    <Button fx:id="playPrevTrackBtn" minHeight="28.0" mnemonicParsing="false" styleClass="btnLeft" stylesheets="@res/landing.css">
 | 
				
			||||||
                        <graphic>
 | 
					                        <graphic>
 | 
				
			||||||
                            <SVGPath content="M 12,12 3.5,6 12,0 Z M 0,0 V 12 H 2 V 0 Z" fill="#e1e1e1" />
 | 
					                            <SVGPath content="M 12,12 3.5,6 12,0 Z M 0,0 V 12 H 2 V 0 Z" fill="#e1e1e1" />
 | 
				
			||||||
                        </graphic></Button>
 | 
					                        </graphic></Button>
 | 
				
			||||||
                    <Button minHeight="28.0" minWidth="53.0" mnemonicParsing="false" onAction="#playBtn" styleClass="btnCenter" stylesheets="@res/landing.css" textAlignment="CENTER">
 | 
					                    <Button fx:id="playBtn" minHeight="28.0" minWidth="53.0" mnemonicParsing="false" styleClass="btnCenter" stylesheets="@res/landing.css" textAlignment="CENTER">
 | 
				
			||||||
                        <graphic>
 | 
					                        <graphic>
 | 
				
			||||||
                            <SVGPath content="M3,5V19L11,12M13,19H16V5H13M18,5V19H21V5" fill="#61dd4e" />
 | 
					                            <SVGPath content="M3,5V19L11,12M13,19H16V5H13M18,5V19H21V5" fill="#61dd4e" />
 | 
				
			||||||
                        </graphic>
 | 
					                        </graphic>
 | 
				
			||||||
                    </Button>
 | 
					                    </Button>
 | 
				
			||||||
                    <Button minHeight="28.0" mnemonicParsing="false" onAction="#stopBtn" styleClass="btnCenter" stylesheets="@res/landing.css">
 | 
					                    <Button fx:id="stopBtn" minHeight="28.0" mnemonicParsing="false" styleClass="btnCenter" stylesheets="@res/landing.css">
 | 
				
			||||||
                        <graphic>
 | 
					                        <graphic>
 | 
				
			||||||
                            <SVGPath content="M18,18H6V6H18V18Z" fill="#e1e1e1" />
 | 
					                            <SVGPath content="M18,18H6V6H18V18Z" fill="#e1e1e1" />
 | 
				
			||||||
                        </graphic>
 | 
					                        </graphic>
 | 
				
			||||||
                    </Button>
 | 
					                    </Button>
 | 
				
			||||||
                    <Button minHeight="28.0" mnemonicParsing="false" onAction="#playNextTrackBtn" styleClass="btnRight" stylesheets="@res/landing.css">
 | 
					                    <Button fx:id="playNextTrackBtn" minHeight="28.0" mnemonicParsing="false" styleClass="btnRight" stylesheets="@res/landing.css">
 | 
				
			||||||
                        <graphic>
 | 
					                        <graphic>
 | 
				
			||||||
                            <SVGPath content="M0,12 L8.5,6 L0,0 L0,12 L0,12 Z M10,0 L10,12 L12,12 L12,0 L10,0 L10,0 Z" fill="#e1e1e1" />
 | 
					                            <SVGPath content="M0,12 L8.5,6 L0,0 L0,12 L0,12 Z M10,0 L10,12 L12,12 L12,0 L10,0 L10,0 Z" fill="#e1e1e1" />
 | 
				
			||||||
                        </graphic></Button>
 | 
					                        </graphic></Button>
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@
 | 
				
			||||||
            <Pane minWidth="20.0" />
 | 
					            <Pane minWidth="20.0" />
 | 
				
			||||||
            <HBox>
 | 
					            <HBox>
 | 
				
			||||||
                <children>
 | 
					                <children>
 | 
				
			||||||
                    <Button minHeight="28.0" minWidth="36.0" mnemonicParsing="false" onAction="#volumeDownBtn" styleClass="btnLeft" stylesheets="@res/landing.css">
 | 
					                    <Button fx:id="volumeDownBtn" minHeight="28.0" minWidth="36.0" mnemonicParsing="false" styleClass="btnLeft" stylesheets="@res/landing.css">
 | 
				
			||||||
                        <opaqueInsets>
 | 
					                        <opaqueInsets>
 | 
				
			||||||
                            <Insets />
 | 
					                            <Insets />
 | 
				
			||||||
                        </opaqueInsets>
 | 
					                        </opaqueInsets>
 | 
				
			||||||
| 
						 | 
					@ -49,20 +49,20 @@
 | 
				
			||||||
                            <SVGPath content="M13.5,8 C13.5,6.2 12.5,4.7 11,4 L11,12 C12.5,11.3 13.5,9.8 13.5,8 L13.5,8 Z M0,5 L0,11 L4,11 L9,16 L9,0 L4,5 L0,5 L0,5 Z" fill="#e1e1e1" />
 | 
					                            <SVGPath content="M13.5,8 C13.5,6.2 12.5,4.7 11,4 L11,12 C12.5,11.3 13.5,9.8 13.5,8 L13.5,8 Z M0,5 L0,11 L4,11 L9,16 L9,0 L4,5 L0,5 L0,5 Z" fill="#e1e1e1" />
 | 
				
			||||||
                        </graphic>
 | 
					                        </graphic>
 | 
				
			||||||
                    </Button>
 | 
					                    </Button>
 | 
				
			||||||
                    <Button minHeight="28.0" minWidth="36.0" mnemonicParsing="false" onAction="#volumeUpBtn" styleClass="btnRight" stylesheets="@res/landing.css">
 | 
					                    <Button fx:id="volumeUpBtn" minHeight="28.0" minWidth="36.0" mnemonicParsing="false" styleClass="btnRight" stylesheets="@res/landing.css">
 | 
				
			||||||
                        <graphic>
 | 
					                        <graphic>
 | 
				
			||||||
                            <SVGPath content="M0,6 L0,12 L4,12 L9,17 L9,1 L4,6 L0,6 L0,6 Z M13.5,9 C13.5,7.2 12.5,5.7 11,5 L11,13 C12.5,12.3 13.5,10.8 13.5,9 L13.5,9 Z M11,0.2 L11,2.3 C13.9,3.2 16,5.8 16,9 C16,12.2 13.9,14.8 11,15.7 L11,17.8 C15,16.9 18,13.3 18,9 C18,4.7 15,1.1 11,0.2 L11,0.2 Z" fill="#e1e1e1" />
 | 
					                            <SVGPath content="M0,6 L0,12 L4,12 L9,17 L9,1 L4,6 L0,6 L0,6 Z M13.5,9 C13.5,7.2 12.5,5.7 11,5 L11,13 C12.5,12.3 13.5,10.8 13.5,9 L13.5,9 Z M11,0.2 L11,2.3 C13.9,3.2 16,5.8 16,9 C16,12.2 13.9,14.8 11,15.7 L11,17.8 C15,16.9 18,13.3 18,9 C18,4.7 15,1.1 11,0.2 L11,0.2 Z" fill="#e1e1e1" />
 | 
				
			||||||
                        </graphic>
 | 
					                        </graphic>
 | 
				
			||||||
                    </Button>
 | 
					                    </Button>
 | 
				
			||||||
                </children>
 | 
					                </children>
 | 
				
			||||||
            </HBox>
 | 
					            </HBox>
 | 
				
			||||||
            <Button minHeight="28.0" mnemonicParsing="false" onAction="#muteBtn" styleClass="btnSimple" stylesheets="@res/landing.css">
 | 
					            <Button fx:id="muteBtn" minHeight="28.0" mnemonicParsing="false" styleClass="btnSimple" stylesheets="@res/landing.css">
 | 
				
			||||||
                <graphic>
 | 
					                <graphic>
 | 
				
			||||||
                    <SVGPath content="M3,9H7L12,4V20L7,15H3V9M16.59,12L14,9.41L15.41,8L18,10.59L20.59,8L22,9.41L19.41,12L22,14.59L20.59,16L18,13.41L15.41,16L14,14.59L16.59,12Z" fill="#e1e1e1" />
 | 
					                    <SVGPath content="M3,9H7L12,4V20L7,15H3V9M16.59,12L14,9.41L15.41,8L18,10.59L20.59,8L22,9.41L19.41,12L22,14.59L20.59,16L18,13.41L15.41,16L14,14.59L16.59,12Z" fill="#e1e1e1" />
 | 
				
			||||||
                </graphic>
 | 
					                </graphic>
 | 
				
			||||||
            </Button>
 | 
					            </Button>
 | 
				
			||||||
            <Pane HBox.hgrow="ALWAYS" />
 | 
					            <Pane HBox.hgrow="ALWAYS" />
 | 
				
			||||||
            <SplitMenuButton mnemonicParsing="false" onAction="#subsTriggerBtn" styleClass="splitMenuButton" stylesheets="@res/landing.css">
 | 
					            <SplitMenuButton fx:id="subsTriggerBtn" mnemonicParsing="false" styleClass="splitMenuButton" stylesheets="@res/landing.css">
 | 
				
			||||||
                <graphic>
 | 
					                <graphic>
 | 
				
			||||||
                    <SVGPath content="M 4,18 C 2.8954305,18 2,17.104569 2,16 V 4 C 2,2.89 2.9,2 4,2 h 16 c 1.104569,0 2,0.8954305 2,2 v 12 c 0,1.104569 -0.895431,2 -2,2 m -6,-7 v 1 h 5 V 11 M 5,12 h 8 V 11 H 5 m 0,3 v 1 h 14 v -1 z" fill="#e1e1e1" />
 | 
					                    <SVGPath content="M 4,18 C 2.8954305,18 2,17.104569 2,16 V 4 C 2,2.89 2.9,2 4,2 h 16 c 1.104569,0 2,0.8954305 2,2 v 12 c 0,1.104569 -0.895431,2 -2,2 m -6,-7 v 1 h 5 V 11 M 5,12 h 8 V 11 H 5 m 0,3 v 1 h 14 v -1 z" fill="#e1e1e1" />
 | 
				
			||||||
                </graphic>
 | 
					                </graphic>
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,7 @@
 | 
				
			||||||
                    <CheckMenuItem fx:id="subsHide" mnemonicParsing="false" text="%subsShow_option" />
 | 
					                    <CheckMenuItem fx:id="subsHide" mnemonicParsing="false" text="%subsShow_option" />
 | 
				
			||||||
                </items>
 | 
					                </items>
 | 
				
			||||||
            </SplitMenuButton>
 | 
					            </SplitMenuButton>
 | 
				
			||||||
            <SplitMenuButton mnemonicParsing="false" onAction="#fullscreenBtn" styleClass="splitMenuButton" stylesheets="@res/landing.css">
 | 
					            <SplitMenuButton fx:id="fullscreenBtn" mnemonicParsing="false" styleClass="splitMenuButton" stylesheets="@res/landing.css">
 | 
				
			||||||
                <items>
 | 
					                <items>
 | 
				
			||||||
                    <CheckMenuItem fx:id="fullScreen" mnemonicParsing="false" text="%fullscreen_option" />
 | 
					                    <CheckMenuItem fx:id="fullScreen" mnemonicParsing="false" text="%fullscreen_option" />
 | 
				
			||||||
                </items>
 | 
					                </items>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@
 | 
				
			||||||
<?import javafx.scene.shape.SVGPath?>
 | 
					<?import javafx.scene.shape.SVGPath?>
 | 
				
			||||||
<?import javafx.scene.text.Font?>
 | 
					<?import javafx.scene.text.Font?>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<VBox xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mplayer4anime.ui.settings.SettingsController">
 | 
					<VBox xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mplayer4anime.ui.settings.SettingsController">
 | 
				
			||||||
   <children>
 | 
					   <children>
 | 
				
			||||||
      <TabPane side="LEFT" styleClass="tab-paneSettings" stylesheets="@../res/landing.css" tabClosingPolicy="UNAVAILABLE" tabMaxHeight="100.0" tabMaxWidth="500.0" tabMinHeight="100.0" tabMinWidth="80.0" VBox.vgrow="ALWAYS">
 | 
					      <TabPane side="LEFT" styleClass="tab-paneSettings" stylesheets="@../res/landing.css" tabClosingPolicy="UNAVAILABLE" tabMaxHeight="100.0" tabMaxWidth="500.0" tabMinHeight="100.0" tabMinWidth="80.0" VBox.vgrow="ALWAYS">
 | 
				
			||||||
         <tabs>
 | 
					         <tabs>
 | 
				
			||||||
| 
						 | 
					@ -49,11 +49,8 @@
 | 
				
			||||||
                              <ChoiceBox fx:id="backEndEngineChoiceBox" prefWidth="150.0" />
 | 
					                              <ChoiceBox fx:id="backEndEngineChoiceBox" prefWidth="150.0" />
 | 
				
			||||||
                           </children>
 | 
					                           </children>
 | 
				
			||||||
                        </HBox>
 | 
					                        </HBox>
 | 
				
			||||||
                        <HBox alignment="CENTER_LEFT" VBox.vgrow="NEVER">
 | 
					 | 
				
			||||||
                           <children>
 | 
					 | 
				
			||||||
                        <CheckBox fx:id="subtitlesFirstCheckBox" mnemonicParsing="false" text="%settings_SubtitlesTabFirst" />
 | 
					                        <CheckBox fx:id="subtitlesFirstCheckBox" mnemonicParsing="false" text="%settings_SubtitlesTabFirst" />
 | 
				
			||||||
                           </children>
 | 
					                        <CheckBox fx:id="openLatestPlaylistCheckBox" mnemonicParsing="false" text="%settings_OpenLatestOnStart" />
 | 
				
			||||||
                        </HBox>
 | 
					 | 
				
			||||||
                     </children>
 | 
					                     </children>
 | 
				
			||||||
                     <padding>
 | 
					                     <padding>
 | 
				
			||||||
                        <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
					                        <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,17 +34,17 @@
 | 
				
			||||||
                  <Pane HBox.hgrow="ALWAYS" />
 | 
					                  <Pane HBox.hgrow="ALWAYS" />
 | 
				
			||||||
                  <Label fx:id="paneLbl" text="%lbl_VideoPane" />
 | 
					                  <Label fx:id="paneLbl" text="%lbl_VideoPane" />
 | 
				
			||||||
                  <Pane HBox.hgrow="ALWAYS" />
 | 
					                  <Pane HBox.hgrow="ALWAYS" />
 | 
				
			||||||
                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#Up">
 | 
					                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#up">
 | 
				
			||||||
                     <graphic>
 | 
					                     <graphic>
 | 
				
			||||||
                        <SVGPath content="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" fill="#1a1a1a" />
 | 
					                        <SVGPath content="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" fill="#1a1a1a" />
 | 
				
			||||||
                     </graphic>
 | 
					                     </graphic>
 | 
				
			||||||
                  </Button>
 | 
					                  </Button>
 | 
				
			||||||
                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#Down">
 | 
					                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#down">
 | 
				
			||||||
                     <graphic>
 | 
					                     <graphic>
 | 
				
			||||||
                        <SVGPath content="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" fill="#1a1a1a" />
 | 
					                        <SVGPath content="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" fill="#1a1a1a" />
 | 
				
			||||||
                     </graphic>
 | 
					                     </graphic>
 | 
				
			||||||
                  </Button>
 | 
					                  </Button>
 | 
				
			||||||
                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#Del">
 | 
					                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#delete">
 | 
				
			||||||
                     <graphic>
 | 
					                     <graphic>
 | 
				
			||||||
                        <SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#cc0101" />
 | 
					                        <SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#cc0101" />
 | 
				
			||||||
                     </graphic>
 | 
					                     </graphic>
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@
 | 
				
			||||||
                  <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
					                  <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
				
			||||||
               </VBox.margin>
 | 
					               </VBox.margin>
 | 
				
			||||||
            </HBox>
 | 
					            </HBox>
 | 
				
			||||||
            <ListView fx:id="paneListView" onKeyPressed="#KeyPressed" styleClass="landing" stylesheets="@../res/landing.css" VBox.vgrow="ALWAYS" />
 | 
					            <ListView fx:id="paneListView" onKeyPressed="#keyPressed" styleClass="landing" stylesheets="@../res/landing.css" VBox.vgrow="ALWAYS" />
 | 
				
			||||||
         </children>
 | 
					         </children>
 | 
				
			||||||
      </VBox>
 | 
					      </VBox>
 | 
				
			||||||
   </children>
 | 
					   </children>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,17 +37,17 @@
 | 
				
			||||||
                  <Pane HBox.hgrow="ALWAYS" />
 | 
					                  <Pane HBox.hgrow="ALWAYS" />
 | 
				
			||||||
                  <Label fx:id="paneLbl" text="%lbl_SubsPane" />
 | 
					                  <Label fx:id="paneLbl" text="%lbl_SubsPane" />
 | 
				
			||||||
                  <Pane HBox.hgrow="ALWAYS" />
 | 
					                  <Pane HBox.hgrow="ALWAYS" />
 | 
				
			||||||
                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#Up">
 | 
					                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#up">
 | 
				
			||||||
                     <graphic>
 | 
					                     <graphic>
 | 
				
			||||||
                        <SVGPath content="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" fill="#1a1a1a" />
 | 
					                        <SVGPath content="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" fill="#1a1a1a" />
 | 
				
			||||||
                     </graphic>
 | 
					                     </graphic>
 | 
				
			||||||
                  </Button>
 | 
					                  </Button>
 | 
				
			||||||
                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#Down">
 | 
					                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#down">
 | 
				
			||||||
                     <graphic>
 | 
					                     <graphic>
 | 
				
			||||||
                        <SVGPath content="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" fill="#1a1a1a" />
 | 
					                        <SVGPath content="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" fill="#1a1a1a" />
 | 
				
			||||||
                     </graphic>
 | 
					                     </graphic>
 | 
				
			||||||
                  </Button>
 | 
					                  </Button>
 | 
				
			||||||
                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#Del">
 | 
					                  <Button minHeight="28.0" mnemonicParsing="false" onAction="#delete">
 | 
				
			||||||
                     <graphic>
 | 
					                     <graphic>
 | 
				
			||||||
                        <SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#b90505" />
 | 
					                        <SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#b90505" />
 | 
				
			||||||
                     </graphic>
 | 
					                     </graphic>
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,7 @@
 | 
				
			||||||
                  <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
					                  <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
				
			||||||
               </VBox.margin>
 | 
					               </VBox.margin>
 | 
				
			||||||
            </HBox>
 | 
					            </HBox>
 | 
				
			||||||
            <ListView fx:id="paneListView" onKeyPressed="#KeyPressed" styleClass="landing" stylesheets="@../res/landing.css" VBox.vgrow="ALWAYS" />
 | 
					            <ListView fx:id="paneListView" onKeyPressed="#keyPressed" styleClass="landing" stylesheets="@../res/landing.css" VBox.vgrow="ALWAYS" />
 | 
				
			||||||
         </children>
 | 
					         </children>
 | 
				
			||||||
      </VBox>
 | 
					      </VBox>
 | 
				
			||||||
   </children>
 | 
					   </children>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,7 @@ settings_videoExtensionList=Avaliable video files extensions:
 | 
				
			||||||
settings_audioExtensionList=Avaliable audio layer extensions:
 | 
					settings_audioExtensionList=Avaliable audio layer extensions:
 | 
				
			||||||
ApplyBtn=Apply
 | 
					ApplyBtn=Apply
 | 
				
			||||||
settings_backendSelect=Backend engine:
 | 
					settings_backendSelect=Backend engine:
 | 
				
			||||||
 | 
					settings_OpenLatestOnStart=Open latest playlist on start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,4 +54,5 @@ settings_audioExtensionList=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u04
 | 
				
			||||||
ApplyBtn=\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C
 | 
					ApplyBtn=\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C
 | 
				
			||||||
settings_backendSelect=\u0414\u0432\u0438\u0436\u043E\u043A \u0432\u043E\u0441\u043F\u0440\u043E\u0438\u0437\u0432\u0435\u0434\u0435\u043D\u0438\u044F:
 | 
					settings_backendSelect=\u0414\u0432\u0438\u0436\u043E\u043A \u0432\u043E\u0441\u043F\u0440\u043E\u0438\u0437\u0432\u0435\u0434\u0435\u043D\u0438\u044F:
 | 
				
			||||||
about_line2=\u0420\u0435\u043B\u0438\u0437: v${project.version}
 | 
					about_line2=\u0420\u0435\u043B\u0438\u0437: v${project.version}
 | 
				
			||||||
 | 
					settings_OpenLatestOnStart=\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0439 \u043F\u043B\u0435\u0439\u043B\u0438\u0441\u0442 \u043F\u0440\u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0435
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue