package org.phoenicis.javafx.views.mainwindow.library;
import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList;
import javafx.scene.control.ToggleButton;
import javafx.stage.FileChooser;
import org.phoenicis.javafx.views.mainwindow.ui.*;
import org.phoenicis.library.dto.ShortcutCategoryDTO;
import org.phoenicis.library.dto.ShortcutDTO;
import java.io.File;
import java.util.function.Consumer;
import static org.phoenicis.configuration.localisation.Localisation.translate;
/**
* An instance of this class represents the left sidebar of the library tab view.
* This sidebar contains three items:
* <ul>
* <li>
* A searchbar, which enables the user to search for an application inside his application library.
* </li>
* <li>
* A button group containing a run, stop and uninstall button for a selected application in the library.
* This group is only shown, if an application is currently selected.
* </li>
* <li>
* A button group containing a "Run a script" and "PlayOnLinux console" button.
* This group is always shown.
* </li>
* </ul>
*
* @author marc
* @since 15.04.17
*/
public class LibrarySideBar extends LeftSideBar {
// the name of this application
private final String applicationName;
// the search bar used for filtering
private SearchBox searchBar;
// the toggleable categories
private LeftToggleGroup<ShortcutCategoryDTO> categoryView;
// consumer called after a text has been entered in the search box
private Consumer<String> onSearch;
// the shortcut group, containing the run, stop and uninstall buttons
private LeftGroup shortcutGroup;
private LeftButton runButton;
private LeftButton stopButton;
private LeftButton uninstallButton;
// the advanced tools group, containing the run script and run console buttons
private LeftGroup advancedToolsGroup;
private LeftButton runScript;
private LeftButton runConsole;
// the current selected shortcut
private ShortcutDTO shortcut;
// consumers called after a category selection has been made
private Runnable onAllCategorySelection;
private Consumer<ShortcutCategoryDTO> onCategorySelection;
// consumers called when a shortcut should be run, stopped or uninstalled
private Consumer<ShortcutDTO> onShortcutRun;
private Consumer<ShortcutDTO> onShortcutStop;
private Consumer<ShortcutDTO> onShortcutUninstall;
// consumers called when a script should be run or a console be opened
private Consumer<File> onScriptRun;
private Runnable onOpenConsole;
/**
* Constructor
*
* @param applicationName The name of this application (normally "PlayOnLinux")
*/
public LibrarySideBar(String applicationName) {
super();
this.applicationName = applicationName;
this.populateSearchBar();
this.populateShortcut();
this.populateCategories();
this.populateAdvancedTools();
this.hideShortcut();
}
/**
* This method selects the "All" application category
*/
public void selectAllCategories() {
this.categoryView.selectAll();
}
/**
* This method sets the to be shown shortcut (including its name).
* Afterwards it updates the sidebar view to show the searchbar, the shortcut related buttons (run, stop and uninstall) and
* the advanced tool buttons (run a script and open a console).
* If a shortcut is already shown the shortcut information will be updated to reflect the new shortcut.
*
* @param shortcut The new shortcut to be shown to the user
*/
public void showShortcut(ShortcutDTO shortcut) {
this.shortcut = shortcut;
this.shortcutGroup.setTitle(shortcut.getName());
this.getChildren().setAll(this.searchBar, new LeftSpacer(), this.categoryView, this.shortcutGroup,
new LeftSpacer(), this.advancedToolsGroup);
}
/**
* This method hides the currently shown shortcut.
* If no shortcut is currently shown, this method does nothing.
*/
public void hideShortcut() {
this.shortcut = null;
this.getChildren().setAll(this.searchBar, new LeftSpacer(), this.categoryView, this.advancedToolsGroup);
}
/**
* This method binds the given category list <code>categories</code> to the categories toggle group.
*
* @param categories The to be bound category list
*/
public void bindCategories(ObservableList<ShortcutCategoryDTO> categories) {
Bindings.bindContent(categoryView.getElements(), categories);
}
/**
* This method populates the searchbar
*/
private void populateSearchBar() {
this.searchBar = new SearchBox(onSearch, () -> {
});
}
private void populateCategories() {
this.categoryView = LeftToggleGroup.create(translate("Categories"), this::createAllCategoriesToggleButton,
this::createCategoryToggleButton);
}
/**
* This method is responsible for creating the "All" categories toggle button.
*
* @return The newly created "All" categories toggle button
*/
private ToggleButton createAllCategoriesToggleButton() {
final LeftToggleButton allCategoryButton = new LeftToggleButton("All");
allCategoryButton.setSelected(true);
allCategoryButton.setId("allButton");
allCategoryButton.setOnMouseClicked(event -> onAllCategorySelection.run());
return allCategoryButton;
}
/**
* This method is responsible for creating a toggle button for a given category.
*
* @param category The category for which a toggle button should be created
* @return The newly created toggle button
*/
private ToggleButton createCategoryToggleButton(ShortcutCategoryDTO category) {
final LeftToggleButton categoryButton = new LeftToggleButton(category.getName());
categoryButton.setId(String.format("%sButton", category.getName().toLowerCase()));
categoryButton.setOnMouseClicked(event -> onCategorySelection.accept(category));
return categoryButton;
}
/**
* This method populates the shortcut button group.
*/
private void populateShortcut() {
this.runButton = new LeftButton(translate("Run"));
this.runButton.getStyleClass().add("runButton");
this.stopButton = new LeftButton(translate("Close"));
this.stopButton.getStyleClass().add("stopButton");
this.uninstallButton = new LeftButton(translate("Uninstall"));
this.uninstallButton.getStyleClass().add("uninstallButton");
this.runButton.setOnMouseClicked(event -> onShortcutRun.accept(shortcut));
this.stopButton.setOnMouseClicked(event -> onShortcutStop.accept(shortcut));
this.uninstallButton.setOnMouseClicked(event -> {
onShortcutUninstall.accept(shortcut);
hideShortcut();
});
this.shortcutGroup = new LeftGroup("Unknown application", runButton, stopButton, uninstallButton);
}
/**
* This method populates the advanced tools button group.
*/
private void populateAdvancedTools() {
this.runScript = new LeftButton(translate("Run a script"));
this.runScript.getStyleClass().add("scriptButton");
this.runConsole = new LeftButton(translate(String.format("%s console", applicationName)));
this.runConsole.getStyleClass().add("consoleButton");
this.runScript.setOnMouseClicked(event -> {
final FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open a script");
// TODO: use correct owner window
final File scriptToRun = fileChooser.showOpenDialog(null);
if (scriptToRun != null) {
onScriptRun.accept(scriptToRun);
}
});
this.runConsole.setOnMouseClicked(event -> onOpenConsole.run());
this.advancedToolsGroup = new LeftGroup("Advanced tools", runScript, runConsole);
}
/**
* This method updates the consumer, that is called when a search term has been entered.
*
* @param onSearch The new consumer to be called
*/
public void setOnSearch(Consumer<String> onSearch) {
this.onSearch = onSearch;
}
/**
* This method sets the consumer, that is called after a category has been selected
*
* @param onAllCategorySelection The new consumer to be used
*/
public void setOnAllCategorySelection(Runnable onAllCategorySelection) {
this.onAllCategorySelection = onAllCategorySelection;
}
/**
* This method sets the consumer, that is called after the "All" categories toggle button has been selected
*
* @param onCategorySelection The new consumer to be used
*/
public void setOnCategorySelection(Consumer<ShortcutCategoryDTO> onCategorySelection) {
this.onCategorySelection = onCategorySelection;
}
/**
* This method updates the consumer, that is called when the "Run" button for the currently selected shortcut has been clicked.
*
* @param onShortcutRun The new consumer to be called
*/
public void setOnShortcutRun(Consumer<ShortcutDTO> onShortcutRun) {
this.onShortcutRun = onShortcutRun;
}
/**
* This method updates the consumer, that is called when the "Stop" button for the currently selected shortcut has been clicked.
*
* @param onShortcutStop The new consumer to be called
*/
public void setOnShortcutStop(Consumer<ShortcutDTO> onShortcutStop) {
this.onShortcutStop = onShortcutStop;
}
/**
* This method updates the consumer, that is called when the "Uninstall" button for the currently selected shortcut has been clicked.
*
* @param onShortcutUninstall The new consumer to be called
*/
public void setOnShortcutUninstall(Consumer<ShortcutDTO> onShortcutUninstall) {
this.onShortcutUninstall = onShortcutUninstall;
}
/**
* This method updates the consumer, that is called when the "Run a script" button in the advanced tools section has been clicked.
*
* @param onScriptRun The new consumer to be called
*/
public void setOnScriptRun(Consumer<File> onScriptRun) {
this.onScriptRun = onScriptRun;
}
/**
* This methdo updates the consumer that is called when the "PlayOnLinux console" button ins the advanced tools section has been clicked.
*
* @param onOpenConsole The new consumer to be called
*/
public void setOnOpenConsole(Runnable onOpenConsole) {
this.onOpenConsole = onOpenConsole;
}
}