Merge pull request #69 from schrom01/feature_tutorial_M3
feature: added tutorial window
This commit is contained in:
commit
04e4ea1dea
|
@ -11,6 +11,9 @@ import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
|
import javafx.stage.Modality;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.WindowEvent;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
@ -40,6 +43,9 @@ public class MainFXMLController {
|
||||||
@FXML
|
@FXML
|
||||||
private Button tutorial_button;
|
private Button tutorial_button;
|
||||||
|
|
||||||
|
private final Stage tutorialModal = new Stage();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* go to home pane
|
* go to home pane
|
||||||
*/
|
*/
|
||||||
|
@ -95,11 +101,23 @@ public class MainFXMLController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* go to Tutorial pane
|
* Show the tutorial window
|
||||||
*/
|
*/
|
||||||
public void goToTutorial() {
|
public void showTutorial() {
|
||||||
showPaneAsMainView("Tutorial.fxml");
|
if (!tutorialModal.isShowing()) {
|
||||||
styleChangeButton(tutorial_button);
|
if (tutorialModal.getScene() == null) {
|
||||||
|
try {
|
||||||
|
appLoader.loadSceneToStage("Tutorial.fxml", tutorialModal);
|
||||||
|
tutorialModal.initModality(Modality.NONE);
|
||||||
|
tutorialModal.setResizable(false);
|
||||||
|
tutorialModal.sizeToScene();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.log(Level.SEVERE, "Could not load Tutorial");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tutorialModal.show();
|
||||||
|
}
|
||||||
|
tutorialModal.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,7 +150,6 @@ public class MainFXMLController {
|
||||||
appLoader.loadAndCacheFxml("MyGarden.fxml");
|
appLoader.loadAndCacheFxml("MyGarden.fxml");
|
||||||
appLoader.loadAndCacheFxml("MySchedule.fxml");
|
appLoader.loadAndCacheFxml("MySchedule.fxml");
|
||||||
appLoader.loadAndCacheFxml("Plants.fxml");
|
appLoader.loadAndCacheFxml("Plants.fxml");
|
||||||
appLoader.loadAndCacheFxml("Tutorial.fxml");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void styleChangeButton(Button button) {
|
private void styleChangeButton(Button button) {
|
||||||
|
@ -153,12 +170,14 @@ public class MainFXMLController {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.log(Level.SEVERE, "Failed to load FXML-Pane!", e);
|
LOG.log(Level.SEVERE, "Failed to load FXML-Pane!", e);
|
||||||
}
|
}
|
||||||
|
mainPane.getScene().getWindow().setOnCloseRequest(this::closeWindowHandler);
|
||||||
setIconToButton(home_button, "homeIcon.png");
|
setIconToButton(home_button, "homeIcon.png");
|
||||||
setIconToButton(settings_button, "settingsIcon.png");
|
setIconToButton(settings_button, "settingsIcon.png");
|
||||||
Settings.getInstance().getShowTutorialProperty().addListener((observable, oldValue, newValue) -> {
|
tutorial_button.visibleProperty().bind(Settings.getInstance().getShowTutorialProperty());
|
||||||
tutorial_button.setVisible(newValue);
|
}
|
||||||
});
|
|
||||||
tutorial_button.setVisible(Settings.getInstance().getShowTutorial());
|
private void closeWindowHandler(WindowEvent windowEvent) {
|
||||||
|
tutorialModal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,7 +192,4 @@ public class MainFXMLController {
|
||||||
imageView.setPreserveRatio(true);
|
imageView.setPreserveRatio(true);
|
||||||
button.setGraphic(imageView);
|
button.setGraphic(imageView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,61 @@
|
||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
|
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.layout.StackPane;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
public class TutorialController {
|
public class TutorialController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public Button previousPageButton;
|
||||||
|
@FXML
|
||||||
|
public Button nextPageButton;
|
||||||
|
@FXML
|
||||||
|
public StackPane tourPages;
|
||||||
|
public ImageView imgAddNewPlant;
|
||||||
|
public ImageView imgTaskList;
|
||||||
|
public ImageView imgSelectDate;
|
||||||
|
|
||||||
|
private int page = 0;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
switchViews();
|
||||||
|
setButtonAbilities();
|
||||||
|
|
||||||
|
Image placeholder = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
|
||||||
|
imgAddNewPlant.setImage(placeholder);
|
||||||
|
imgSelectDate.setImage(placeholder);
|
||||||
|
imgTaskList.setImage(placeholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void viewNextPage() {
|
||||||
|
page++;
|
||||||
|
switchViews();
|
||||||
|
setButtonAbilities();
|
||||||
|
}
|
||||||
|
public void viewPreviousPage() {
|
||||||
|
page--;
|
||||||
|
switchViews();
|
||||||
|
setButtonAbilities();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setButtonAbilities() {
|
||||||
|
previousPageButton.setDisable(page <= 0);
|
||||||
|
nextPageButton.setDisable(page >= tourPages.getChildren().size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchViews() {
|
||||||
|
tourPages.getChildren().forEach(node -> node.setOpacity(0));
|
||||||
|
tourPages.getChildren().get(page).setOpacity(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeTutorial() {
|
||||||
|
Stage root = (Stage) tourPages.getScene().getWindow();
|
||||||
|
root.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<Button fx:id="home_button" mnemonicParsing="false" onAction="#goToHome" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
<Button fx:id="home_button" mnemonicParsing="false" onAction="#goToHome" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
||||||
<Button fx:id="myGarden_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMyPlants" prefHeight="38.0" prefWidth="121.0" text="My Garden" />
|
<Button fx:id="myGarden_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMyPlants" prefHeight="38.0" prefWidth="121.0" text="My Garden" />
|
||||||
<Button fx:id="mySchedule_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMySchedule" prefHeight="38.0" prefWidth="121.0" text="My Schedule" />
|
<Button fx:id="mySchedule_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMySchedule" prefHeight="38.0" prefWidth="121.0" text="My Schedule" />
|
||||||
<Button fx:id="tutorial_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToTutorial" prefHeight="38.0" prefWidth="121.0" text="Tutorial" />
|
<Button fx:id="tutorial_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#showTutorial" prefHeight="38.0" prefWidth="121.0" text="Tutorial" />
|
||||||
<Pane maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
|
<Pane maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
|
||||||
<Button fx:id="settings_button" maxHeight="1.7976931348623157E308" mnemonicParsing="false" onAction="#openSettings" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
<Button fx:id="settings_button" maxHeight="1.7976931348623157E308" mnemonicParsing="false" onAction="#openSettings" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
||||||
</children>
|
</children>
|
||||||
|
|
|
@ -1,27 +1,141 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.layout.AnchorPane?>
|
<?import javafx.scene.control.ButtonBar?>
|
||||||
|
<?import javafx.scene.control.CheckBox?>
|
||||||
|
<?import javafx.scene.control.Separator?>
|
||||||
|
<?import javafx.scene.image.ImageView?>
|
||||||
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
|
<?import javafx.scene.text.Text?>
|
||||||
|
<?import javafx.scene.text.TextFlow?>
|
||||||
|
|
||||||
|
<BorderPane maxHeight="470.0" maxWidth="724.0" minHeight="470.0" minWidth="724.0" prefHeight="470.0" prefWidth="724.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.TutorialController">
|
||||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/17"
|
<bottom>
|
||||||
xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.TutorialController">
|
<HBox alignment="CENTER" prefHeight="0.0" prefWidth="724.0" BorderPane.alignment="CENTER">
|
||||||
<children>
|
<children>
|
||||||
<VBox layoutX="7.0" layoutY="8.0" prefHeight="200.0" prefWidth="100.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<CheckBox mnemonicParsing="false" text="Don't show again" />
|
||||||
<children>
|
<Separator prefWidth="50.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
<Label text="Tutorial">
|
<ButtonBar prefHeight="40.0" prefWidth="200.0">
|
||||||
<font>
|
<buttons>
|
||||||
<Font size="18.0" />
|
<Button cancelButton="true" contentDisplay="CENTER" graphicTextGap="5.0" mnemonicParsing="false" text="Close" onAction="#closeTutorial"/>
|
||||||
</font>
|
<Button fx:id="previousPageButton" mnemonicParsing="false" text="Previous" onAction="#viewPreviousPage"/>
|
||||||
</Label>
|
<Button fx:id="nextPageButton" defaultButton="true" mnemonicParsing="false" text="Next" onAction="#viewNextPage" />
|
||||||
<Label text="To be added" />
|
</buttons>
|
||||||
|
</ButtonBar>
|
||||||
</children>
|
</children>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
|
||||||
</padding>
|
</padding>
|
||||||
|
</HBox>
|
||||||
|
</bottom>
|
||||||
|
<center>
|
||||||
|
<StackPane fx:id="tourPages" prefHeight="150.0" prefWidth="200.0" BorderPane.alignment="CENTER">
|
||||||
|
<children>
|
||||||
|
<VBox layoutX="30.0" layoutY="26.0" opacity="0.0" prefHeight="200.0" prefWidth="100.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Managing Your Crops">
|
||||||
|
<font>
|
||||||
|
<Font size="24.0" />
|
||||||
|
</font>
|
||||||
|
</Text>
|
||||||
|
<Separator prefWidth="200.0">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets bottom="15.0" top="10.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</Separator>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="In the "My Garden" tab, you can see all of the plants you're planning on growing.">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets bottom="20.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</Text>
|
||||||
|
<HBox prefHeight="100.0" prefWidth="200.0">
|
||||||
|
<children>
|
||||||
|
<TextFlow lineSpacing="4.0" prefHeight="90.0" prefWidth="500.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="To get started, click on the "Add new Plant" button in the bottom left. This will open a list of all the plants you can grow. Use the search bar at the top, the filters on the left, or simply browse the list until you've found a plant you want to grow in your garden." wrappingWidth="345.80316162109375" />
|
||||||
|
</children>
|
||||||
|
<HBox.margin>
|
||||||
|
<Insets bottom="20.0" />
|
||||||
|
</HBox.margin>
|
||||||
|
</TextFlow>
|
||||||
|
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
|
<ImageView fx:id="imgAddNewPlant" fitHeight="98.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<HBox prefHeight="100.0" prefWidth="200.0">
|
||||||
|
<children>
|
||||||
|
<TextFlow lineSpacing="4.0" prefHeight="200.0" prefWidth="500.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Once you've found what you're looking for, click the "Select Sow/Harvest Date" button at the bottom of the window. In the subsequently shown dialog, you can select the date you'd like to sow or harvest the crop. The date selector shows possible dates in green. Confirm your selection with the "Save" button." />
|
||||||
|
</children>
|
||||||
|
</TextFlow>
|
||||||
|
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
|
<ImageView fx:id="imgSelectDate" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
</children>
|
||||||
|
<opaqueInsets>
|
||||||
|
<Insets />
|
||||||
|
</opaqueInsets>
|
||||||
|
</VBox>
|
||||||
|
<VBox prefHeight="200.0" prefWidth="100.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Managing Your Tasks">
|
||||||
|
<font>
|
||||||
|
<Font size="24.0" />
|
||||||
|
</font>
|
||||||
|
</Text>
|
||||||
|
<Separator prefWidth="200.0">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets bottom="15.0" top="10.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</Separator>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="In the "My Schedule" tab, you can see all of the tasks you need to complete for a successful harvest.">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets bottom="20.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</Text>
|
||||||
|
<HBox prefHeight="100.0" prefWidth="200.0">
|
||||||
|
<children>
|
||||||
|
<TextFlow lineSpacing="4.0" prefHeight="90.0" prefWidth="500.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="You can view the tasks for a specific crop by selecting it from the left sidebar. To see all tasks again, click the "Clear Filter" button at the bottom." wrappingWidth="345.80316162109375" />
|
||||||
|
</children>
|
||||||
|
<HBox.margin>
|
||||||
|
<Insets bottom="20.0" />
|
||||||
|
</HBox.margin>
|
||||||
|
</TextFlow>
|
||||||
|
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
|
<ImageView fx:id="imgTaskList" fitHeight="98.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<HBox prefHeight="100.0" prefWidth="200.0">
|
||||||
|
<children>
|
||||||
|
<TextFlow lineSpacing="4.0" prefHeight="200.0" prefWidth="500.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="You can also add your own custom tasks, by clicking the "Add Task" button. In the subsequently shown dialog, you can enter the corresponding details. Note: If you want to make a task recurring, you need to set both an interval (in days) AND an end date, so the task won't repeat for all eternity." />
|
||||||
|
</children>
|
||||||
|
</TextFlow>
|
||||||
|
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
|
<ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
|
||||||
|
</children></HBox>
|
||||||
|
</children>
|
||||||
|
<opaqueInsets>
|
||||||
|
<Insets />
|
||||||
|
</opaqueInsets>
|
||||||
</VBox>
|
</VBox>
|
||||||
</children>
|
</children>
|
||||||
</AnchorPane>
|
<BorderPane.margin>
|
||||||
|
<Insets />
|
||||||
|
</BorderPane.margin>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||||
|
</padding>
|
||||||
|
</StackPane>
|
||||||
|
</center>
|
||||||
|
</BorderPane>
|
||||||
|
|
Loading…
Reference in New Issue