feature: added tutorial window

This commit is contained in:
David Guler 2022-11-23 21:55:35 +01:00
parent f7105f041c
commit bcb36b89c7
4 changed files with 215 additions and 30 deletions

View File

@ -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);
} }
} }

View File

@ -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();
}
} }

View File

@ -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>

View File

@ -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/19" 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 &quot;My Garden&quot; 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 &quot;Add new Plant&quot; button in the bottom left. This will open a list of all the plants you can grow.&#10;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 &quot;Select Sow/Harvest Date&quot; button at the bottom of the window.&#10;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 &quot;Save&quot; 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 &quot;My Schedule&quot; 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.&#10;To see all tasks again, click the &quot;Clear Filter&quot; 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 &quot;Add Task&quot; button.&#10;In the subsequently shown dialog, you can enter the corresponding details.&#10;&#10;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>