diff --git a/PlayWall/assets/de/tobias/playpad/assets/classic_style.css b/PlayWall/assets/de/tobias/playpad/assets/classic_style.css
new file mode 100644
index 0000000000000000000000000000000000000000..135dfc913b7279684cd5f03dbb9f6db0b76d7e63
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/classic_style.css
@@ -0,0 +1,19 @@
+.pad-grid {
+	-fx-hgap: 0px;
+	-fx-vgap: 0px;
+}
+
+.pad {
+	-fx-padding: 4px;
+	-fx-spacing: 5px;
+	-fx-background-insets: 2px;
+}
+
+.pad:drag {
+	-fx-opacity: 0.6;
+}
+
+
+.live-label {
+	-fx-text-fill: red !important;
+}
\ No newline at end of file
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/changelogDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/changelogDialog.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..24bcd24faa2503a5829fddfd981c000a6013f7a1
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/changelogDialog.fxml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import javafx.scene.web.*?>
+
+
+<WebView fx:id="contentView" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" />
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/errorSummaryDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/errorSummaryDialog.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..8f793f0dd48086a72fa6b55edb4b70f184366674
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/errorSummaryDialog.fxml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <TableView fx:id="errorTable" layoutY="38.0" prefHeight="312.0" prefWidth="600.0" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
+        <columns>
+          <TableColumn fx:id="padColumn" prefWidth="230.0" text="%errorSummary.column.cart" />
+          <TableColumn fx:id="errorColumn" prefWidth="465.0" text="%errorSummary.column.des" />
+            <TableColumn fx:id="fixColumn" prefWidth="200.0" text="%errorSummary.column.solution" />
+        </columns>
+      </TableView>
+      <Label layoutX="14.0" layoutY="14.0" text="%errorSummary.label.headline" />
+      <Button fx:id="closeButton" layoutX="587.0" layoutY="260.0" mnemonicParsing="false" onAction="#closeButtonHandler" text="%errorSummary.button.close" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" />
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/launchDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/launchDialog.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..4b68d4f98ea2ddcf32efa55f44b663c240ffdb10
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/launchDialog.fxml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.text.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.effect.*?>
+<?import javafx.scene.image.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="345.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <VBox alignment="CENTER" layoutX="24.0" layoutY="5.0" spacing="7.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="34.0" AnchorPane.topAnchor="14.0">
+         <children>
+            <ImageView fx:id="imageView" fitHeight="144.0" fitWidth="140.0" layoutX="80.0" layoutY="14.0" pickOnBounds="true" preserveRatio="true">
+               <effect>
+                  <DropShadow />
+               </effect>
+            </ImageView>
+            <Label fx:id="infoLabel" alignment="CENTER" layoutX="24.0" layoutY="212.0" prefHeight="39.0" prefWidth="310.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="266.0" AnchorPane.topAnchor="212.0">
+               <font>
+                  <Font size="25.0" />
+               </font>
+            </Label>
+            <VBox layoutX="109.0" layoutY="259.0" spacing="14.0">
+               <children>
+                  <Button fx:id="newProfileButton" layoutX="115.0" layoutY="259.0" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#newProfileButtonHandler" text="%launch.button.new" VBox.vgrow="ALWAYS" />
+                  <Button fx:id="importProfileButton" layoutX="109.0" layoutY="292.0" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#importProfileButtonHandler" text="%launch.button.import" VBox.vgrow="ALWAYS" />
+               </children>
+            </VBox>
+         </children>
+      </VBox>
+      <ListView id="projectList" fx:id="projectListView" fixedCellSize="40.0" layoutX="371.0" prefHeight="345.0" prefWidth="269.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="371.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
+      <HBox layoutX="494.0" layoutY="305.0" spacing="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0">
+         <children>
+            <Button fx:id="deleteButton" layoutX="494.0" layoutY="305.0" mnemonicParsing="false" onAction="#deleteButtonHandler" text="%launch.button.delete" />
+            <Button fx:id="openButton" layoutX="568.0" layoutY="305.0" mnemonicParsing="false" onAction="#openButtonHandler" text="%launch.button.open" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" />
+         </children>
+      </HBox>
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/mappingView.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/mappingView.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..1fd280d7d78644ca6efa907ef4fcc530ae4f8cd3
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/mappingView.fxml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox layoutX="14.0" layoutY="9.0" spacing="14.0">
+         <children>
+            <HBox alignment="CENTER_LEFT" layoutX="14.0" layoutY="9.0" spacing="14.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="14.0" prefWidth="150.0" text="%mappingPreset.label.mapping" textAlignment="RIGHT" AnchorPane.leftAnchor="14.0" />
+                  <ComboBox fx:id="presetsListView" layoutX="169.0" layoutY="9.0" prefWidth="150.0" AnchorPane.leftAnchor="169.0" />
+               </children>
+            </HBox>
+            <HBox layoutX="343.0" layoutY="9.0" spacing="14.0">
+               <children>
+                  <Button fx:id="addButton" layoutX="300.0" layoutY="9.0" mnemonicParsing="false" onAction="#addButtonHandler" text="%mappingPreset.button.add" />
+                  <Button fx:id="duplicateButton" layoutX="407.0" layoutY="9.0" mnemonicParsing="false" onAction="#duplicateButtonHandler" text="%mappingPreset.button.duplicate" />
+               </children>
+            </HBox>
+         </children>
+      </HBox>
+      <Separator layoutY="49.0" prefHeight="3.0" prefWidth="600.0" />
+      <HBox alignment="CENTER_LEFT" layoutX="14.0" layoutY="62.0" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="67.0" prefWidth="150.0" text="%mappingPreset.label.name" textAlignment="RIGHT" AnchorPane.leftAnchor="14.0" />
+            <TextField fx:id="nameTextField" layoutX="169.0" layoutY="62.0" prefWidth="150.0" AnchorPane.leftAnchor="169.0" />
+         </children>
+      </HBox>
+      <HBox layoutY="138.0" spacing="14.0">
+         <children>
+            <Button fx:id="exportButton" mnemonicParsing="false" onAction="#exportButtonHandler" prefWidth="150.0" text="%mappingPreset.button.export" />
+            <Button fx:id="importButton" mnemonicParsing="false" onAction="#importButtonHandler" prefWidth="150.0" text="%mappingPreset.button.import" />
+            <Button fx:id="removeButton" mnemonicParsing="false" onAction="#removeButtonHandler" prefWidth="150.0" text="%mappingPreset.button.delete" />
+         </children>
+      </HBox>
+      <HBox alignment="BOTTOM_RIGHT" VBox.vgrow="ALWAYS">
+         <children>
+            <Button fx:id="finishButton" mnemonicParsing="false" onAction="#finishButtonHandler" text="%mappingPreset.button.finish" />
+         </children>
+      </HBox>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/newProfileDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/newProfileDialog.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..4825083a71d4ace4249e86fe5788d1d5321a5423
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/newProfileDialog.fxml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox alignment="CENTER_LEFT" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" minWidth="100.0" prefWidth="100.0" text="%newProfile.label.name" />
+            <TextField fx:id="nameTextField" minWidth="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+         </children>
+      </HBox>
+      <Separator prefWidth="200.0" />
+      <VBox fx:id="accordionParent" spacing="14.0" VBox.vgrow="ALWAYS">
+         <children>
+            <Accordion fx:id="accordion" maxWidth="1.7976931348623157E308">
+              <panes>
+                <TitledPane animated="false" text="%newProfile.label.midiSettings">
+                     <content>
+                        <AnchorPane>
+                           <children>
+                              <VBox spacing="14.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+                                 <children>
+                                    <HBox alignment="CENTER_LEFT" spacing="14.0">
+                                       <children>
+                                          <Label alignment="CENTER_RIGHT" prefWidth="100.0" text="%newProfile.label.midi" />
+                                          <CheckBox fx:id="activeCheckBox" minWidth="200.0" mnemonicParsing="false" onAction="#activeCheckBoxHandler" prefWidth="200.0" text="%settings.checkbox.activate" />
+                                       </children>
+                                    </HBox>
+                                    <HBox alignment="CENTER_LEFT" spacing="14.0">
+                                       <children>
+                                          <Label alignment="CENTER_RIGHT" prefWidth="100.0" text="%settings.midi.label.device" />
+                                          <ComboBox fx:id="midiDeviceComboBox" maxWidth="1.7976931348623157E308" HBox.hgrow="ALWAYS" />
+                                       </children>
+                                    </HBox>
+                                 </children>
+                              </VBox>
+                           </children>
+                        </AnchorPane>
+                     </content>
+                </TitledPane>
+              </panes>
+            </Accordion>
+         </children>
+      </VBox>
+      <Separator maxWidth="1.7976931348623157E308" valignment="BOTTOM" />
+      <HBox alignment="BOTTOM_RIGHT" spacing="14.0">
+         <children>
+            <Button fx:id="cancelButton" mnemonicParsing="false" onAction="#cancelButtonHandler" text="%newProfile.button.cancel" />
+            <Button fx:id="finishButton" defaultButton="true" mnemonicParsing="false" onAction="#finishButtonHandler" text="%newProfile.button.finish" />
+         </children>
+      </HBox>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/newProjectDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/newProjectDialog.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..f209b7e315ec0401af8b174d867a6bc170ea6843
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/newProjectDialog.fxml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="200.0" minWidth="500.0" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox alignment="CENTER_LEFT" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" minWidth="100.0" prefWidth="100.0" text="%newProject.label.name" />
+            <TextField fx:id="nameTextField" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+         </children>
+      </HBox>
+      <HBox alignment="CENTER_LEFT" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" minWidth="100.0" prefWidth="100.0" text="%newProject.label.profile" HBox.hgrow="NEVER" />
+            <ComboBox fx:id="profileComboBox" maxWidth="1.7976931348623157E308" minWidth="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+            <Button fx:id="newProfileButton" mnemonicParsing="false" onAction="#newProfileButtonHandler" prefWidth="130.0" text="%newProject.button.newProfile" />
+         </children>
+      </HBox>
+      <HBox prefWidth="500.0" VBox.vgrow="ALWAYS">
+         <children>
+            <Label alignment="TOP_LEFT" text="%profile.label.info" textAlignment="JUSTIFY" wrapText="true" HBox.hgrow="ALWAYS">
+               <padding>
+                  <Insets left="114.0" />
+               </padding>
+            </Label>
+         </children>
+      </HBox>
+      <Separator valignment="BOTTOM" VBox.vgrow="ALWAYS" />
+      <HBox alignment="BOTTOM_RIGHT" spacing="14.0">
+         <children>
+            <Button fx:id="cnacelButton" mnemonicParsing="false" onAction="#cancelButtonHandler" prefWidth="130.0" text="%newProject.button.cancel" />
+            <Button fx:id="finishButton" defaultButton="true" mnemonicParsing="false" onAction="#finishButtonHandler" prefWidth="130.0" text="%newProject.button.finish" />
+         </children>
+      </HBox>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/pluginView.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/pluginView.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..49239259cdc8195284cd959f732b223f3a9cfd93
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/pluginView.fxml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <ListView fx:id="pluginListView" maxWidth="1.7976931348623157E308" AnchorPane.bottomAnchor="52.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" VBox.vgrow="ALWAYS" />
+      <Label layoutX="407.0" layoutY="364.0" text="%plugin.label.updateInfo" wrapText="true" HBox.hgrow="ALWAYS">
+         <VBox.margin>
+            <Insets left="14.0" right="14.0" />
+         </VBox.margin>
+      </Label>
+      <Label layoutX="14.0" layoutY="365.0" text="%plugin.label.restart" wrapText="true" AnchorPane.bottomAnchor="19.0" AnchorPane.leftAnchor="14.0">
+         <VBox.margin>
+            <Insets left="14.0" right="14.0" />
+         </VBox.margin>
+      </Label>
+      <HBox alignment="TOP_RIGHT">
+         <children>
+            <Button fx:id="finishButton" mnemonicParsing="false" onAction="#finishButtonHandler" text="%plugin.button.finish" />
+         </children>
+         <VBox.margin>
+            <Insets bottom="14.0" right="14.0" />
+         </VBox.margin>
+      </HBox>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/profileChooseDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/profileChooseDialog.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..2b5338add17b385651412d338c1a79dc5c2eb402
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/profileChooseDialog.fxml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox maxHeight="-Infinity" maxWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox alignment="CENTER_LEFT" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" minWidth="100.0" prefWidth="100.0" text="%newProject.label.profile" HBox.hgrow="NEVER" />
+            <ComboBox fx:id="profileComboBox" maxWidth="1.7976931348623157E308" minWidth="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+            <Button fx:id="newProfileButton" mnemonicParsing="false" onAction="#newProfileButtonHandler" prefWidth="130.0" text="%newProject.button.newProfile" />
+         </children>
+      </HBox>
+      <HBox prefHeight="70.0" prefWidth="500.0" VBox.vgrow="ALWAYS">
+         <children>
+            <Label alignment="TOP_LEFT" text="%profileChoose.label.info" wrapText="true" HBox.hgrow="ALWAYS">
+               <padding>
+                  <Insets left="114.0" />
+               </padding>
+            </Label>
+         </children>
+      </HBox>
+      <Separator valignment="BOTTOM" VBox.vgrow="ALWAYS" />
+      <HBox alignment="BOTTOM_RIGHT" spacing="14.0">
+         <children>
+            <Button fx:id="cnacelButton" mnemonicParsing="false" onAction="#cancelButtonHandler" prefWidth="130.0" text="%newProject.button.cancel" />
+            <Button fx:id="finishButton" defaultButton="true" mnemonicParsing="false" onAction="#finishButtonHandler" prefWidth="130.0" text="%profileChoose.button.finish" />
+         </children>
+      </HBox>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/profileSettingsView.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/profileSettingsView.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..f683242929d1be0b9ad6c09795524bf2ba049fee
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/profileSettingsView.fxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="445.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <ListView fx:id="profileList" layoutX="14.0" layoutY="14.0" prefHeight="376.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
+      <Button fx:id="chooseButton" layoutX="523.0" layoutY="360.0" mnemonicParsing="false" onAction="#chooseButtonHandler" text="%profile.button.choose" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" />
+      <VBox layoutX="236.0" layoutY="253.0" spacing="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="214.0">
+         <children>
+            <Button fx:id="newButton" layoutX="236.0" layoutY="253.0" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#newButtonHandler" text="%profile.button.new" VBox.vgrow="ALWAYS" />
+            <Button fx:id="duplicateButton" layoutX="236.0" layoutY="289.0" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#duplicateButtonHandler" text="%profile.button.duplicate" VBox.vgrow="ALWAYS" />
+            <Button fx:id="deleteButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#deleteButtonHandler" text="%profile.button.delete" VBox.vgrow="ALWAYS" />
+         </children>
+      </VBox>
+      <HBox alignment="CENTER_LEFT" layoutX="214.0" layoutY="17.0" spacing="14.0" AnchorPane.leftAnchor="214.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
+         <children>
+            <Label layoutX="214.0" layoutY="22.0" text="%profile.label.name" />
+            <TextField fx:id="nameTextField" layoutX="272.0" layoutY="17.0" HBox.hgrow="ALWAYS" />
+         </children>
+      </HBox>
+      <Label alignment="TOP_LEFT" layoutX="214.0" layoutY="82.0" prefHeight="184.0" prefWidth="216.0" text="%profile.label.info" wrapText="true" AnchorPane.bottomAnchor="134.0" AnchorPane.leftAnchor="214.0" AnchorPane.rightAnchor="15.0" AnchorPane.topAnchor="82.0" />
+      <Button fx:id="renameButton" layoutX="347.0" layoutY="48.0" mnemonicParsing="false" onAction="#renameButtonHandler" text="%profile.button.rename" AnchorPane.rightAnchor="15.0" AnchorPane.topAnchor="48.0" />
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/project/exportDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/project/exportDialog.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..103db556aa08bc7dd67c6f8474d3e8f6dc82fd02
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/project/exportDialog.fxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<StackPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <VBox spacing="14.0">
+         <children>
+            <VBox layoutX="14.0" layoutY="14.0" spacing="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0">
+               <children>
+                  <Label layoutX="14.0" layoutY="14.0" text="%project.export.label.headline" />
+                  <CheckBox fx:id="profileCheckBox" layoutX="29.0" layoutY="42.0" mnemonicParsing="false" text="%project.export.checkbox.profile" />
+                  <CheckBox fx:id="mediaCheckBox" layoutX="29.0" layoutY="69.0" mnemonicParsing="false" text="%project.export.checkbox.media" />
+               </children>
+            </VBox>
+            <HBox alignment="BOTTOM_RIGHT" layoutX="457.0" layoutY="102.0" spacing="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" VBox.vgrow="ALWAYS">
+               <children>
+                  <Button fx:id="cancelButton" layoutX="457.0" layoutY="102.0" mnemonicParsing="false" onAction="#cancelButtonHandler" text="%project.export.button.cancel" />
+                  <Button fx:id="saveButton" layoutX="528.0" layoutY="102.0" mnemonicParsing="false" onAction="#saveButtonHandler" text="%project.export.button.save" />
+               </children>
+            </HBox>
+         </children>
+         <padding>
+            <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+         </padding>
+      </VBox>
+   </children>
+</StackPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/project/openDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/project/openDialog.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..b0aae277d16ff7e84307867b50aa13b027b8ca8f
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/project/openDialog.fxml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <AnchorPane fx:id="rootNode" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+         <children>
+            <ListView fx:id="projectList" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
+            <VBox layoutX="200.0" prefHeight="200.0" prefWidth="100.0" spacing="14.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="200.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+               <children>
+                  <HBox alignment="CENTER_LEFT" spacing="14.0">
+                     <children>
+                        <Label text="%project.label.name" />
+                        <TextField fx:id="nameTextField" HBox.hgrow="ALWAYS" />
+                        <Button fx:id="renameButton" mnemonicParsing="false" onAction="#renameButtonHandler" text="%project.button.rename" />
+                     </children>
+                  </HBox>
+                  <Separator prefWidth="200.0" />
+                  <HBox spacing="14.0">
+                     <children>
+                        <VBox spacing="14.0">
+                           <children>
+                              <Label text="%project.label.fileSize" />
+                              <Label text="%project.label.lastModified" />
+                           </children>
+                        </VBox>
+                        <VBox spacing="14.0">
+                           <children>
+                              <Label fx:id="sizeLabel" text="100 MB" />
+                              <Label fx:id="dateLabel" text="20. Dez 2015 19:45" />
+                           </children>
+                        </VBox>
+                     </children>
+                  </HBox>
+                  <HBox spacing="14.0" VBox.vgrow="ALWAYS">
+                     <children>
+                        <VBox spacing="14.0" VBox.vgrow="ALWAYS">
+                           <children>
+                              <Button fx:id="newButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#newButtonHandler" text="%project.button.new" VBox.vgrow="ALWAYS" />
+                              <Button fx:id="duplicateButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#duplicateButtonHandler" text="%project.button.duplicate" VBox.vgrow="ALWAYS" />
+                              <Button fx:id="deleteButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#deleteButtonHandler" text="%project.button.delete" VBox.vgrow="ALWAYS" />
+                           </children>
+                        </VBox>
+                        <VBox spacing="14.0">
+                           <children>
+                              <Button fx:id="exportButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#exportButtonHandler" text="%project.button.export" VBox.vgrow="ALWAYS" />
+                              <Button fx:id="importButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#importButtonHandler" text="%project.button.import" VBox.vgrow="ALWAYS" />
+                           </children>
+                        </VBox>
+                     </children>
+                  </HBox>
+                  <Separator prefWidth="200.0" />
+                  <HBox alignment="TOP_RIGHT" spacing="14.0">
+                     <children>
+                        <Button fx:id="cancelButton" mnemonicParsing="false" onAction="#cancelButtonHandler" text="%project.button.cancel" />
+                        <Button fx:id="openButton" mnemonicParsing="false" onAction="#openButtonHandler" text="%project.button.finish" />
+                     </children>
+                  </HBox>
+               </children>
+               <padding>
+                  <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+               </padding>
+            </VBox>
+         </children>
+      </AnchorPane>
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/project/printDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/project/printDialog.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..9e2f0f9c41b401e6ba60d67c7a98996ec011335a
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/project/printDialog.fxml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import javafx.scene.web.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <WebView fx:id="webView" prefHeight="348.0" prefWidth="600.0" AnchorPane.bottomAnchor="52.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
+      <HBox alignment="CENTER_LEFT" layoutX="14.0" layoutY="360.0" spacing="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0">
+         <children>
+            <Label layoutX="14.0" layoutY="365.0" text="%print.label.page" />
+            <ComboBox fx:id="pageComboBox" layoutX="94.0" layoutY="360.0" prefWidth="150.0" />
+         </children>
+      </HBox>
+      <HBox layoutX="463.0" layoutY="360.0" spacing="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0">
+         <children>
+            <Button fx:id="cancelButton" layoutX="463.0" layoutY="360.0" mnemonicParsing="false" onAction="#cancelButtonHandler" text="%print.button.cancel" />
+            <Button fx:id="printButton" layoutX="528.0" layoutY="360.0" mnemonicParsing="false" onAction="#printButtonHandler" text="%print.button.print" />
+         </children>
+      </HBox>
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/files/Test-Sound.wav b/PlayWall/assets/de/tobias/playpad/assets/files/Test-Sound.wav
new file mode 100644
index 0000000000000000000000000000000000000000..1a627d7c84165c6131c47134b1ca1f4fcb0bf3be
Binary files /dev/null and b/PlayWall/assets/de/tobias/playpad/assets/files/Test-Sound.wav differ
diff --git a/PlayWall/assets/de/tobias/playpad/assets/files/dialogDnD.png b/PlayWall/assets/de/tobias/playpad/assets/files/dialogDnD.png
new file mode 100644
index 0000000000000000000000000000000000000000..79a1e57c0fabf8751169b46cd0be117ca457adad
Binary files /dev/null and b/PlayWall/assets/de/tobias/playpad/assets/files/dialogDnD.png differ
diff --git a/PlayWall/assets/de/tobias/playpad/assets/files/dialogDnD.pxm b/PlayWall/assets/de/tobias/playpad/assets/files/dialogDnD.pxm
new file mode 100644
index 0000000000000000000000000000000000000000..34238c749b4b88804485d74eb87307a03d2588e6
Binary files /dev/null and b/PlayWall/assets/de/tobias/playpad/assets/files/dialogDnD.pxm differ
diff --git a/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties b/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties
new file mode 100644
index 0000000000000000000000000000000000000000..054e2ce5b5f25c3fd4ee0c2f390d9523d0dd0aa3
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties
@@ -0,0 +1,224 @@
+# Hier sind Sachen, die dynamisch im Code verwendet werden. Also wenn eine spezielle Aktionen ist. Beispielsweise Fehlermeldung und Hinweise. Die Sachen sind aber trotzdem in der UI.   
+#Kommentare befinden sich immer -->�BER<-- dem jeweiligen Eintrag
+
+# Standard - File
+Standard.File.Save=Gespeichert
+Standard.Copy={} - Kopie
+Standard.Time.Seconds={} sec
+
+# File - Filter
+File.Filter.ZIP=Archivedatei
+File.Filter.Media=Medien
+File.Filter.Preset=Vorlagen
+
+# Timemode - Enum
+Pad.TimeMode.PLAYED=Abgelaufene Zeit
+Pad.TimeMode.REST=Verbleibende Zeit
+Pad.TimeMode.BOTH=Abgelaufende Zeit / Gesamtzeit
+
+# UI - Window - Titles
+UI.Dialog.Launch.Title=Projekt w�hlen...
+UI.Window.Main.Title=Play Wall [Projekt: {} - Profil: {}]
+UI.Window.Changelog.Title=Was ist neu?
+UI.Window.Settings.Title=Einstellungen - {}
+UI.Window.PadSettings.Title=Kachel Einstellungen - {} | {}
+UI.Dialog.DragAndDrop.Title=Drag and Drop
+UI.Dialog.ProjectExport.Title=Project exportieren
+UI.Dialog.ErrorSummary.Title=Fehlerbericht
+UI.Dialog.NewProfile.Title=Neues Profil
+UI.Dialog.NewProject.Title=Neues Projekt
+UI.Dialog.ChooseProfile.Title=Profil w�hlen
+UI.Dialog.ProjectManager.Title=Projektverwaltung
+UI.Dialog.UpdateCenter.Title=Aktualisierungen
+UI.Dialog.Preset.Title=Vorlagen
+UI.Dialog.Plugins.Title=Erweiterungen
+UI.Dialog.Print.Title=Drucken
+UI.Dialog.Profile.Title=Profile
+
+# UI - Standard
+UI.Standard.DoNotShow=Nicht mehr anzeigen
+
+# UI - Layout - Classic - Theme - Enum
+UI.Layout.Classic.Theme.DARK=Dunkel
+UI.Layout.Classic.Theme.TWILIGHT=Dunkelblau (Twilight)
+UI.Layout.Classic.Theme.LIGHT=Hell
+
+# UI - Window - Main
+UI.Window.Main.CloseRequest=Es wird gerade noch Musik abgespielt. M�chten Sie PlayWall trotzdem beenden?
+UI.Window.Main.PageButton = Seite {}
+
+# UI - Dialog - Launch
+UI.Dialog.Launch.Info={} - {}
+
+# UI Window - Settings
+UI.Window.Settings.Gen.Title=Allgemein
+UI.Window.Settings.Gen.CacheSize=Gr��e: {}B
+UI.Window.Settings.Mapping.Title=Mapping
+UI.Window.Settings.Midi.Title=Midi
+UI.Window.Settings.Layout.Title=Layout
+UI.Window.Settings.Player.Title=Player
+UI.Window.Settings.Audio.Title=Audio
+UI.Window.Settings.Updates.Title=Updates
+
+# UI - Dialog - DragAndDrop
+UI.Dialog.DragAndDrop.Header=Hinweis
+UI.Dialog.DragAndDrop.Content=F�r das Verschieben von Kacheln gibt es zwei M�glichkeiten: Vertauschen oder Ersetzen.\nUm die gw�hlte Kachel mit der Zielkachel zu vertauschen, muss der obere Teil der Zielkachel gew�hlt werden. Es erscheint eine blaue Umrandung. \nUm die ausgew�hlte Kachel mit der Zielkachel zu ersetzen, muss der untere Teil der Zielkachel gew�hlt werden. Es erscheint eine rote Umrandung.
+UI.Dialog.DragAndDrop.Button=OK
+
+# UI - Dialog - NewProfile
+UI.Dialog.NewProfile.Content=Geben Sie einen Namen f�r das neue Profil ein:
+
+# UI - Dialog - NewProject
+UI.Dialog.NewProject.Content=Geben Sie einen Namen f�r das neue Projekt ein.
+
+# UI - Dialog - Import
+UI.Dialog.Import.ReplaceProfile.Content=Es gibt bereits eine Profil mit dem Namen {}. Bitte nennen Sie das Profil um.
+UI.Dialog.Import.ReplaceProfile.Skip=Import �berspringen
+UI.Dialog.Import.ReplaceProfile.Rename=Umbenennen
+UI.Dialog.Import.ReplaceProfile.ReplaceContent=Es gibt bereits ein Profil mit dem Namen {}.\nBitte geben Sie einen neuen Namen ein.
+UI.Dialog.Import.ReplaceProject.ReplaceContent=Es gibt bereits ein Projekt mit dem Namen {}.\nBitte geben Sie einen neuen Namen ein.
+UI.Dialog.Import.ReplaceMedia.Content=M�chten Sie die Mediendaten von diesem Projekt importieren?
+UI.Dialog.Import.ReplaceMedia.Copy=Kopieren
+UI.Dialog.Import.ReplaceMedia.Skip=�berspringen
+
+# UI - Dialog - ProjectManager
+UI.Dialog.ProjectManager.Delete.Content=M�chten Sie das Projekt {} wirklich l�schen?
+
+# UI - Dialog - Profile
+UI.Dialog.Profile.Delete.Content=Sind Sie sicher, dass Sie das Profil {} l�schen m�chten?
+
+# UI - Dialog - Info
+UI.Dialog.Info.Header=�ber {}
+UI.Dialog.Info.Content=Version: {} (Build: {})\nAutor: {}\n\nDieses Programm nutzt Bibliotheken. ControlsFX (8.40.10), dom4j (1.6.1), snakeyaml (1.11), guava (15.0), gagawa (1.0.1), TinySound (1.1.1), JLayer (1.0.1), JSPF (1.0.2), json-smart (1.2). \nBesonderen Dank an die Betatester: Stefan, Robert.
+
+# UI - Dialog - Feedback
+UI.Dialog.Feedback.Content=Der Fehlerbericht wird �bermittelt. Bitte haben Sie etwas Geduld. Ihre Nummer wird am Ende angezeigt.
+
+# UI - Placeholder
+UI.Placeholder.Project=Keine Projekte vorhanden
+UI.Placeholder.Preset=Keine Vorlagen vorhanden
+UI.Placeholder.Plugins=Keine Plugins vorhanden
+UI.Placeholder.Updates=Es sind keine Updates verf�gbar
+UI.Placeholder.ErrorSummary=Keine Fehler
+
+# Info - MIDI
+Info.Midi.Device.Connected=Midi Ger�t erkannt ({})
+
+# Info - Settings
+Info.Settings.ResetWarning=Die Einstellungen wurden zur�ckgesetzt.
+Info.Settings.CacheDelete={} Dateien wurden gel�scht.
+
+# Info - Print
+Info.Print.Header={} - Seite {}
+
+# Error - Standard
+Error.Standard.Gen=Es ist ein Fehler aufgetreten, bitte versuchen Sie es sp�ter noch einmal. ({})
+Error.Standard.NameInUse=Der Name {} kann nicht gew�hlt werden, da er bereits vergeben ist.
+
+# Error - Settings
+Error.Settings.CacheSize=Die Gr��e des Cache kann nicht bestimmt werden. ({})
+Error.Settings.CacheClear=Beim L�schen des Caches ist ein Fehler aufgetreten. ({})
+
+# Error - Profile
+Error.Profile.Create=Das Profil konnte aufgrund eines Fehlers nicht erstellt werden. ({})
+Error.Profile.NotFound=Das Profil konnte nicht geladen werden, da die Datein fehlen. W�hle eine neues Profile und �ffne das Projekt erneut. ({})
+Error.Profile.Save=Das Profil konnte aufgrund eines Fehlers nicht gespeichert werden. ({})
+Error.Profile.Delete=Das Projekt konnte nicht gel�scht werden. ({})
+Error.Profile.SmallScreen=Ihr Bildschirm ist f�r die gew�hlte Anzahl der Kacheln zu klein. (Maximal: {}x{})
+
+# Error - Preset
+Error.Preset.Import=Es ist ein Fehler beim Importieren der Vorlage aufgetreten. ({})
+Error.Preset.Export=Die Vorlage konnte nicht exportiert werden. ({})
+
+# Error - Project
+Error.Project.Create=Das Projekt konnte nicht erstellt werden. ({})
+Error.Profile.NotFound=Das Projekt {} konnte nicht ge�ffnet werden, da die Projektdatei nicht gefunden wurde. ({})
+Error.Project.Open=Das Projekt {} konnte nicht ge�ffnet werden. ({})
+Error.Project.Save=Das Projekt {} konnte nicht gespeichert werden. ({})
+Error.Project.Rename=Das Projekt konnte nicht umbenannt werden. ({})
+Error.Project.Delete=Das Projekt konnte nicht gel�scht werden. ({})
+Error.Project.Export=Das Projekt {} konnte nicht exportiert werden. ({})
+
+# Error - Pad - Enum
+Error.Pad.FILE_NOT_FOUND=Die Datei {} konnte nicht gefunden werden.
+Error.Pad.FILE_FORMAT_NOT_SUPPORTED=Die Datei {} ist inkompatibel.
+Error.Pad.CONVERT_NOT_SUPPORTED=Die Datei {} kann nicht umgewandelt werden. (W�hlen Sie ein anderes Format zum Import aus)
+Error.Pad.UNKOWN=Es ist ein Unbekannter Fehler aufgetreten. {}
+Error.Pad.UNKOWN_CONTENT_TYPE=Die Kachel {} konnte nicht geladen werden.
+
+# Error - L�sung
+Error.Fix.NewFile=Neue Datei w�hlen
+
+# Error - Midi
+Error.Midi.Settings.Unkown=F�r die ausgew�hlte Seite sind keine Midi Einstellungen aktiv. In Einstellungen -> Midi -> Presets kann dies angepasst werden.
+Error.Midi.Device.Busy=Das Midi-Ger�t wird bereits durch ein anderes Programm verwendet. ({})
+Error.Midi.Device.Unavailible=Das Midi-Ger�t {} konnte nicht gefunden werden.
+Error.Midi.Record.Fail=Die gedr�ckte Taste wird bereits verwendet.
+Error.Midi.Send=Der Midi Befehl konnte nicht gesendet werden. ({})
+
+# Error - Plugins
+Error.Plugins.Download=Das Plugin {} konnte nicht geladen werden.
+
+#Mapper
+Mapper.Keyboard.Name=Tastatur
+Mapper.Midi.Name=Midi
+Mapper.Keyboard.toString=Tastatur {}
+Mapper.Midi.toString=Midi {}
+
+# Info - Mapper
+Info.Mapper.PressKey=Dr�cken Sie eine Taste auf dem Ger�t.
+
+# UI - Window - PadSettings
+UI.Window.PadSettings.General.Title=Allgemein
+UI.Window.PadSettings.Player.Title=Player
+UI.Window.PadSettings.Layout.Title=Layout
+UI.Window.PadSettings.Trigger.Title=Trigger
+
+# Actions
+Action.Cart.toString=Kachel {}
+Action.Page.toString=Seite {}
+Action.Navigate.toString={}
+Action.Cart.Name=Kacheln
+Action.Page.Name=Seiten
+Action.Navigate.Name=Navigation
+
+#Content
+Content.Empyt=Leer
+Content.Audio.Name=Audio
+
+# NavigationType - Enum
+NavigationType.PREVIOUS=Vorherige Seite
+NavigationType.NEXT=N�chste Seite
+
+# CartAction - Enum
+CartAction.Mode.PLAY_STOP=Play/Stop
+CartAction.Mode.PLAY_PAUSE=Play/Pause
+CartAction.Mode.PLAY_HOLD=Play/Hold
+
+#UI - Dialog -AutoUpdate
+UI.Dialog.AutoUpdate.Header=Updates
+UI.Dialog.AutoUpdate.Content=Es gibt Updates. Weitere Informationen finden Sie in den Update Einstellungen. Wollen Sie die Updates jetzt installieren?
+
+# Error - Layout
+Error.Layout.Load=Es gab einen Fehler beim Laden des Layouts ({})
+
+# UI - Dialog - Update
+UI.Dialog.Update.Cell={}: Installiert: {} - Neu: {}
+UI.Window.Settings.Updates.CurrentVersion={} (Build {})
+UI.Window.Settings.Updates.NewVersion={} (Build {})
+
+# Error - Update - Downlaod
+Error.Update.Download=Es ist ein Fehler beim Downloaden des Updates aufgetreten. Bitte versuchen Sie es sp�ter noch einmal. ({})
+
+# Layout
+Layout.Modern.Name=Modern
+Layout.Classic.Name=Klassisch
+
+# Trigger
+TriggerPoint.toString={} ({})
+Trigger.Cart.Name=Kacheln
+Trigger.Volume.Name=Lautst�rke
+
+# TriggerPoint - Enum
+TriggerPoint.START=Start
+TriggerPoint.EOF_STOP=Ende/Stop
\ No newline at end of file
diff --git a/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties b/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ae2924f4608d192e0c581a1b3e39abf905ed8773
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties
@@ -0,0 +1,196 @@
+#Sprachdatei f�r die Benutzeroberfl�che
+
+main.menu.file=Datei
+main.menu.option=Optionen
+main.menu.view=Ansicht
+main.menu.info=Info
+main.menu.extension=Erweitert
+
+main.menuitem.new=Neues Projekt...
+main.menuitem.project=Projekte verwalten...
+main.menuitem.save=Projekt speichern...
+main.menuitem.recentFiles=Zuletzt verwendete Projekte
+main.menuitem.profile=Profile verwalten...
+main.menuitem.print=Drucken...
+main.menuitem.onTop=Fenster im Vordergrund
+main.menuitem.plugins=Erweiterungen...
+main.menuitem.dnd=Bearbeitungsmodus
+main.menuitem.errors=Fehlerbericht anzeigen...
+main.menuitem.settings=Einstellungen...
+main.menuitem.about=�ber Play Wall...
+main.menuitem.website=Webseite besuchen...
+main.menuitem.senderror=Fehler senden...
+main.menuitem.fullScreen=Vollbild
+
+main.label.live=Live
+
+settings.gen.label.view=Ansicht:
+settings.gen.label.pages=Anzahl der Seiten:
+settings.gen.label.columns=Anzahl der Spalten:
+settings.gen.label.rows=Anzahl der Reihen:
+settings.gen.label.additional=Erweitert:
+settings.gen.label.liveMode=Live Modus:
+settings.gen.checkbox.liveMode=Aktivieren
+settings.gen.label.liveModeInfo=Der Live Modus verhindet ungewollte Aktionen w�hrend der Wiedergabe einer Kachel.
+settings.gen.warning.button.reset=Hinweismeldungen zur�cksetzen
+settings.gen.cache.label=Cachespeicher:
+settings.gen.cache.button.choose=W�hlen
+settings.gen.cache.button.reset=Cache leeren
+settings.gen.cache.label.info=Wenn Sie als Audioausgabetyp "Java Audiostream" gew�hlt haben, werden jegliche MP3-Dateien in eine WAV-Dateien umgewandelt. Diese wird dann in den oben angegebenen Ordner abgelegt. Sollen Sie viele Dateien aus Ihrem Projekt gel�scht haben, ist es sinnvoll, den Cache zu leeren, um die ben�tigten Speicher zu verringern. Ben�tigte Dateien werden automatisch neu umgewandelt, falls sie nicht (mehr) existieren. 
+
+settings.mapping.label.mapping=Mapping:
+settings.mapping.button.edit=Bearbeiten...
+
+settings.midi.button.activate=Aktivieren
+settings.midi.label.device=Midi Ger�te:
+
+settings.layout.label.type=Layout Type:
+
+settings.player.label.warning=Warnhinweise:
+settings.player.label.fade=Ein-/Ausblenden:
+settings.player.label.fadeIn=Einblenden (in s):
+settings.player.label.fadeOut=Ausblenden (in s):
+settings.player.label.startIn=... nach Start
+settings.player.label.pauseIn=... nach Pause
+settings.player.label.pauseOut=... vor Pause
+settings.player.label.stopOut=... vor Stop (nicht Ende)
+settings.player.label.fadeInfo=Wird beim Ein- oder Ausblenden die Dauer auf 0 gesetzt, so findet keine �berblendung statt. Wenn der Sound zu Ende ist, findet kein Ausblenden statt.
+settings.player.label.timeDisplay=Zeitanzeige:
+
+settings.update.label.current=Installierte Version:
+settings.update.label.new=Aktuelle Version:
+settings.update.label.search=Nach updates suchen:
+settings.update.label.available=Verf�gbare Updates:
+settings.update.button.search=Jetzt suchen
+settings.update.button.install=Aktualisieren und neu starten
+
+settings.button.finish=Fertig
+settings.checkbox.activate=Aktivieren
+
+layout.label.programmLayout=Programmlayout:
+layout.label.customLayout=Eigenes Layout:
+layout.label.baseColor=Akzentfarbe:
+layout.label.background=Hintergrund:
+layout.label.playground=Hintergrund w�hrend Wiedergabe:
+layout.label.fadeColor=Hintergrund w�hrend Ausblenden:
+layout.label.warnColor=Warnhinweis:
+layout.label.color=Farbe:
+layout.label.fontSize=Schriftgr��e:
+layout.label.infoLabel=Kopfzeile:
+layout.label.titleLabel=Titel:
+layout.label.animation=Animationen:
+layout.label.warnAnimation=Warnhinweise
+layout.button.reset=Zur�cksetzen
+
+midi.label.key=Taste (Midi):
+midi.button.new=�ndern
+
+keyboard.label.key=Taste (Tastatur):
+keyboard.button.new=�ndern
+
+padSettings.button.delete=L�schen
+
+padSettings.gen.label.title=Titel:
+padSettings.gen.label.volume=Lautst�rke:
+padSettings.gen.label.timeDisplay=Zeitanzeige:
+padSettings.gen.checkbox.customSettings=Eigene Einstellungen
+padSettings.checkbox.loop=Wiederholen
+padSettings.button.finish=Fertig
+
+padSettings.player.label.warning=Warnhinweise:
+padSettings.player.label.fade=Ein-/Ausblenden:
+
+padSettings.layout.label.custom=Eigenes Layout:
+padSettings.layout.checkbox.custom=aktiviert
+
+project.button.finish=�ffnen
+project.button.cancel=Abbrechen
+project.button.delete=L�schen
+project.button.rename=Umbenennen
+project.button.new=Neues Projekt
+project.button.duplicate=Duplizieren
+project.button.export=Exportieren...
+project.button.import=Importieren..
+project.label.name=Name:
+project.label.fileSize=Dateigr��e
+project.label.lastModified=Zuletzt bearbeitet:
+
+project.export.label.headline=Projekt exportieren:
+project.export.checkbox.profile=Zus�tzlich das Profil mit exportieren?
+project.export.checkbox.media=Zus�tzlich die Medieninhalte exportieren?
+project.export.button.cancel=Abbrechen
+project.export.button.save=Speichern...
+#Project import ist in der _de.properties
+
+launch.button.import=Projekt importieren
+launch.button.new=Neues Projekt
+launch.button.open=�ffnen
+launch.button.delete=L�schen
+
+profile.label.name=Name
+profile.label.info=Ein Profil umfasst alle Einstellungen des Programmes, beispielsweise das Aussehen, die Midi-Einstellungen oder die Audioeinstellungen. Sie k�nnen jederzeit f�r ein Projekt das Profil wechseln.
+profile.button.rename=Umbenennen
+profile.button.new=Neu
+profile.button.delete=L�schen
+profile.button.duplicate=Duplizieren
+profile.button.choose=Profil w�hlen
+
+warning.label.time=Warnhinweis ab Restdauer: (Sek)
+
+print.label.page=Seite:
+print.button.cancel=Abbrechen
+print.button.print=Drucken
+
+plugin.label.restart=Einige �nderungen werden erst nach dem Neustart des Programmes wirksam.
+plugin.label.updateInfo=Plugins k�nnen in den Updateeinstellungen aktualisiert werden.
+plugin.button.finish=Fertig
+
+settings.audio.type=Ausgabe Type w�hlen:
+
+newProject.label.name=Name:
+newProject.label.profile=Profil:
+newProject.button.newProfile=Neues Profil...
+newProject.button.finish=Projekt erstellen
+newProject.button.cancel=Abbrechen
+
+newProfile.label.name=Name:
+newProfile.label.midiSettings=Midi Einstellungen:
+newProfile.label.midi=Midi Funktion:
+newProfile.button.finish=Profil erstellen
+newProfile.button.cancel=Abbrechen
+
+profileChoose.label.info=Die Voreinstellungen zu diesem Projekt wurden nicht gefunden.\nBitte w�hlen Sie neue Voreinstellungen aus.
+profileChoose.button.finish=Profil w�hlen
+
+doubleFeedback.label.colorEvent=Event Farbe:
+doubleFeedback.label.colorDefault=Standard Farbe:
+
+cartAction.label.headline=Einstellungen zur Kachel:
+cartAction.label.type=Typ:
+cartAction.label.autoColor=Feedback wie Layout:
+cartAction.checkbox.autoColor=Aktivieren
+
+action.mapper.headline=Einstellungen zum Mapping:
+
+mappingPreset.button.add=Hinzuf�gen
+mappingPreset.button.duplicate=Duplizieren
+mappingPreset.button.export=Exportieren...
+mappingPreset.button.import=Importieren...
+mappingPreset.button.delete=L�schen
+mappingPreset.button.finish=Fertig
+mappingPreset.label.mapping=Mapping:
+mappingPreset.label.name: Name:
+
+errorSummary.label.headline=Fehlerzusammenfassung:
+errorSummary.column.cart=Kachel
+errorSummary.column.des=Fehlerbeschreibung
+errorSummary.column.solution=L�sung
+errorSummary.button.close=Schlie�en
+
+tinysound.label.soundcard=Sound Karte:
+
+triggertime.label.time=Zeit vom Trigger: (Sek)
+
+carttrigger.label.action=Aktion f�r Kacheln:
+carttrigger.label.carts=Kacheln:
+carttrigger.checkbox.all=Alle (au�er diese)
diff --git a/PlayWall/assets/de/tobias/playpad/assets/modern_style.css b/PlayWall/assets/de/tobias/playpad/assets/modern_style.css
new file mode 100644
index 0000000000000000000000000000000000000000..8c1ff6afa671324e61247d11ffb1072ad84891d0
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/modern_style.css
@@ -0,0 +1,134 @@
+.root {
+	-fx-base: rgb(30, 30, 30);
+}
+
+.deleteButton {
+	-fx-background-color: transparent;
+	-fx-padding: 0;
+}
+
+.pad:drag {
+	-fx-opacity: 0.8;
+}
+
+.text-field:error {
+	-fx-text-box-border: red;
+	-fx-focus-color: red;
+}
+
+.live-label {
+	-fx-text-fill: red !important;
+}
+
+// Neu
+.pad {
+	/*
+	-fx-background-color: linear-gradient(#A7FF9A, #8FD673); // Grün
+	-fx-background-color: linear-gradient(#469fe2, #0080e2); // Blau
+
+
+	-fx-background-color: linear-gradient(#a90329, #6d0019); // Weinrot F
+	-fx-background-color: linear-gradient(#55B7FF, #369FE9); // Blau F
+	-fx-background-color: linear-gradient(#FF6E6B, #EF5350); // Rot F
+	-fx-background-color: linear-gradient(#73E178, #66BB6A); // Grün F
+	-fx-background-color: linear-gradient(#ffe08c, #d5bf54); // Gelb F
+	-fx-background-color: linear-gradient(#db7ab7, #dd61b0); // Pink F
+	-fx-background-color: linear-gradient(#ff9254, #ff7526); // Orange F
+	-fx-background-color: linear-gradient(#86F7FF, #52E3EC); // Aqua F
+	-fx-background-color: linear-gradient(#555555, #333333); // Dark F	
+	-fx-background-color: linear-gradient(#eeeeee, #cccccc); // Grau F
+	-fx-background-color: linear-gradient(#cccccc, #aaaaaa); // Mittel Grau F
+	*/
+
+	-fx-background-radius: 10px;
+	
+	-fx-border-color: rgb(20, 20, 20);
+	-fx-border-width: 2px;
+	-fx-border-radius: 8px;
+	
+	-fx-padding: 5 10 5 10;
+}
+
+.pad-root {
+	-fx-spacing: 4px;
+}
+
+.pad-button-box {
+	-fx-spacing: 0px;
+}
+
+.pad-grid {
+	-fx-background-color: rgb(60, 60, 60);
+
+	-fx-hgap: 6px;
+	-fx-vgap: 6px;
+	
+	-fx-padding: 6px;
+}
+
+.pad-info {
+	-fx-text-fill: white;
+	-fx-font-size: 15px;
+}
+
+.pad-button {
+	-fx-background-color: transparent;
+	-fx-border-color: transparent;
+}
+
+
+.pad-button:hover {
+	-fx-background-color: transparent;
+	-fx-border-width: 1px;
+	-fx-border-color: rgb(30, 30, 30, 0.5);
+	-fx-border-radius: 10px;
+}
+
+.pad-button:pressed {
+	-fx-background-color: transparent;
+	-fx-border-width: 1px;
+	-fx-border-color: black;
+	-fx-border-radius: 10px;
+}
+
+.fonticon {
+	-fx-text-fill: white;
+	-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 4, 0.1, 1, 1);
+}
+
+.pad-playbar .bar {
+    -fx-background-color: white;
+    -fx-padding: 0.5em;
+    
+    -fx-background-radius: 10px;    
+}
+
+.pad-playbar .track { 
+	-fx-base: black;
+    -fx-background-radius: 10px; 
+}
+
+.pad-playbar {
+    -fx-background-radius: 10px;
+    -fx-effect: dropshadow( gaussian , rgba(0, 0, 0, 0.5), 8, 0.5, 2, 2);     
+}
+
+.tool-bar {
+	-fx-base: rgb(60, 60, 60);
+}
+
+.menu-bar {
+	-fx-base: rgb(60, 60, 60);
+}
+
+.current-page-button {
+	-fx-base: lightgray;
+}
+
+.slider .thumb {
+	-fx-base: white;
+}
+
+.volume-item {
+	-fx-text-fill: white !important;
+}
diff --git a/PlayWall/assets/de/tobias/playpad/assets/settings/fadeView.fxml b/PlayWall/assets/de/tobias/playpad/assets/settings/fadeView.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..d736fbbff8080e0e0fd31ea92b900d0adbfe19a7
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/settings/fadeView.fxml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox prefWidth="500.0" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="19.0" prefWidth="150.0" text="%settings.player.label.fadeIn" textAlignment="RIGHT" />
+            <VBox spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <HBox spacing="14.0">
+                     <children>
+                        <Slider fx:id="fadeInSlider" blockIncrement="0.1" majorTickUnit="1.0" max="10.0" maxWidth="1.7976931348623157E308" minorTickCount="9" showTickLabels="true" showTickMarks="true" snapToTicks="true" HBox.hgrow="ALWAYS" />
+                        <Label fx:id="fadeInLabel" prefWidth="75.0" />
+                     </children>
+                  </HBox>
+                  <HBox spacing="14.0">
+                     <children>
+                        <CheckBox fx:id="fadeInStartCheckBox" mnemonicParsing="false" text="%settings.player.label.startIn" />
+                        <CheckBox fx:id="fadeInPauseCheckBox" mnemonicParsing="false" text="%settings.player.label.pauseIn" />
+                     </children>
+                  </HBox>
+               </children>
+            </VBox>
+         </children>
+      </HBox>
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="53.0" prefWidth="150.0" text="%settings.player.label.fadeOut" textAlignment="RIGHT" />
+            <VBox spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <HBox spacing="14.0">
+                     <children>
+                        <Slider fx:id="fadeOutSlider" blockIncrement="0.1" majorTickUnit="1.0" max="10.0" maxWidth="1.7976931348623157E308" minorTickCount="9" showTickLabels="true" showTickMarks="true" snapToTicks="true" HBox.hgrow="ALWAYS" />
+                        <Label fx:id="fadeOutLabel" prefWidth="75.0" />
+                     </children>
+                  </HBox>
+                  <HBox spacing="14.0">
+                     <children>
+                        <CheckBox fx:id="fadeOutPauseCheckBox" mnemonicParsing="false" text="%settings.player.label.pauseOut" />
+                        <CheckBox fx:id="fadeOutStopCheckBox" mnemonicParsing="false" text="%settings.player.label.stopOut" />
+                     </children>
+                  </HBox>
+               </children>
+            </VBox>
+         </children>
+      </HBox>
+      <Label maxWidth="1.7976931348623157E308" text="%settings.player.label.fadeInfo" wrapText="true" VBox.vgrow="ALWAYS">
+         <VBox.margin>
+            <Insets left="164.0" />
+         </VBox.margin></Label>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/settings/warningFeedbackSettingsView.fxml b/PlayWall/assets/de/tobias/playpad/assets/settings/warningFeedbackSettingsView.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..c203846c01b6c92c94bba75699eb7b9618ba64c4
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/settings/warningFeedbackSettingsView.fxml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.shape.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox alignment="CENTER_LEFT" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="14.0" prefWidth="150.0" text="%warning.label.time" textAlignment="RIGHT" wrapText="true" AnchorPane.leftAnchor="14.0" />
+            <Slider fx:id="warningFeedbackTimeSlider" blockIncrement="0.1" majorTickUnit="1.0" max="10.0" minorTickCount="9" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="5.0" HBox.hgrow="ALWAYS" />
+            <Label fx:id="warningFeedbackTimeLabel" prefWidth="75.0" />
+         </children>
+      </HBox>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/style.css b/PlayWall/assets/de/tobias/playpad/assets/style.css
new file mode 100644
index 0000000000000000000000000000000000000000..40d94559897cdc6ca42596283df2053edf65483a
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/style.css
@@ -0,0 +1,30 @@
+.text-field:error {
+	-fx-text-box-border: red ;
+	-fx-focus-color: red ;
+}
+
+.color-view-item {
+	-fx-stroke: black;
+	-fx-stroke-width: 2;
+	-fx-arc-height: 7.5;
+	-fx-arc-width: 7.5;
+}
+
+.color-view-item:hover {
+	-fx-stroke: DARKRED;
+}
+
+.color-view-item:pressed {
+	-fx-stroke: RED;
+}
+
+.dnd-file-option {
+	-fx-text-fill: white;
+}
+
+.dnd-file-option:drag {
+	-fx-text-fill: white;
+	-fx-border-width: 2px;
+	-fx-border-color: white;
+	-fx-border-radius:10px;
+}
diff --git a/PlayWall/assets/de/tobias/playpad/assets/style/Dark.css b/PlayWall/assets/de/tobias/playpad/assets/style/Dark.css
new file mode 100644
index 0000000000000000000000000000000000000000..b169cecdab23acef41f7350f255a0a346e46c1e0
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/style/Dark.css
@@ -0,0 +1,95 @@
+.root {
+	-fx-base: rgb(40, 40, 40);
+	-fx-background: rgb(40, 40, 40);
+	-fx-control-inner-background:  rgb(45, 45, 45);
+}
+ 
+.tab {
+	-fx-background-color: linear-gradient(to top, -fx-base, derive(-fx-base,50%));
+}
+
+.tab:selected {
+	-fx-background-color: linear-gradient(to bottom, -fx-base, derive(-fx-base,50%));
+}
+ 
+.menu-bar {
+	-fx-background-color: linear-gradient(to bottom, -fx-base, derive(-fx-base, 15%));
+}
+
+.menu:hover, 
+.menu-item:hover, 
+.menu:showing, 
+.menu-item:focused, 
+.list-view .list-cell:selected, 
+.combo-box-popup .list-view .list-cell:filled:selected, 
+.combo-box-popup .list-view .list-cell:filled:selected:hover, 
+.combo-box-popup .list-view .list-cell:filled:hover {
+	-fx-background-color: rgb(70, 70, 70);
+	-fx-text-fill: white;
+}
+
+.tool-bar:horizontal {
+	-fx-background-color: linear-gradient(to bottom, derive(-fx-base,+20%), derive(-fx-base,+0%));
+	-fx-border: 1px 0px 1px 0px;
+	-fx-border-color: black;
+}
+ 
+.button {
+	-fx-base: black;
+}
+ 
+.button:hover {
+	-fx-background-color: -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
+	-fx-color: -fx-hover-base;
+}
+ 
+.table-view {
+	-fx-table-cell-border-color:derive(-fx-base,+10%);
+	-fx-table-header-border-color:derive(-fx-base,+20%);
+}
+
+.fonticon {
+	-fx-text-fill: red;
+}
+
+.label {
+	-fx-text-fill: white;
+	-fx-fill: white;
+}
+
+.pad-playbar {
+	-fx-accent: #ff0000ff;
+}
+
+.pad:play {
+	-fx-background-color: #aa5555bb;
+}
+.pad:warn {
+	-fx-background-color: #cc0000bb;
+}
+.pad:fade {
+	-fx-background-color: #99bb88bb;
+}
+
+.current-page-button {
+	-fx-base: lightgray;
+}
+
+/*Notification Bar*/
+.notification-pane.dark .notification-bar > .pane {
+    -fx-background-color: linear-gradient(#D6D6D6, #CCCCCC 37%, #ABABAB);
+    -fx-padding: 0 7 0 7;
+}
+
+.notification-pane.top .notification-bar > .pane {
+    -fx-background-insets: 0 0 0 0, 0 0 1 0, 0 0 2 0;
+}
+
+.notification-pane.bottom .notification-bar > .pane {
+    -fx-background-insets: 0 0 0 0, 1 0 0 0, 2 0 0 0;
+}
+
+.notification-pane .notification-bar > .pane .label {
+    -fx-font-size: 1.166667em; /*15px;*/
+    -fx-text-fill: #292929;
+}
diff --git a/PlayWall/assets/de/tobias/playpad/assets/style/Light.css b/PlayWall/assets/de/tobias/playpad/assets/style/Light.css
new file mode 100644
index 0000000000000000000000000000000000000000..6f0efc0bdbdeccbdf92a148a74d87b100f989b4a
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/style/Light.css
@@ -0,0 +1,71 @@
+.root {
+	/*-fx-base: rgb(40, 40, 40);*/
+	/*-fx-background: rgb(40, 40, 40);*/
+	/*-fx-control-inner-background:  rgb(45, 45, 45);*/
+}
+ 
+.menu-bar {
+	-fx-background-color: linear-gradient(to bottom, -fx-base, derive(-fx-base, 15%));
+}
+
+.menu:hover, 
+.menu-item:hover, 
+.menu:showing, 
+.menu-item:focused, 
+.list-view .list-cell:selected, 
+.combo-box-popup .list-view .list-cell:filled:selected, 
+.combo-box-popup .list-view .list-cell:filled:selected:hover, 
+.combo-box-popup .list-view .list-cell:filled:hover {
+	-fx-background-color: rgb(200, 200, 200);
+	-fx-text-fill: white;
+}
+
+.tool-bar:horizontal {
+	-fx-border: 1px 0px 1px 0px;
+	-fx-border-color: black;
+}
+ 
+.button:hover {
+	-fx-color: -fx-hover-base;
+}
+ 
+.table-view {
+	-fx-table-cell-border-color:derive(-fx-base,+10%);
+	-fx-table-header-border-color:derive(-fx-base,+20%);
+}
+ 
+.split-pane:horizontal > * > .split-pane-divider {
+	-fx-border-color: transparent -fx-base transparent -fx-base;
+	-fx-background-color: transparent, derive(-fx-base,20%);
+	-fx-background-insets: 0, 0 1 0 1;
+}
+
+.fonticon {
+	-fx-text-fill: black;
+}
+
+.label {
+	-fx-text-fill: black;
+}
+
+.progress-bar {
+	-fx-accent: black;
+}
+
+.notification-pane.dark .notification-bar > .pane .label {
+    -fx-text-fill: #ebebeb;
+}
+
+.pad:play {
+	-fx-background-color: #aa5555bb;
+}
+.pad:warn {
+	-fx-background-color: #cc0000bb;
+}
+.pad:fade {
+	-fx-background-color: #ff9933bb;
+}
+
+.current-page-button {
+	-fx-base: lightgray;
+}
diff --git a/PlayWall/assets/de/tobias/playpad/assets/style/Twilight.css b/PlayWall/assets/de/tobias/playpad/assets/style/Twilight.css
new file mode 100644
index 0000000000000000000000000000000000000000..bdc0554fce821d7b3f1489ed887b47f369ef239a
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/style/Twilight.css
@@ -0,0 +1,96 @@
+.root {
+	-fx-base: rgb(40, 40, 50);
+	-fx-background: rgb(40, 40, 50);
+	-fx-control-inner-background:  rgb(40, 40, 50);
+}
+ 
+.tab {
+	-fx-background-color: linear-gradient(to top, -fx-base, derive(-fx-base,30%));
+}
+
+.tab:selected {
+	-fx-background-color: linear-gradient(to bottom, -fx-base, derive(-fx-base,30%));
+}
+ 
+.menu-bar {
+	-fx-background-color: linear-gradient(to top, -fx-base, derive(-fx-base,30%));
+}
+ 
+.menu:hover, 
+.menu-item:hover, 
+.menu:showing, 
+.menu-item:focused, 
+.list-view .list-cell:selected, 
+.combo-box-popup .list-view .list-cell:filled:selected, 
+.combo-box-popup .list-view .list-cell:filled:selected:hover, 
+.combo-box-popup .list-view .list-cell:filled:hover{
+	-fx-background-color: rgb(70, 70, 90);
+	-fx-text-fill: white;
+}
+
+.tool-bar:horizontal {
+	-fx-background-color: linear-gradient(to bottom, derive(-fx-base,+20%), derive(-fx-base,+0%));
+}
+ 
+.button {
+	-fx-base: rgb(20, 20, 30);
+}
+ 
+.button:hover {
+	-fx-background-color: -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
+	-fx-color: -fx-hover-base;
+}
+ 
+.table-view {
+	-fx-table-cell-border-color:derive(-fx-base,+10%);
+	-fx-table-header-border-color:derive(-fx-base,+20%);
+}
+ 
+ 
+.fonticon {
+	-fx-text-fill: white;
+}
+
+.label {
+	-fx-text-fill: white;
+	-fx-fill: white;
+}
+
+.pad-playbar {
+	-fx-accent: white;
+}
+
+.pad:play {
+	-fx-background-color: #aa5555bb;
+}
+
+.pad:warn {
+	-fx-background-color: #cc0000bb;
+}
+
+.pad:fade {
+	-fx-background-color: #999988bb;
+}
+
+.current-page-button {
+	-fx-base: lightgray;
+}
+
+/*Notification Bar*/
+.notification-pane.dark .notification-bar > .pane {
+    -fx-background-color: linear-gradient(#D6D6D6, #CCCCCC 37%, #ABABAB);
+    -fx-padding: 0 7 0 7;
+}
+
+.notification-pane.top .notification-bar > .pane {
+    -fx-background-insets: 0 0 0 0, 0 0 1 0, 0 0 2 0;
+}
+
+.notification-pane.bottom .notification-bar > .pane {
+    -fx-background-insets: 0 0 0 0, 1 0 0 0, 2 0 0 0;
+}
+
+.notification-pane .notification-bar > .pane .label {
+    -fx-font-size: 1.166667em; /*15px;*/
+    -fx-text-fill: #292929;
+}
diff --git a/PlayWall/assets/de/tobias/playpad/assets/style/launchDialog_style.css b/PlayWall/assets/de/tobias/playpad/assets/style/launchDialog_style.css
new file mode 100644
index 0000000000000000000000000000000000000000..5140429aa49a7b813a470a5d749b29b6df9d8810
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/style/launchDialog_style.css
@@ -0,0 +1,72 @@
+/*projectList */
+#list .list-cell {
+    -fx-skin: "com.sun.javafx.scene.control.skin.ListCellSkin";
+    -fx-background-color: -fx-base;
+    -fx-padding: 10px;
+    -fx-text-fill: -fx-text-inner-color;
+    -fx-opacity: 1;
+}
+
+#list .list-cell:filled {
+    /*-fx-background-color: derive(-fx-control-inner-background,-5%);*/
+    -fx-border-width: 0px 0px 1px 0px;
+    -fx-border-color: #00000044;
+}
+
+#list .list-view:focused .list-cell:focused {
+    -fx-background-color: derive(-fx-hover-base,+50%);
+    -fx-background-insets: 0, 1, 2;
+}
+
+#list .list-view:focused .list-cell:focused:odd {
+    -fx-background-color: derive(-fx-hover-base,+50%);
+    -fx-background-insets: 0, 1, 2;
+}
+
+/* When the list-cell is selected and focused */
+#list .list-view:focused .list-cell:filled:focused:selected {
+    -fx-background-color: derive(-fx-hover-base,+50%);
+    -fx-background-insets: 0, 1, 2;
+    -fx-background: -fx-base;
+    -fx-text-fill: -fx-selection-bar-text;
+}
+
+#list .list-view:focused .list-cell:filled:selected, #list .list-view:focused .list-cell:filled:selected:hover {
+    -fx-background: -fx-base;
+    -fx-background-color: derive(-fx-hover-base,+50%);
+    -fx-text-fill: -fx-selection-bar-text;
+}
+
+#list .list-view:focused .list-cell:filled:focused:selected:hover {
+    -fx-background: -fx-base;
+    -fx-background-color: derive(-fx-hover-base,+50%);
+    -fx-background-insets: 0, 1, 2;
+    -fx-text-fill: -fx-selection-bar-text;
+}
+
+/* When the ListView is _not_ focused, we show alternate selection colors */
+#list .list-cell:filled:selected:focused, #list .list-cell:filled:selected, .list-view:horizontal .list-cell:filled:selected {
+    -fx-background-color: lightgray;
+    -fx-text-fill: -fx-selection-bar-text;
+}
+
+#list .list-cell:filled:selected:focused:disabled, #list .list-cell:filled:selected:disabled {
+    -fx-opacity: -fx-disabled-opacity;
+}
+
+#list .list-cell:filled:hover {
+    -fx-background-color: -fx-hover-base;
+    -fx-text-fill: -fx-text-inner-color;
+}
+
+#list .list-view:focused .list-cell:filled:focused:hover {
+    -fx-background-color: derive(-fx-hover-base,+50%);
+
+    -fx-background-insets: 0, 1, 2;
+    -fx-text-fill: -fx-text-inner-color;
+}
+
+#list .list-view:horizontal .list-cell:filled:selected, #list .list-view:horizontal .list-cell:filled:selected:hover {
+    -fx-background-color: derive(-fx-hover-base,+50%);
+}
+
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/actions/cartAction.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/actions/cartAction.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..249047f8ba33c886d0fc46d1ca88d9fc76d2a1bc
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/actions/cartAction.fxml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox fx:id="rootContainer" maxWidth="1.7976931348623157E308" spacing="14.0" VBox.vgrow="ALWAYS" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <Label text="%cartAction.label.headline" underline="true" />
+      <VBox fx:id="settingsView">
+         <children>
+            <HBox alignment="CENTER_LEFT" spacing="14.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" minWidth="150.0" text="%cartAction.label.type" />
+                  <ComboBox fx:id="controlMode" prefWidth="150.0" />
+               </children>
+            </HBox>
+         </children>
+      </VBox>
+      <VBox fx:id="settingsView1">
+         <children>
+            <HBox alignment="CENTER_LEFT" spacing="14.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" minWidth="150.0" text="%cartAction.label.autoColor" />
+                  <CheckBox fx:id="autoColorCheckbox" mnemonicParsing="false" text="%cartAction.checkbox.autoColor" />
+               </children>
+            </HBox>
+         </children>
+      </VBox>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/actions/cartActions.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/actions/cartActions.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..f51a447b46c39cce3eed03f403278af7ff0e9b40
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/actions/cartActions.fxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+
+<VBox fx:id="buttonVbox" spacing="7.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox fx:id="pageHbox" minHeight="20.0" spacing="7.0" VBox.vgrow="NEVER" />
+      <GridPane fx:id="gridPane" alignment="CENTER" hgap="7.0" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" vgap="7.0" VBox.vgrow="NEVER">
+        <columnConstraints>
+          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
+          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
+        </columnConstraints>
+        <rowConstraints>
+          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        </rowConstraints>
+         <VBox.margin>
+            <Insets />
+         </VBox.margin>
+      </GridPane>
+      <Separator prefWidth="200.0" />
+      <VBox fx:id="cartActionContainer" minHeight="20.0" />
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/audio/clipSettings.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/audio/clipSettings.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..dec8adcf9d311f4a8d8c9ab7b27f9fe00a685994
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/audio/clipSettings.fxml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+
+<HBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="19.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%tinysound.label.soundcard" />
+      <ComboBox fx:id="soundCardComboBox" layoutX="118.0" layoutY="14.0" prefHeight="26.0" prefWidth="241.0" />
+      <Button fx:id="testButton" layoutX="372.0" layoutY="14.0" mnemonicParsing="false" onAction="#testButtonHandler" />
+   </children>
+</HBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/audio/tinySoundSettings.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/audio/tinySoundSettings.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..dec8adcf9d311f4a8d8c9ab7b27f9fe00a685994
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/audio/tinySoundSettings.fxml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+
+<HBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="19.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%tinysound.label.soundcard" />
+      <ComboBox fx:id="soundCardComboBox" layoutX="118.0" layoutY="14.0" prefHeight="26.0" prefWidth="241.0" />
+      <Button fx:id="testButton" layoutX="372.0" layoutY="14.0" mnemonicParsing="false" onAction="#testButtonHandler" />
+   </children>
+</HBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/main/mainMenu.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainMenu.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..65407383ec6125fd235602d2e35b4814394689fd
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainMenu.fxml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.input.*?>
+
+<MenuBar fx:id="menuBar" prefHeight="29.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.tobias.playpad.viewcontroller.main.MainMenuBarController">
+   <menus>
+      <Menu mnemonicParsing="false" text="%main.menu.file">
+         <items>
+            <MenuItem mnemonicParsing="false" onAction="#newDocumentHandler" text="%main.menuitem.new">
+               <accelerator>
+                  <KeyCodeCombination alt="UP" code="N" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+               </accelerator>
+            </MenuItem>
+            <MenuItem mnemonicParsing="false" onAction="#openDocumentHandler" text="%main.menuitem.project">
+               <accelerator>
+                  <KeyCodeCombination alt="UP" code="O" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+               </accelerator>
+            </MenuItem>
+            <MenuItem fx:id="saveMenuItem" mnemonicParsing="false" onAction="#saveMenuHandler" text="%main.menuitem.save">
+               <accelerator>
+                  <KeyCodeCombination alt="UP" code="S" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+               </accelerator>
+            </MenuItem>
+            <Menu fx:id="recentOpenMenu" mnemonicParsing="false" text="%main.menuitem.recentFiles" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem fx:id="profileMenu" mnemonicParsing="false" onAction="#profileMenuHandler" text="%main.menuitem.profile" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" onAction="#printMenuHandler" text="%main.menuitem.print">
+               <accelerator>
+                  <KeyCodeCombination alt="UP" code="P" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+               </accelerator></MenuItem>
+         </items>
+      </Menu>
+      <Menu mnemonicParsing="false" text="%main.menu.option">
+         <items>
+            <CheckMenuItem fx:id="dndModeMenuItem" mnemonicParsing="false" onAction="#dndModeHandler" text="%main.menuitem.dnd">
+               <accelerator>
+                  <KeyCodeCombination alt="UP" code="M" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+               </accelerator>
+            </CheckMenuItem>
+            <MenuItem fx:id="errorMenu" mnemonicParsing="false" onAction="#errorMenuHandler" text="%main.menuitem.errors">
+               <accelerator>
+                  <KeyCodeCombination alt="UP" code="E" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+               </accelerator>
+            </MenuItem>
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" onAction="#pluginMenuItemHandler" text="%main.menuitem.plugins" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <CheckMenuItem fx:id="quickEditMenuItem" mnemonicParsing="false" onAction="#quickEditMenuHandler" text="Quick Edit" visible="false" />
+            <MenuItem fx:id="settingsMenuItem" mnemonicParsing="false" onAction="#settingsHandler" text="%main.menuitem.settings">
+               <accelerator>
+                  <KeyCodeCombination alt="UP" code="COMMA" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+               </accelerator>
+            </MenuItem>
+         </items>
+      </Menu>
+      <Menu mnemonicParsing="false" text="%main.menu.view">
+         <items>
+            <CheckMenuItem fx:id="alwaysOnTopItem" mnemonicParsing="false" onAction="#alwaysOnTopItemHandler" text="%main.menuitem.onTop" />
+            <CheckMenuItem fx:id="fullScreenMenuItem" mnemonicParsing="false" onAction="#fullScreenMenuItemHandler" text="%main.menuitem.fullScreen">
+               <accelerator>
+                  <KeyCodeCombination alt="UP" code="F" control="UP" meta="UP" shift="DOWN" shortcut="DOWN" />
+               </accelerator></CheckMenuItem>
+         </items>
+      </Menu>
+      <Menu fx:id="extensionMenu" mnemonicParsing="false" text="%main.menu.extension" />
+      <Menu mnemonicParsing="false" text="%main.menu.info">
+         <items>
+            <MenuItem mnemonicParsing="false" onAction="#aboutMenuHandler" text="%main.menuitem.about" />
+            <MenuItem mnemonicParsing="false" onAction="#visiteWebsiteMenuHandler" text="%main.menuitem.website" />
+            <MenuItem mnemonicParsing="false" onAction="#sendErrorMenuItem" text="%main.menuitem.senderror" />
+         </items>
+      </Menu>
+   </menus>
+</MenuBar>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/main/mainToolbarView.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainToolbarView.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..6688f5fbdf89a9bfd687e8d0c64c1f09825ca457
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainToolbarView.fxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.text.*?>
+
+<ToolBar fx:id="toolbar" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.tobias.playpad.viewcontroller.main.MainToolbarController">
+   <items>
+      <HBox fx:id="toolbarHBox" alignment="CENTER_LEFT" maxWidth="1.7976931348623157E308" prefHeight="28.0" prefWidth="586.0" spacing="14.0">
+         <children>
+            <HBox fx:id="pageHBox" alignment="CENTER_LEFT" spacing="14.0" HBox.hgrow="ALWAYS" />
+            <HBox alignment="CENTER" spacing="7.0" HBox.hgrow="NEVER">
+               <children>
+                  <Label fx:id="volumeDownLabel">
+                     <font>
+                        <Font size="24.0" />
+                     </font>
+                  </Label>
+                  <Slider fx:id="volumeSlider" focusTraversable="false" max="1.0" />
+                  <Label fx:id="volumeUpLabel">
+                     <font>
+                        <Font size="24.0" />
+                     </font>
+                  </Label>
+               </children>
+            </HBox>
+         </children>
+      </HBox>
+   </items>
+</ToolBar>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/main/mainView.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainView.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..42936d2dd659548c8a2115bf5153f2c11155c90a
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainView.fxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.text.*?>
+<?import javafx.scene.input.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <VBox layoutX="-0.7071067690849304" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+         <children>
+            <fx:include fx:id="menuBar" source="mainMenu.fxml" />
+            <fx:include fx:id="toolbar" source="mainToolbarView.fxml" />
+            <AnchorPane fx:id="gridContainer" layoutX="-0.7071067690849304" layoutY="68.29289245605469" AnchorPane.bottomAnchor="-0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="69.0" VBox.vgrow="ALWAYS">
+               <children>
+                  <GridPane fx:id="padGridPane" layoutX="0.7071067690849304" layoutY="0.7071075439453125" prefHeight="331.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+      </GridPane>
+               </children>
+            </AnchorPane>
+         </children>
+      </VBox>
+      <Label fx:id="liveLabel" alignment="CENTER" mouseTransparent="true" prefHeight="40.0" prefWidth="600.0" text="%main.label.live" textFill="RED" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="29.0">
+         <font>
+            <Font name="System Bold" size="26.0" />
+         </font>
+      </Label>
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/mapper/keyboard.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/mapper/keyboard.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..628ecfc28b7461cc828d1c324329a22050c29746
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/mapper/keyboard.fxml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox alignment="CENTER_LEFT" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%keyboard.label.key" />
+            <Label fx:id="keyLabel" prefWidth="68.0" text="KEY" />
+            <Button fx:id="mappingButton" mnemonicParsing="false" onAction="#mappingButtonHandler" prefWidth="68.0" text="%keyboard.button.new" />
+         </children>
+      </HBox>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/mapper/midi.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/mapper/midi.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..f0c21f66c26388cbcdebd44d7120129a5944a8b1
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/mapper/midi.fxml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+
+
+<VBox fx:id="root" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox alignment="CENTER_LEFT" spacing="14.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="18.0" layoutY="76.0" prefWidth="150.0" text="%midi.label.key" />
+            <Label fx:id="midiInputKeyLabel" prefWidth="68.0" />
+            <Button fx:id="midiInputRecordButton" layoutX="167.0" layoutY="71.0" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#midiInputRecordButtonHandler" prefWidth="68.0" text="%midi.button.new" />
+         </children>
+      </HBox>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/audioTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/audioTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..86cb23c1f4f1362e39a0d79c5b87ea3147c51acd
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/audioTab.fxml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox layoutX="14.0" layoutY="14.0" spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" layoutX="14.0" layoutY="19.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.audio.type" />
+            <ComboBox fx:id="audioTypeComboBox" layoutX="156.0" layoutY="14.0" prefHeight="26.0" prefWidth="226.0" />
+         </children>
+      </HBox>
+      <AnchorPane fx:id="audioUserInfoSettings" layoutX="14.0" layoutY="53.0" prefHeight="312.0" prefWidth="617.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="53.0" />
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/feedback/doubleFeedback.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/feedback/doubleFeedback.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..6f57c1dc8b58e67d72b76d1880f95b59ad7a8494
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/feedback/doubleFeedback.fxml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import javafx.scene.shape.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox fx:id="defaultColorParent" maxWidth="1.7976931348623157E308" spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" layoutX="24.0" layoutY="237.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%doubleFeedback.label.colorDefault" />
+            <StackPane layoutX="122.0" layoutY="232.0" maxWidth="1.7976931348623157E308" prefWidth="150.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Rectangle fx:id="colorPreviewDefault" arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="26.0" layoutX="122.0" layoutY="272.0" stroke="BLACK" strokeType="INSIDE" width="128.0" StackPane.alignment="CENTER_LEFT" />
+                  <Button fx:id="colorChooseDefaultButton" alignment="CENTER_RIGHT" layoutX="122.0" layoutY="232.0" maxWidth="150.0" mnemonicParsing="false" onAction="#colorChooseButtonHandler" prefWidth="150.0" style="-fx-background-color: transparent;" StackPane.alignment="CENTER_LEFT" />
+               </children>
+            </StackPane>
+         </children>
+      </HBox>
+      <HBox fx:id="eventColorParent" spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" layoutX="24.0" layoutY="237.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%doubleFeedback.label.colorEvent" />
+            <StackPane layoutX="122.0" layoutY="232.0" maxWidth="1.7976931348623157E308" prefWidth="150.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Rectangle fx:id="colorPreviewEvent" arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="26.0" layoutX="122.0" layoutY="272.0" stroke="BLACK" strokeType="INSIDE" width="128.0" StackPane.alignment="CENTER_LEFT" />
+                  <Button fx:id="colorChooseEventButton" alignment="CENTER_RIGHT" layoutX="122.0" layoutY="232.0" maxWidth="150.0" mnemonicParsing="false" onAction="#colorChooseButtonHandler" prefWidth="150.0" style="-fx-background-color: transparent;" StackPane.alignment="CENTER_LEFT" />
+               </children>
+            </StackPane>
+         </children>
+      </HBox>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/feedback/singleFeedback.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/feedback/singleFeedback.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..220768e7c8a47281604d955706edb994083886fd
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/feedback/singleFeedback.fxml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import javafx.scene.shape.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox fx:id="defaultColorParent" alignment="CENTER_LEFT" maxWidth="1.7976931348623157E308" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="24.0" layoutY="237.0" prefWidth="150.0" text="%doubleFeedback.label.colorDefault" />
+            <StackPane layoutX="122.0" layoutY="232.0" maxWidth="1.7976931348623157E308" prefWidth="150.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Rectangle fx:id="colorPreviewDefault" arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="26.0" layoutX="122.0" layoutY="272.0" stroke="BLACK" strokeType="INSIDE" width="128.0" StackPane.alignment="CENTER_LEFT" />
+                  <Button fx:id="colorChooseDefaultButton" alignment="CENTER_RIGHT" layoutX="122.0" layoutY="232.0" maxWidth="150.0" mnemonicParsing="false" onAction="#colorChooseButtonHandler" prefWidth="150.0" style="-fx-background-color: transparent;" StackPane.alignment="CENTER_LEFT" />
+               </children>
+            </StackPane>
+         </children>
+      </HBox>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/generalTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/generalTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..0e7c0a04dfb157dc027271d81c6708ebd787d6fe
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/generalTab.fxml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import java.lang.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox prefWidth="587.0" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <Label text="%settings.gen.label.view" underline="true" />
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" layoutX="21.0" layoutY="40.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.pages" />
+            <TextField fx:id="pageCountTextField" prefWidth="50.0" />
+         </children>
+      </HBox>
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" layoutX="20.0" layoutY="68.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.columns" />
+            <TextField fx:id="columnTextField" prefWidth="50.0" />
+         </children>
+      </HBox>
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" layoutX="18.0" layoutY="96.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.rows" />
+            <TextField fx:id="rowTextField" prefWidth="50.0" />
+         </children>
+      </HBox>
+      <Separator prefHeight="2.0" prefWidth="600.0" />
+      <Label text="%settings.gen.label.additional" underline="true" />
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" maxWidth="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.liveMode" />
+            <CheckBox fx:id="liveModeCheckBox" layoutX="30.0" layoutY="269.0" mnemonicParsing="false" text="%settings.gen.checkbox.liveMode" AnchorPane.leftAnchor="30.0" AnchorPane.topAnchor="269.0" />
+         </children>
+      </HBox>
+      <Label text="%settings.gen.label.liveModeInfo" wrapText="true">
+         <VBox.margin>
+            <Insets left="164.0" />
+         </VBox.margin>
+      </Label>
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.cache.label" />
+            <TextField fx:id="cacheTextField" promptText="C:\Users\Max\Cache" HBox.hgrow="ALWAYS" />
+            <Button mnemonicParsing="false" onAction="#cacheChooseHandler" text="%settings.gen.cache.button.choose" />
+         </children>
+      </HBox>
+      <HBox alignment="CENTER_LEFT" spacing="14.0">
+         <children>
+            <Label prefWidth="150.0" />
+            <Button mnemonicParsing="false" onAction="#cacheResetButtonHandler" text="%settings.gen.cache.button.reset" />
+            <Label fx:id="cacheSizeLabel" text="Label" />
+         </children>
+      </HBox>
+      <Label text="%settings.gen.cache.label.info" wrapText="true">
+         <VBox.margin>
+            <Insets left="164.0" />
+         </VBox.margin>
+      </Label>
+      <Separator prefWidth="200.0" />
+      <Button alignment="TOP_LEFT" mnemonicParsing="false" onAction="#resetDialogs" text="%settings.gen.warning.button.reset">
+         <VBox.margin>
+            <Insets left="164.0" />
+         </VBox.margin></Button>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/classicLayoutCart.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/classicLayoutCart.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..6b90344ea45255ee05b1260e936ca459f84becfb
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/classicLayoutCart.fxml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox prefHeight="100.0" prefWidth="517.0" spacing="14.0" VBox.vgrow="ALWAYS">
+         <children>
+            <VBox alignment="BOTTOM_LEFT" maxWidth="-Infinity" prefWidth="150.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%layout.label.color" textAlignment="RIGHT" VBox.vgrow="ALWAYS" />
+               </children>
+            </VBox>
+            <VBox layoutX="110.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="110.0" layoutY="8.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.background" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <ColorPicker fx:id="backgroundColorPicker" layoutX="110.0" layoutY="68.0" maxWidth="1.7976931348623157E308" />
+               </children>
+            </VBox>
+            <VBox layoutX="243.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.playground" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <ColorPicker fx:id="playgroundColorPicker" layoutX="244.0" layoutY="68.0" maxWidth="1.7976931348623157E308" />
+               </children>
+            </VBox>
+            <VBox layoutX="374.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="374.0" layoutY="8.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.warnColor" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <ColorPicker fx:id="warnColorPicker" layoutX="374.0" layoutY="68.0" maxWidth="1.7976931348623157E308" />
+               </children>
+            </VBox>
+            <VBox layoutX="507.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="508.0" layoutY="8.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.fadeColor" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <ColorPicker fx:id="fadeColorPicker" layoutX="507.0" layoutY="68.0" maxWidth="1.7976931348623157E308" />
+               </children>
+            </VBox>
+         </children>
+      </HBox>
+      <Separator prefHeight="3.0" prefWidth="600.0" />
+      <HBox spacing="14.0" VBox.vgrow="ALWAYS">
+         <children>
+            <VBox alignment="BOTTOM_LEFT" layoutX="26.0" layoutY="184.0" prefWidth="150.0" spacing="23.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" layoutX="26.0" layoutY="184.0" prefWidth="150.0" text="%layout.label.color" textAlignment="RIGHT" AnchorPane.leftAnchor="26.0" />
+               </children>
+               <HBox.margin>
+                  <Insets bottom="7.0" />
+               </HBox.margin>
+            </VBox>
+            <VBox layoutX="109.0" layoutY="154.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Label alignment="TOP_CENTER" layoutX="109.0" layoutY="154.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.infoLabel" VBox.vgrow="ALWAYS" />
+                  <ColorPicker fx:id="infoLabelColorPicker" layoutX="109.0" layoutY="179.0" maxWidth="1.7976931348623157E308" />
+               </children>
+            </VBox>
+            <VBox layoutX="243.0" layoutY="154.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Label alignment="TOP_CENTER" layoutX="243.0" layoutY="154.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.titleLabel" AnchorPane.leftAnchor="243.0" VBox.vgrow="ALWAYS" />
+                  <ColorPicker fx:id="titleLabelColorPicker" layoutX="243.0" layoutY="179.0" maxWidth="1.7976931348623157E308" AnchorPane.leftAnchor="243.0" />
+               </children>
+            </VBox>
+            <VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" HBox.hgrow="ALWAYS" />
+            <VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" HBox.hgrow="ALWAYS" />
+         </children>
+      </HBox>
+      <Button fx:id="resetButton" mnemonicParsing="false" onAction="#resetButtonHandler" text="%layout.button.reset">
+         <VBox.margin>
+            <Insets left="164.0" />
+         </VBox.margin></Button>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/classicLayoutGlobal.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/classicLayoutGlobal.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..31b762d687e55fa46cb2b26b38753ad090174797
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/classicLayoutGlobal.fxml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox spacing="14.0">
+         <children>
+            <VBox spacing="14.0">
+               <children>
+                  <HBox alignment="CENTER_LEFT" layoutX="23.0" layoutY="193.0" spacing="14.0">
+                     <children>
+                        <Label alignment="CENTER_RIGHT" layoutX="23.0" layoutY="198.0" minWidth="150.0" prefWidth="150.0" text="%layout.label.programmLayout" />
+                        <ComboBox fx:id="programLayoutComboBox" layoutX="134.0" layoutY="193.0" prefWidth="150.0" />
+                     </children>
+                  </HBox>
+                  <HBox alignment="CENTER_LEFT" layoutX="23.0" layoutY="225.0" spacing="14.0">
+                     <children>
+                        <Label alignment="CENTER_RIGHT" layoutX="23.0" layoutY="226.0" minWidth="150.0" prefWidth="150.0" text="%layout.label.customLayout" />
+                        <CheckBox fx:id="customLayoutCheckBox" layoutX="134.0" layoutY="225.0" mnemonicParsing="false" text="%settings.checkbox.activate" />
+                     </children>
+                  </HBox>
+               </children>
+            </VBox>
+            <HBox alignment="CENTER_LEFT" spacing="14.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" layoutX="362.0" layoutY="193.0" prefWidth="150.0" text="%layout.label.baseColor" />
+                  <ColorPicker fx:id="accentColorChooser" layoutX="420.0" layoutY="196.0" />
+               </children>
+            </HBox>
+         </children>
+      </HBox>
+      <VBox fx:id="customizeView" spacing="14.0">
+         <children>
+            <Separator prefWidth="200.0" />
+            <HBox prefWidth="517.0" spacing="14.0">
+               <children>
+                  <VBox alignment="BOTTOM_LEFT" prefWidth="150.0">
+                     <children>
+                        <Label alignment="CENTER_RIGHT" maxWidth="1.7976931348623157E308" text="%layout.label.color" VBox.vgrow="ALWAYS" />
+                     </children>
+                  </VBox>
+                  <VBox layoutX="110.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+                     <children>
+                        <Label alignment="BOTTOM_LEFT" layoutX="110.0" layoutY="8.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.background" wrapText="true" VBox.vgrow="ALWAYS" />
+                        <ColorPicker fx:id="backgroundColorPicker" layoutX="110.0" layoutY="68.0" maxWidth="1.7976931348623157E308" />
+                     </children>
+                  </VBox>
+                  <VBox layoutX="243.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+                     <children>
+                        <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.playground" wrapText="true" VBox.vgrow="ALWAYS" />
+                        <ColorPicker fx:id="playgroundColorPicker" layoutX="244.0" layoutY="68.0" maxWidth="1.7976931348623157E308" />
+                     </children>
+                  </VBox>
+                  <VBox layoutX="374.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+                     <children>
+                        <Label alignment="BOTTOM_LEFT" layoutX="374.0" layoutY="8.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.warnColor" wrapText="true" VBox.vgrow="ALWAYS" />
+                        <ColorPicker fx:id="warnColorPicker" layoutX="374.0" layoutY="68.0" maxWidth="1.7976931348623157E308" />
+                     </children>
+                  </VBox>
+                  <VBox layoutX="507.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+                     <children>
+                        <Label alignment="BOTTOM_LEFT" layoutX="508.0" layoutY="8.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="%layout.label.fadeColor" wrapText="true" VBox.vgrow="ALWAYS" />
+                        <ColorPicker fx:id="fadeColorPicker" layoutX="507.0" layoutY="68.0" maxWidth="1.7976931348623157E308" />
+                     </children>
+                  </VBox>
+               </children>
+            </HBox>
+            <Separator prefHeight="3.0" prefWidth="600.0" />
+            <HBox spacing="14.0">
+               <children>
+                  <VBox alignment="BOTTOM_LEFT" layoutX="26.0" layoutY="184.0" prefWidth="150.0" spacing="23.0">
+                     <children>
+                        <Label alignment="CENTER_RIGHT" layoutX="26.0" layoutY="184.0" maxWidth="1.7976931348623157E308" text="%layout.label.color" AnchorPane.leftAnchor="26.0" VBox.vgrow="ALWAYS" />
+                        <Label alignment="CENTER_RIGHT" layoutX="26.0" layoutY="224.0" maxWidth="1.7976931348623157E308" text="%layout.label.fontSize" AnchorPane.leftAnchor="26.0" VBox.vgrow="ALWAYS" />
+                     </children>
+                     <HBox.margin>
+                        <Insets bottom="7.0" />
+                     </HBox.margin>
+                  </VBox>
+                  <VBox layoutX="109.0" layoutY="154.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+                     <children>
+                        <Label alignment="TOP_CENTER" layoutX="109.0" layoutY="154.0" maxWidth="1.7976931348623157E308" text="%layout.label.infoLabel" VBox.vgrow="ALWAYS" />
+                        <ColorPicker fx:id="infoLabelColorPicker" layoutX="109.0" layoutY="179.0" maxWidth="1.7976931348623157E308" />
+                        <ComboBox fx:id="infoLabelFontSizeComboBox" editable="true" maxWidth="1.7976931348623157E308" />
+                     </children>
+                  </VBox>
+                  <VBox layoutX="243.0" layoutY="154.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" spacing="14.0" HBox.hgrow="ALWAYS">
+                     <children>
+                        <Label alignment="TOP_CENTER" layoutX="243.0" layoutY="154.0" maxWidth="1.7976931348623157E308" text="%layout.label.titleLabel" AnchorPane.leftAnchor="243.0" VBox.vgrow="ALWAYS" />
+                        <ColorPicker fx:id="titleLabelColorPicker" layoutX="243.0" layoutY="179.0" maxWidth="1.7976931348623157E308" AnchorPane.leftAnchor="243.0" />
+                        <ComboBox fx:id="titleLabelFontSizeComboBox" editable="true" maxWidth="1.7976931348623157E308" />
+                     </children>
+                  </VBox>
+                  <VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" HBox.hgrow="ALWAYS" />
+                  <VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" HBox.hgrow="ALWAYS" />
+               </children>
+            </HBox>
+         </children>
+      </VBox>
+      <Button fx:id="resetButton" mnemonicParsing="false" onAction="#resetButtonHandler" text="%layout.button.reset">
+         <VBox.margin>
+            <Insets left="164.0" />
+         </VBox.margin></Button>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutCart.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutCart.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..47f1ad840bd6cebeedff224dff9332c4c32d01a4
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutCart.fxml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.shape.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox spacing="14.0">
+         <children>
+            <VBox alignment="BOTTOM_LEFT" prefWidth="150.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%layout.label.color" VBox.vgrow="ALWAYS">
+                     <VBox.margin>
+                        <Insets bottom="5.0" />
+                     </VBox.margin></Label>
+               </children>
+            </VBox>
+            <VBox layoutX="110.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="125.0" spacing="14.0">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="110.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" text="%layout.label.background" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <Button fx:id="backgroundColorButton" focusTraversable="false" mnemonicParsing="false" onAction="#backgroundColorButtonHandler" prefWidth="150.0" />
+               </children>
+            </VBox>
+            <VBox layoutX="243.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="125.0" spacing="14.0">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" text="%layout.label.playground" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <Button fx:id="playColorButton" focusTraversable="false" mnemonicParsing="false" onAction="#playColorButtonHandler" prefWidth="150.0" />
+               </children>
+            </VBox>
+            <VBox maxWidth="1.7976931348623157E308" prefWidth="150.0" spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" text="%layout.label.animation" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <CheckBox fx:id="warnAnimationCheckBox" mnemonicParsing="false" text="%layout.label.warnAnimation" />
+               </children>
+            </VBox>
+         </children>
+      </HBox>
+      <Button fx:id="resetButton" mnemonicParsing="false" onAction="#resetButtonHandler" text="%layout.button.reset">
+         <VBox.margin>
+            <Insets left="164.0" />
+         </VBox.margin></Button>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutGlobal.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutGlobal.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..c80cc9f2edd3d4183eb2ed67078c54c9fc22f799
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutGlobal.fxml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.shape.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox prefHeight="100.0" prefWidth="517.0" spacing="14.0">
+         <children>
+            <VBox alignment="BOTTOM_LEFT" prefWidth="150.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%layout.label.color" VBox.vgrow="ALWAYS">
+                     <VBox.margin>
+                        <Insets bottom="5.0" />
+                     </VBox.margin></Label>
+               </children>
+            </VBox>
+            <VBox layoutX="110.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="150.0" spacing="14.0">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="110.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" text="%layout.label.background" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <Button fx:id="backgroundColorButton" focusTraversable="false" mnemonicParsing="false" onAction="#backgroundColorButtonHandler" prefWidth="150.0" />
+               </children>
+            </VBox>
+            <VBox layoutX="243.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="150.0" spacing="14.0">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" text="%layout.label.playground" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <Button fx:id="playColorButton" focusTraversable="false" mnemonicParsing="false" onAction="#playColorButtonHandler" prefWidth="150.0" />
+               </children>
+            </VBox>
+            <VBox maxWidth="1.7976931348623157E308" prefWidth="150.0" spacing="14.0">
+               <children>
+                  <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" text="%layout.label.animation" wrapText="true" VBox.vgrow="ALWAYS" />
+                  <CheckBox fx:id="warnAnimationCheckBox" mnemonicParsing="false" text="%layout.label.warnAnimation" />
+               </children>
+            </VBox>
+         </children>
+      </HBox>
+      <Separator prefHeight="3.0" prefWidth="600.0" />
+      <HBox spacing="14.0">
+         <children>
+            <VBox alignment="BOTTOM_LEFT" layoutX="26.0" layoutY="184.0" prefWidth="150.0" spacing="23.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" layoutX="26.0" layoutY="224.0" prefWidth="150.0" text="%layout.label.fontSize" AnchorPane.leftAnchor="26.0" />
+               </children>
+               <HBox.margin>
+                  <Insets bottom="7.0" />
+               </HBox.margin>
+            </VBox>
+            <VBox layoutX="109.0" layoutY="154.0" maxWidth="1.7976931348623157E308" prefWidth="150.0" spacing="14.0">
+               <children>
+                  <Label alignment="TOP_CENTER" layoutX="109.0" layoutY="154.0" maxWidth="1.7976931348623157E308" text="%layout.label.infoLabel" VBox.vgrow="ALWAYS" />
+                  <ComboBox fx:id="infoLabelFontSizeComboBox" editable="true" prefWidth="150.0" />
+               </children>
+            </VBox>
+            <VBox layoutX="243.0" layoutY="154.0" maxWidth="1.7976931348623157E308" prefWidth="150.0" spacing="14.0">
+               <children>
+                  <Label alignment="TOP_CENTER" layoutX="243.0" layoutY="154.0" maxWidth="1.7976931348623157E308" text="%layout.label.titleLabel" AnchorPane.leftAnchor="243.0" VBox.vgrow="ALWAYS" />
+                  <ComboBox fx:id="titleLabelFontSizeComboBox" editable="true" prefWidth="150.0" />
+               </children>
+            </VBox>
+         </children>
+      </HBox>
+      <Button fx:id="resetButton" mnemonicParsing="false" onAction="#resetButtonHandler" text="%layout.button.reset">
+         <VBox.margin>
+            <Insets left="164.0" />
+         </VBox.margin></Button>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/layoutTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/layoutTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..c7049d4e4e458c03cc31508d39effa8ef640a028
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/layoutTab.fxml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import java.lang.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox alignment="CENTER_LEFT" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%settings.layout.label.type" />
+            <ComboBox fx:id="layoutTypeComboBox" prefWidth="150.0" />
+         </children>
+         <VBox.margin>
+            <Insets />
+         </VBox.margin>
+      </HBox>
+      <VBox fx:id="layoutContainer" maxWidth="1.7976931348623157E308" prefHeight="20.0" VBox.vgrow="ALWAYS" />
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/mapping.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/mapping.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..376799ae457ad29e9f71975036d099b65277c6bf
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/mapping.fxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox layoutX="14.0" layoutY="14.0" spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" layoutX="14.0" layoutY="19.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.mapping.label.mapping" />
+            <ComboBox fx:id="mappingComboBox" layoutX="100.0" layoutY="14.0" prefWidth="150.0" />
+            <Button fx:id="editMappingsButton" layoutX="264.0" layoutY="14.0" mnemonicParsing="false" onAction="#editMappingsHandler" text="%settings.mapping.button.edit" />
+         </children>
+      </HBox>
+      <HBox layoutY="50.0" spacing="14.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="50.0">
+         <children>
+            <TreeView fx:id="treeView" prefHeight="400.0" prefWidth="200.0" showRoot="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="50.0" />
+            <ScrollPane fitToWidth="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-background-color: transparent;" HBox.hgrow="ALWAYS">
+               <content>
+                  <VBox fx:id="detailView" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" spacing="14.0" />
+               </content>
+            </ScrollPane>
+         </children>
+      </HBox>
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/midiTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/midiTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..c65c10d53e6eac505cc56160ada1d49e3a428287
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/midiTab.fxml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.shape.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%settings.midi.label.device">
+               <HBox.margin>
+                  <Insets top="4.0" />
+               </HBox.margin>
+            </Label>
+            <HBox maxWidth="1.7976931348623157E308" spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <ComboBox fx:id="deviceComboBox" onAction="#deviceHandler" prefWidth="150.0" />
+                  <Pane HBox.hgrow="ALWAYS" />
+                  <CheckBox fx:id="midiActiveCheckBox" mnemonicParsing="false" text="%settings.checkbox.activate">
+                     <padding>
+                        <Insets top="5.0" />
+                     </padding>
+                     <HBox.margin>
+                        <Insets top="4.0" />
+                     </HBox.margin>
+                  </CheckBox>
+               </children>
+            </HBox>
+         </children>
+      </HBox>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/midiTab_old.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/midiTab_old.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..5923d8e0a7b57dd5fb8b9142528faf0ad80c962b
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/midiTab_old.fxml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane fx:id="rootPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox layoutX="34.0" layoutY="34.0" prefHeight="67.0" prefWidth="523.0" spacing="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
+         <children>
+            <VBox alignment="CENTER_RIGHT" layoutX="9.0" layoutY="19.0" prefHeight="67.0" spacing="25.0" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0">
+               <children>
+                  <Label layoutX="9.0" layoutY="19.0" text="%settings.midi.label.device" />
+                  <Label layoutX="11.0" layoutY="51.0" text="%settings.midi.label.preset" />
+               </children>
+            </VBox>
+            <VBox layoutX="127.0" layoutY="14.0" maxWidth="1.7976931348623157E308" spacing="14.0" HBox.hgrow="ALWAYS">
+               <children>
+                  <HBox alignment="CENTER_LEFT" layoutX="127.0" layoutY="14.0" maxWidth="1.7976931348623157E308" spacing="14.0" AnchorPane.leftAnchor="127.0" AnchorPane.rightAnchor="121.0" VBox.vgrow="ALWAYS">
+                     <children>
+                        <ComboBox fx:id="deviceComboBox" onAction="#deviceHandler" prefWidth="150.0" />
+                        <Pane HBox.hgrow="ALWAYS" />
+                        <CheckBox fx:id="midiActiveCheckBox" mnemonicParsing="false" text="%settings.checkbox.activate" />
+                     </children>
+                  </HBox>
+                  <HBox layoutX="127.0" layoutY="47.0" maxWidth="1.7976931348623157E308" spacing="14.0" VBox.vgrow="ALWAYS">
+                     <children>
+                        <ComboBox fx:id="presetsList" layoutX="127.0" layoutY="47.0" prefWidth="150.0" />
+                        <Button fx:id="presetsEditButton" layoutX="304.0" layoutY="47.0" mnemonicParsing="false" onAction="#presetsEditButtonHandler" text="%settings.midi.presetEdit" />
+                        <Button fx:id="activateButton" mnemonicParsing="false" onAction="#activateButtonHandler" text="%settings.midi.button.activate" />
+                     </children>
+                  </HBox>
+               </children>
+            </VBox>
+         </children>
+      </HBox>
+      <TreeView fx:id="contentTreeView" prefHeight="375.0" prefWidth="300.0" AnchorPane.bottomAnchor="135.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="90.0" />
+      <ComboBox fx:id="midiActionTypeComboBox" layoutX="312.0" layoutY="90.0" prefWidth="264.0" AnchorPane.leftAnchor="314.0" />
+      <AnchorPane fx:id="settingsAnchorPane" layoutX="306.0" layoutY="133.0" prefHeight="467.0" prefWidth="300.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="300.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="133.0" />
+      <HBox layoutX="14.0" layoutY="534.0" prefHeight="52.0" prefWidth="281.0" spacing="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0">
+         <children>
+            <VBox spacing="14.0">
+               <children>
+                  <Button fx:id="addMidiButton" defaultButton="true" layoutX="14.0" layoutY="319.0" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#addMidiButtonHandler" text="%settings.midi.button.add" AnchorPane.bottomAnchor="56.0" AnchorPane.leftAnchor="14.0" />
+                  <Button fx:id="addMidiDraftButton" layoutX="14.0" layoutY="354.0" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#addMidiDraftButtonHandler" text="%settings.midi.button.addDraft" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="14.0" />
+                  <Button fx:id="draftButton" mnemonicParsing="false" onAction="#draftButtonHandler" text="%settings.midi.button.saveDraft" />
+               </children>
+            </VBox>
+            <VBox spacing="14.0">
+               <children>
+                  <Button fx:id="deleteMidiButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#deleteMidiButtonHandler" text="%settings.midi.button.delete" />
+                  <Button fx:id="clearMidiButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#clearMidiButtonHandler" prefHeight="26.0" prefWidth="68.0" text="%settings.midi.button.clear" />
+               </children>
+            </VBox>
+         </children>
+      </HBox>
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/generalTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/generalTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..5e3012693a20acdcf1b1b400e7176d1b37631f31
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/generalTab.fxml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <VBox layoutX="14.0" layoutY="14.0" spacing="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
+         <children>
+            <HBox alignment="CENTER_LEFT" layoutX="14.0" layoutY="14.0" spacing="14.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="19.0" prefWidth="150.0" text="%padSettings.gen.label.title" AnchorPane.leftAnchor="14.0" />
+                  <TextField fx:id="titleTextField" layoutX="125.0" layoutY="14.0" prefWidth="250.0" AnchorPane.leftAnchor="127.0" />
+                  <VBox HBox.hgrow="ALWAYS" />
+                  <Button fx:id="deleteButton" mnemonicParsing="false" onAction="#deleteButtonHandler" text="%padSettings.button.delete" />
+               </children>
+            </HBox>
+            <HBox alignment="CENTER_LEFT" layoutX="14.0" layoutY="48.0" spacing="14.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="50.0" prefWidth="150.0" text="%padSettings.gen.label.volume" AnchorPane.leftAnchor="14.0" />
+                  <Slider fx:id="volumeSlider" layoutX="122.0" layoutY="54.0" prefWidth="250.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="100.0" AnchorPane.leftAnchor="127.0" />
+                  <VBox HBox.hgrow="ALWAYS" />
+                  <CheckBox fx:id="repeatCheckBox" mnemonicParsing="false" text="%padSettings.checkbox.loop" />
+               </children>
+            </HBox>
+            <HBox alignment="CENTER_LEFT" layoutX="14.0" layoutY="84.0" spacing="14.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="89.0" prefWidth="150.0" text="%padSettings.gen.label.timeDisplay" AnchorPane.leftAnchor="14.0" />
+                  <ComboBox fx:id="timeDisplayComboBox" layoutX="127.0" layoutY="84.0" prefWidth="250.0" AnchorPane.leftAnchor="127.0" />
+                  <VBox HBox.hgrow="ALWAYS" />
+                  <CheckBox fx:id="customTimeDisplayCheckBox" layoutX="406.0" layoutY="88.0" mnemonicParsing="false" text="%padSettings.gen.checkbox.customSettings" />
+               </children>
+            </HBox>
+         </children>
+      </VBox>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/layoutTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/layoutTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..649480a0b2de5432e38f7342dd7b1bbafa527cf0
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/layoutTab.fxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox layoutX="14.0" layoutY="13.0" spacing="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="14.0" prefWidth="150.0" text="%padSettings.layout.label.custom" />
+            <CheckBox fx:id="enableLayoutCheckBox" layoutX="127.0" layoutY="13.0" mnemonicParsing="false" text="%padSettings.layout.checkbox.custom" />
+         </children>
+         <VBox.margin>
+            <Insets />
+         </VBox.margin>
+      </HBox>
+      <VBox fx:id="layoutContainer" prefHeight="200.0" prefWidth="100.0" />
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/padSettingsView.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/padSettingsView.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..3de2d6271f86b985d4d36a09f7de44e67489dbe4
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/padSettingsView.fxml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <TabPane fx:id="tabPane" prefHeight="484.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="53.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
+      <Button fx:id="finishButton" defaultButton="true" layoutX="534.0" layoutY="497.0" mnemonicParsing="false" onAction="#finishButtonHandler" text="%padSettings.button.finish" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" />
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/playerTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/playerTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..4c4a693ff9e3adedf6579f70a46e46a8c39b3b41
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/playerTab.fxml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <VBox spacing="14.0">
+         <children>
+            <HBox layoutX="14.0" layoutY="253.0" spacing="14.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%padSettings.player.label.fade" textAlignment="RIGHT" />
+                  <CheckBox fx:id="customFadeCheckBox" mnemonicParsing="false" text="%padSettings.gen.checkbox.customSettings" />
+               </children>
+            </HBox>
+         </children>
+      </VBox>
+      <VBox fx:id="fadeContainer" minHeight="20.0" />
+      <Separator prefWidth="200.0" />
+      <VBox layoutX="14.0" layoutY="139.0" spacing="14.0">
+         <children>
+            <HBox layoutX="14.0" layoutY="139.0" spacing="14.0">
+               <children>
+                  <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%padSettings.player.label.warning" textAlignment="RIGHT" />
+                  <CheckBox fx:id="warningEnableCheckBox" mnemonicParsing="false" text="%padSettings.gen.checkbox.customSettings" />
+               </children>
+            </HBox>
+            <VBox fx:id="warningFeedbackContainer" minHeight="25.0" />
+         </children>
+      </VBox>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/cartTrigger.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/cartTrigger.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..3aee2f7dda47d7fcd51ad973ddb0a0a4a4ea055b
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/cartTrigger.fxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="BASELINE_RIGHT" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%carttrigger.label.action" />
+            <ComboBox fx:id="statusComboBox" prefWidth="150.0" />
+         </children>
+      </HBox>
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="TOP_RIGHT" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%carttrigger.label.carts" />
+            <VBox spacing="14.0">
+               <children>
+                  <CheckBox fx:id="allCartsCheckbox" mnemonicParsing="false" text="%carttrigger.checkbox.all" />
+                  <TextField fx:id="cartTextField" prefWidth="150.0" promptText="1, 3-5" />
+               </children>
+            </VBox>
+         </children>
+      </HBox>
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/triggerPoint.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/triggerPoint.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..14672bf25973b06c9e55e4404d99719c5b035326
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/triggerPoint.fxml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <ScrollPane fitToWidth="true" maxWidth="1.7976931348623157E308" prefViewportHeight="20.0" prefViewportWidth="100.0" style="-fx-background-color: transparent;" VBox.vgrow="ALWAYS">
+         <content>
+            <VBox fx:id="itemView" minHeight="20.0" minWidth="100.0" spacing="14.0" />
+         </content>
+      </ScrollPane>
+      <HBox fx:id="buttonBox" minHeight="10.0" spacing="14.0" />
+   </children>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/triggerTime.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/triggerTime.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..1b38ff3c2f2810a912106725ed630eaa0e4f2456
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/triggerTime.fxml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <Label alignment="BASELINE_RIGHT" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%triggertime.label.time" />
+      <TextField fx:id="timeTextField" prefWidth="150.0" />
+   </children>
+</HBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/triggerTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/triggerTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..e015d3a7d7ebfd570af1fe9fc500975d52ce28a5
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/triggerTab.fxml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <TreeView fx:id="treeView" showRoot="false" />
+      <VBox fx:id="contentView" minWidth="100.0" HBox.hgrow="ALWAYS">
+         <HBox.margin>
+            <Insets left="14.0" right="14.0" top="14.0" />
+         </HBox.margin>
+      </VBox>
+   </children>
+</HBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/playerTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/playerTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..9c906697b32ec661415ee0eb9ce42c57d78873a9
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/playerTab.fxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import java.lang.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <Label text="%settings.player.label.warning" underline="true" />
+      <VBox fx:id="warningFeedbackContainer" minHeight="25.0" />
+      <Separator prefWidth="200.0" />
+      <Label text="%settings.player.label.fade" underline="true" />
+      <VBox fx:id="fadeContainer" minHeight="20.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" />
+      <Separator layoutY="91.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" />
+      <HBox alignment="CENTER_LEFT" layoutX="14.0" layoutY="105.0" spacing="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="110.0" minWidth="150.0" prefWidth="150.0" text="%settings.player.label.timeDisplay" />
+            <ComboBox fx:id="timeDisplayComboBox" layoutX="104.0" layoutY="105.0" prefHeight="26.0" prefWidth="254.0" />
+         </children>
+      </HBox>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/settingsView.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/settingsView.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..23efae52a75f75d6b931db277299917bba3eea67
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/settingsView.fxml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="592.0" prefWidth="645.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <TabPane fx:id="tabPane" prefHeight="348.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="52.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
+      <Button fx:id="finishButton" layoutX="508.0" layoutY="360.0" mnemonicParsing="false" onAction="#finishButtonHandler" text="%settings.button.finish" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" />
+   </children>
+</AnchorPane>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/updateTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/updateTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..91c68b8a000fcfe5f6028a2d03f1ab06a68131cf
--- /dev/null
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/updateTab.fxml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+
+
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <HBox layoutX="14.0" layoutY="14.0" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="14.0" prefWidth="150.0" text="%settings.update.label.current" />
+            <Label fx:id="currentVersionLabel" layoutX="175.0" layoutY="14.0" text="5.0.1 (stable)" />
+         </children>
+      </HBox>
+      <HBox layoutX="14.0" layoutY="36.0" spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="36.0" prefWidth="150.0" text="%settings.update.label.new" />
+            <Label fx:id="newVersionLabel" layoutX="175.0" layoutY="36.0" text="5.0.2 (stable)" />
+         </children>
+      </HBox>
+      <Separator prefWidth="200.0" />
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="106.0" layoutY="183.0" prefWidth="150.0" text="%settings.update.label.search" />
+            <CheckBox fx:id="automaticSearchCheckBox" layoutX="275.0" layoutY="183.0" mnemonicParsing="false" text="Automatisch" />
+         </children>
+      </HBox>
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" layoutX="106.0" layoutY="222.0" prefWidth="150.0" />
+            <Button fx:id="manualSearchButton" layoutX="275.0" layoutY="217.0" mnemonicParsing="false" onAction="#manualSearchHandler" text="%settings.update.button.search" />
+         </children>
+      </HBox>
+      <Separator prefWidth="200.0" />
+      <HBox spacing="14.0">
+         <children>
+            <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%settings.update.label.available" />
+            <ListView fx:id="openUpdateList" prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+         </children>
+      </HBox>
+      <HBox alignment="TOP_RIGHT">
+         <children>
+            <Button fx:id="updateButton" mnemonicParsing="false" onAction="#updateHandler" text="%settings.update.button.install" />
+         </children>
+      </HBox>
+   </children>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/src/application.yml b/PlayWall/src/application.yml
new file mode 100644
index 0000000000000000000000000000000000000000..8c4c7d52ea06939be86818ed0ebb573f90415f5e
--- /dev/null
+++ b/PlayWall/src/application.yml
@@ -0,0 +1,15 @@
+name: PlayWall
+version: b5.0.0
+build: 24
+identifier: de.tobias.playpad
+main: de.tobias.playpad.PlayPadMain
+author: Tobias Ullerich
+backup: false
+iconPath: icon
+updateURL: http://s522730663.online.de/programmer/files/PlayWall
+userInfo:
+  Website: http://tobisan.no-ip.org/
+  ErrorURL: http://s522730663.online.de/programmer/upload.php
+  PluginsURL: http://s522730663.online.de/programmer/files/PlayWall/plugins.yml
+  ChangelogURL: http://s522730663.online.de/programmer/whatsnew-2.php?id=1
+  UpdaterProgram: http://s522730663.online.de/programmer/files/Updater/
diff --git a/PlayWall/src/controlsfx_de_DE.properties b/PlayWall/src/controlsfx_de_DE.properties
new file mode 100644
index 0000000000000000000000000000000000000000..3416523e7ebdad7ee87d1388e65e7287ce7cf2d0
--- /dev/null
+++ b/PlayWall/src/controlsfx_de_DE.properties
@@ -0,0 +1,70 @@
+### Dialogs ###
+
+dlg.ok.button = OK
+dlg.cancel.button = Abbruch
+dlg.yes.button = Ja
+dlg.no.button = Nein
+dlg.close.button = Schlie�en
+dlg.detail.button.more = Show Details
+dlg.detail.button.less = Hide Details
+
+### Common Dialogs ###
+
+font.dlg.title=Select font
+font.dlg.header=Select font
+font.dlg.sample.text=Sample
+font.dlg.font.label=Font
+font.dlg.style.label=Style
+font.dlg.size.label=Size
+
+progress.dlg.title=Progress
+progress.dlg.header=Progress
+
+login.dlg.title=Login
+login.dlg.header=Enter user name and password
+login.dlg.user.caption=User Name
+login.dlg.pswd.caption=Password
+login.dlg.login.button=Login
+
+exception.dlg.title = Exception Details
+exception.dlg.header = Exception Details
+exception.dlg.label = The exception stacktrace was:
+exception.button.label = Open Exception
+
+### Wizard ###
+
+wizard.next.button = Weiter
+wizard.previous.button = Zur�ck
+
+### Property Sheet ###
+
+bean.property.change.error.title = Property Change Error
+bean.property.change.error.header = Change is not allowed
+bean.property.category.basic=Basic
+bean.property.category.expert=Expert
+
+property.sheet.search.field.prompt = Search
+property.sheet.group.mode.byname = By Name
+property.sheet.group.mode.bycategory = By Category
+
+### Spreadsheet View ###
+
+spreadsheet.view.menu.copy = Copy
+spreadsheet.view.menu.paste = Paste
+spreadsheet.view.menu.comment = Comment cell
+spreadsheet.view.menu.comment.top-left = top left
+spreadsheet.view.menu.comment.top-right = top right
+spreadsheet.view.menu.comment.bottom-right = bottom right
+spreadsheet.view.menu.comment.bottom-left = bottom left
+spreadsheet.column.menu.fix = Fix column
+spreadsheet.column.menu.unfix = Unfix column
+spreadsheet.verticalheader.menu.fix = Fix row
+spreadsheet.verticalheader.menu.unfix = Unfix row
+
+### Status Bar ###
+statusbar.ok = OK
+
+### List Selection View ###
+listSelectionView.header.source = Available
+listSelectionView.header.target = Selected
+
diff --git a/PlayWall/src/de/tobias/playpad/AppUserInfoStrings.java b/PlayWall/src/de/tobias/playpad/AppUserInfoStrings.java
new file mode 100644
index 0000000000000000000000000000000000000000..df966939ee73d71abe043ee02b458093900bced8
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/AppUserInfoStrings.java
@@ -0,0 +1,10 @@
+package de.tobias.playpad;
+
+public class AppUserInfoStrings {
+
+	public static final String WEBSITE = "Website";
+	public static final String PLUGINS_URL = "PluginsURL";
+	public static final String ERROR_URL = "ErrorURL";
+	public static final String CHANGELOG_URL = "ChangelogURL";
+	public static final String UPDATER_PROGRAM = "UpdaterProgram";
+}
diff --git a/PlayWall/src/de/tobias/playpad/PlayPadMain.java b/PlayWall/src/de/tobias/playpad/PlayPadMain.java
new file mode 100644
index 0000000000000000000000000000000000000000..81e098fd6605ccd1fc4e045f2f657285a8c07e8b
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/PlayPadMain.java
@@ -0,0 +1,460 @@
+package de.tobias.playpad;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.UUID;
+
+import de.tobias.playpad.action.ActionRegistery;
+import de.tobias.playpad.action.connect.CartActionConnect;
+import de.tobias.playpad.action.connect.NavigateActionConnect;
+import de.tobias.playpad.action.connect.PageActionConnect;
+import de.tobias.playpad.action.mapper.KeyboardMapperConnect;
+import de.tobias.playpad.action.mapper.MapperRegistry;
+import de.tobias.playpad.action.mapper.MidiMapperConnect;
+import de.tobias.playpad.audio.AudioRegistry;
+import de.tobias.playpad.audio.ClipAudioHandler;
+import de.tobias.playpad.audio.ClipAudioHandlerConnect;
+import de.tobias.playpad.audio.JavaFXAudioHandler;
+import de.tobias.playpad.audio.JavaFXHandlerConnect;
+import de.tobias.playpad.audio.TinyAudioHandler;
+import de.tobias.playpad.audio.TinyAudioHandlerConnect;
+import de.tobias.playpad.layout.LayoutRegistry;
+import de.tobias.playpad.layout.classic.ClassicGlobalLayout;
+import de.tobias.playpad.layout.classic.ClassicLayoutConnect;
+import de.tobias.playpad.layout.modern.ModernLayoutConnect;
+import de.tobias.playpad.midi.device.DeviceRegistry;
+import de.tobias.playpad.midi.device.PD12;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
+import de.tobias.playpad.pad.content.AudioContentConnect;
+import de.tobias.playpad.pad.drag.MoveDragMode;
+import de.tobias.playpad.pad.drag.PadDragModeRegistery;
+import de.tobias.playpad.pad.drag.ReplaceDragMode;
+import de.tobias.playpad.plugin.PadListener;
+import de.tobias.playpad.plugin.SettingsListener;
+import de.tobias.playpad.plugin.WindowListener;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileListener;
+import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.playpad.tigger.TriggerRegistry;
+import de.tobias.playpad.trigger.CartTriggerItemConnect;
+import de.tobias.playpad.view.MapperOverviewViewController;
+import de.tobias.playpad.viewcontroller.IPadSettingsViewController;
+import de.tobias.playpad.viewcontroller.ISettingsViewController;
+import de.tobias.playpad.viewcontroller.LaunchDialog;
+import de.tobias.playpad.viewcontroller.dialog.ChangelogDialog;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.playpad.viewcontroller.main.MainViewController;
+import de.tobias.playpad.viewcontroller.option.UpdateTabViewController;
+import de.tobias.utils.application.App;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.ConsoleUtils;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.Localization.LocalizationDelegate;
+import de.tobias.utils.util.Worker;
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.ButtonType;
+import javafx.scene.image.Image;
+import javafx.stage.Stage;
+import net.xeoh.plugins.base.PluginManager;
+import net.xeoh.plugins.base.impl.PluginManagerFactory;
+
+/*
+ * TODOS
+ */
+// PlayWall 5.0.0
+// FIXME XML Tags in String Konstanten
+
+// Common Updater für Plugins & Programme
+// Changelog OK Button
+// Keine Schriftgröße bei Cart Layout
+
+// Profile mit UUID
+
+// FEATURE Backups irgendwann löschen
+
+// Pad System neu machen
+// Neue PadViewController für jedes pad
+// Midi Modell Überarbeiten
+// Bei Seitenwechsel Pad auf Play lassen
+
+// FEATURE Trigger
+
+// FEATURE Option bei Import Media auch Copy Media in Library
+
+// FEATURE lnk für Windows mit Dateiparameter
+
+// FEATURE PFL
+// FEATURE Sound Card Pro Cart
+
+public class PlayPadMain extends Application implements LocalizationDelegate, PlayPad, ProfileListener {
+
+	private static final String iconPath = "icon_small.png";
+	public static Optional<Image> stageIcon = Optional.empty();
+
+	public static final long notificationDisplayTimeMillis = 1500;
+
+	public static final String[] projectType = { "*.xml" };
+	public static final String[] projectCompressedType = { "*.zip" };
+	public static final String[] midiPresetType = { "*.pre" };
+
+	private static ResourceBundle uiResourceBundle;
+	private static MainViewController mainViewController;
+
+	private static PlayPadUpdater updater;
+	private static Set<Path> deletedPlugins = new HashSet<>();
+
+	public static void addDeletedPlugin(Path path) {
+		deletedPlugins.add(path);
+	}
+
+	/*
+	 * 
+	 */
+
+	public static ResourceBundle getUiResourceBundle() {
+		return uiResourceBundle;
+	}
+
+	public static void main(String[] args) throws Exception {
+		// Debug
+		System.setOut(ConsoleUtils.convertStream(System.out, "[PlayWall] "));
+		System.setErr(ConsoleUtils.convertStream(System.err, "[PlayWall] "));
+
+		App app = ApplicationUtils.registerMainApplication(PlayPadMain.class);
+		ApplicationUtils.registerUpdateSercive(new VersionUpdater());
+		app.start(args);
+	}
+
+	private static PluginManager pluginManager;
+
+	@Override
+	public void init() throws Exception {
+		PlayPadPlugin.setImplementation(this);
+
+		// Localization
+		setupLocalization();
+
+		// Console
+		if (!ApplicationUtils.getApplication().isDebug()) {
+			System.setOut(ConsoleUtils.streamToFile(ApplicationUtils.getApplication().getPath(PathType.LOG, "out.log")));
+			System.setErr(ConsoleUtils.streamToFile(ApplicationUtils.getApplication().getPath(PathType.LOG, "err.log")));
+		}
+	}
+
+	@Override
+	public void start(Stage stage) throws Exception {
+		// Assets
+		try {
+			Image stageIcon = new Image(iconPath);
+			PlayPadMain.stageIcon = Optional.of(stageIcon);
+		} catch (Exception e) {}
+
+		/*
+		 * Setup
+		 */
+		updater = new PlayPadUpdater();
+		UpdateRegistery.registerUpdateable(updater);
+		registerComponents();
+		setupPlugins();
+
+		/*
+		 * Load Data
+		 */
+		ProfileReference.loadProfiles();
+		ProjectReference.loadProjects();
+
+		Runtime.getRuntime().addShutdownHook(new Thread(() ->
+		{
+			try {
+				if (mainViewController != null) {
+					if (mainViewController.getProject().getRef() != null) {
+						// Projekt Speichern
+						mainViewController.getProject().save();
+					}
+				}
+
+				if (Profile.currentProfile() != null)
+					Profile.currentProfile().save();
+
+				ProfileReference.saveProfiles();
+				ProjectReference.saveProjects();
+			} catch (Exception e) {
+				e.printStackTrace(); // Speichern Fehler
+			}
+		}));
+
+		// Changelog nach Update anzeigen
+		try {
+			ViewController.create(ChangelogDialog.class);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// Auto Open Project
+		if (getParameters().getRaw().size() > 0) {
+			try {
+				UUID uuid = UUID.fromString(getParameters().getRaw().get(0));
+				launchProject(Project.load(ProjectReference.getProject(uuid), true, null));
+				return;
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+
+		ViewController.create(LaunchDialog.class, stage);
+	}
+
+	private void registerComponents() {
+		// Audio
+		AudioRegistry.register(new JavaFXHandlerConnect(), JavaFXAudioHandler.NAME);
+		AudioRegistry.register(new TinyAudioHandlerConnect(), TinyAudioHandler.NAME);
+		AudioRegistry.register(new ClipAudioHandlerConnect(), ClipAudioHandler.NAME);
+
+		AudioRegistry.setDefaultAudioInterface(JavaFXAudioHandler.NAME);
+
+		// Layout
+		LayoutRegistry.registerLayout(new ClassicLayoutConnect());
+		LayoutRegistry.registerLayout(new ModernLayoutConnect());
+		LayoutRegistry.setDefaultLayout(ClassicGlobalLayout.TYPE);
+
+		// Midi
+		DeviceRegistry.getFactoryInstance().registerDevice(PD12.NAME, PD12.class);
+
+		// Trigger
+		TriggerRegistry.register(new CartTriggerItemConnect());
+//		TriggerRegistry.register(new VolumeTriggerItemConnect());
+
+		// Actions
+		ActionRegistery.registerActionConnect(new CartActionConnect());
+		ActionRegistery.registerActionConnect(new PageActionConnect());
+		ActionRegistery.registerActionConnect(new NavigateActionConnect());
+
+		// Mapper
+		MapperRegistry.registerMapperConnect(new MidiMapperConnect());
+		MapperRegistry.registerMapperConnect(new KeyboardMapperConnect());
+		MapperRegistry.setOverviewViewController(new MapperOverviewViewController());
+
+		// Pad Content
+		PadContentRegistry.registerActionConnect(new AudioContentConnect());
+
+		// Pad Drag Mode
+		PadDragModeRegistery.registerActionConnect(new MoveDragMode());
+		PadDragModeRegistery.registerActionConnect(new ReplaceDragMode());
+
+		Profile.registerListener(this);
+	}
+
+	private void setupPlugins() throws IOException, MalformedURLException {
+		/*
+		 * Plugins
+		 */
+		Path pluginInfoPath = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, "pluginInfo.txt");
+
+		// Delete Plugin
+		if (Files.exists(pluginInfoPath)) {
+			BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(pluginInfoPath)));
+			String line;
+			while ((line = reader.readLine()) != null) {
+				Path plugin = Paths.get(line);
+				Files.deleteIfExists(plugin);
+			}
+			reader.close();
+			Files.delete(pluginInfoPath);
+		}
+
+		// Load Plugins
+		pluginManager = PluginManagerFactory.createPluginManager();
+		if (ApplicationUtils.getApplication().isDebug())
+			// DEBUG PLUGINS EINBINDEN
+			pluginManager.addPluginsFrom(Paths.get("/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWallPlugins/bin/").toUri());
+		else
+			pluginManager.addPluginsFrom(ApplicationUtils.getApplication().getPath(PathType.LIBRARY).toUri());
+
+		// Shutdown Plugins
+		Runtime.getRuntime().addShutdownHook(new Thread(() ->
+		{
+			pluginManager.shutdown();
+
+			try {
+				if (Files.notExists(pluginInfoPath)) {
+					Files.createDirectories(pluginInfoPath.getParent());
+					Files.createFile(pluginInfoPath);
+				}
+				PrintWriter deleteWriter = new PrintWriter(Files.newOutputStream(pluginInfoPath));
+				for (Path path : deletedPlugins) {
+					deleteWriter.println(path.toString());
+				}
+				deleteWriter.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}));
+	}
+
+	private void setupLocalization() {
+		Localization.setDelegate(this);
+		Localization.load();
+
+		uiResourceBundle = Localization.loadBundle("de/tobias/playpad/assets/lang/ui", getClass().getClassLoader());
+	}
+
+	public static void launchProject(Project project) {
+		mainViewController = new MainViewController(project, mainViewListeners, pluginManager);
+	}
+
+	@Override
+	public void reloadSettings(Profile oldProfile, Profile currentProfile) {
+		if (currentProfile.getProfileSettings().isAutoUpdate()) {
+			Worker.runLater(() ->
+			{
+				UpdateRegistery.lookupUpdates();
+				if (!UpdateRegistery.getAvailableUpdates().isEmpty()) {
+					Platform.runLater(() ->
+					{
+						Alert alert = new Alert(AlertType.CONFIRMATION);
+						alert.setHeaderText(Localization.getString(Strings.UI_Dialog_AutoUpdate_Header));
+						alert.setContentText(Localization.getString(Strings.UI_Dialog_AutoUpdate_Content));
+						alert.showAndWait().filter(item -> item == ButtonType.OK).ifPresent(result ->
+						{
+							UpdateTabViewController.update(null);
+						});
+					});
+				}
+			});
+		}
+	}
+
+	@Override
+	public String getBaseResource() {
+		return "de/tobias/playpad/assets/lang/";
+	}
+
+	@Override
+	public Locale getLocale() {
+		return Locale.getDefault();
+	}
+
+	/*
+	 * Plugins
+	 */
+	protected static List<WindowListener<IMainViewController>> mainViewListeners = new ArrayList<>();
+	protected static List<WindowListener<ISettingsViewController>> settingsViewListeners = new ArrayList<>();
+	protected static List<WindowListener<IPadSettingsViewController>> padSettingsViewListeners = new ArrayList<>();
+	protected static List<SettingsListener> settingsListeners = new ArrayList<>();
+	protected static List<PadListener> padListeners = new ArrayList<>();
+
+	@Override
+	public void addMainViewListener(WindowListener<IMainViewController> listener) {
+		mainViewListeners.add(listener);
+	}
+
+	@Override
+	public void removeMainViewListener(WindowListener<IMainViewController> listener) {
+		mainViewListeners.remove(listener);
+	}
+
+	@Override
+	public void addSettingsViewListener(WindowListener<ISettingsViewController> listener) {
+		settingsViewListeners.add(listener);
+	}
+
+	@Override
+	public void removeSettingsViewListener(WindowListener<ISettingsViewController> listener) {
+		settingsViewListeners.remove(listener);
+	}
+
+	@Override
+	public List<WindowListener<ISettingsViewController>> getSettingsViewListener() {
+		return settingsViewListeners;
+	}
+
+	@Override
+	public void addPadSettingsViewListener(WindowListener<IPadSettingsViewController> listener) {
+		padSettingsViewListeners.add(listener);
+	}
+
+	@Override
+	public void removePadSettingsViewListener(WindowListener<IPadSettingsViewController> listener) {
+		padSettingsViewListeners.remove(listener);
+	}
+
+	@Override
+	public List<WindowListener<IPadSettingsViewController>> getPadSettingsViewListener() {
+		return padSettingsViewListeners;
+	}
+
+	@Override
+	public void addSettingsListener(SettingsListener listener) {
+		settingsListeners.add(listener);
+	}
+
+	@Override
+	public void removeSettingsListener(SettingsListener listener) {
+		settingsListeners.remove(listener);
+	}
+
+	@Override
+	public List<SettingsListener> getSettingsListener() {
+		return settingsListeners;
+	}
+
+	@Override
+	public void addPadListener(PadListener listener) {
+		padListeners.add(listener);
+	}
+
+	@Override
+	public void removePadListener(PadListener listener) {
+		padListeners.remove(listener);
+	}
+
+	@Override
+	public List<PadListener> getPadListener() {
+		return padListeners;
+	}
+
+	@Override
+	public MainViewController getMainViewController() {
+		return mainViewController;
+	}
+
+	@Override
+	public PluginManager getPluginManager() {
+		return pluginManager;
+	}
+
+	@Override
+	public String[] getProjectFiles() {
+		return projectType;
+	}
+
+	@Override
+	public Optional<Image> getIcon() {
+		return stageIcon;
+	}
+
+	public static Updatable getUpdater() {
+		return updater;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/PlayPadUpdater.java b/PlayWall/src/de/tobias/playpad/PlayPadUpdater.java
new file mode 100644
index 0000000000000000000000000000000000000000..be17c2fe34175743038c7fd97744c106298ecddc
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/PlayPadUpdater.java
@@ -0,0 +1,91 @@
+package de.tobias.playpad;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import de.tobias.utils.application.App;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.util.SystemUtils;
+
+public class PlayPadUpdater implements Updatable {
+
+	private int newBuild;
+	private String newVersion;
+	private URL remotePath;
+
+	@Override
+	public int getCurrentBuild() {
+		return (int) ApplicationUtils.getMainApplication().getInfo().getBuild();
+	}
+
+	@Override
+	public String getCurrentVersion() {
+		return ApplicationUtils.getMainApplication().getInfo().getVersion();
+	}
+
+	@Override
+	public int getNewBuild() {
+		if (newBuild == 0) {
+			checkUpdate();
+		}
+		return newBuild;
+	}
+
+	@Override
+	public String getNewVersion() {
+		if (newVersion == null) {
+			checkUpdate();
+		}
+		return newVersion;
+	}
+
+	@Override
+	public boolean checkUpdate() {
+		App app = ApplicationUtils.getMainApplication();
+		try {
+			FileConfiguration config = YamlConfiguration.loadConfiguration(new URL(app.getInfo().getUpdateURL() + "/version.yml").openStream());
+			newBuild = config.getInt("build");
+			newVersion = config.getString("version");
+
+			if (SystemUtils.isExe()) {
+				remotePath = new URL(config.getString("pathExe"));
+			} else {
+				remotePath = new URL(config.getString("pathJar"));				
+			}
+			
+			return getCurrentBuild() < getNewBuild();
+		} catch (IOException | URISyntaxException e) {
+			e.printStackTrace();
+		}
+		return false;
+	}
+
+	@Override
+	public URL getDownloadPath() {
+		if (remotePath == null) {
+			checkUpdate();
+		}
+		return remotePath;
+	}
+
+	@Override
+	public Path getLocalPath() {
+		try {
+			return SystemUtils.getRunPath();
+		} catch (URISyntaxException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	@Override
+	public String name() {
+		return ApplicationUtils.getApplication().getInfo().getName();
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/PseudoClasses.java b/PlayWall/src/de/tobias/playpad/PseudoClasses.java
new file mode 100644
index 0000000000000000000000000000000000000000..0bb01d7339f00d9df02746e900b57ed8a844dc29
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/PseudoClasses.java
@@ -0,0 +1,13 @@
+package de.tobias.playpad;
+
+import javafx.css.PseudoClass;
+
+public class PseudoClasses {
+
+	public static final PseudoClass ERROR_CLASS = PseudoClass.getPseudoClass("error");
+	public static final PseudoClass PLAY_CALSS = PseudoClass.getPseudoClass("play");
+	public static final PseudoClass FADE_CLASS = PseudoClass.getPseudoClass("fade");
+	public static final PseudoClass WARN_CLASS = PseudoClass.getPseudoClass("warn");
+	public static final PseudoClass HOVER_CLASS = PseudoClass.getPseudoClass("drag");
+	public static final PseudoClass DRAG_CLASS = PseudoClass.getPseudoClass("drag");
+}
diff --git a/PlayWall/src/de/tobias/playpad/Strings.java b/PlayWall/src/de/tobias/playpad/Strings.java
new file mode 100644
index 0000000000000000000000000000000000000000..7dae7bef76b698e9dec6f00d12fe3fa15b5e32d2
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/Strings.java
@@ -0,0 +1,218 @@
+package de.tobias.playpad;
+
+public class Strings {
+
+	// Standard - File
+	public static final String Standard_File_Save = "Standard.File.Save";
+	public static final String Standard_Copy = "Standard.Copy";
+	public static final String Standard_Time_Seconds = "Standard.Time.Seconds";
+
+	// File - Filter
+	public static final String File_Filter_ZIP = "File.Filter.ZIP";
+	public static final String File_Filter_Media = "File.Filter.Media";
+	public static final String File_Filter_Preset = "File.Filter.Preset";
+
+	// Timemode - Enum
+	public static final String Pad_TimeMode_BaseName = "Pad.TimeMode.";
+
+	// UI - Window - Titles
+	public static final String UI_Dialog_Launch_Title = "UI.Dialog.Launch.Title";
+	public static final String UI_Window_Main_Title = "UI.Window.Main.Title";
+	public static final String UI_Window_Changelog_Title = "UI.Window.Changelog.Title";
+	public static final String UI_Window_Settings_Title = "UI.Window.Settings.Title";
+	public static final String UI_Window_PadSettings_Title = "UI.Window.PadSettings.Title";
+	public static final String UI_Dialog_DragAndDrop_Title = "UI.Dialog.DragAndDrop.Title";
+	public static final String UI_Dialog_ProjectExport_Title = "UI.Dialog.ProjectExport.Title";
+	public static final String UI_Dialog_ErrorSummary_Title = "UI.Dialog.ErrorSummary.Title";
+	public static final String UI_Dialog_NewProile_Title = "UI.Dialog.NewProfile.Title";
+	public static final String UI_Dialog_NewProject_Title = "UI.Dialog.NewProject.Title";
+	public static final String UI_Dialog_ChooseProfile_Title = "UI.Dialog.ChooseProfile.Title";
+	public static final String UI_Dialog_ProjectManager_Title = "UI.Dialog.ProjectManager.Title";
+	public static final String UI_Dialog_UpdateCenter_Title = "UI.Dialog.UpdateCenter.Title";
+	public static final String UI_Dialog_Preset_Title = "UI.Dialog.Preset.Title";
+	public static final String UI_Dialog_Plugins_Title = "UI.Dialog.Plugins.Title";
+	public static final String UI_Dialog_Print_Title = "UI.Dialog.Print.Title";
+	public static final String UI_Dialog_Profile_Title = "UI.Dialog.Profile.Title";
+
+	// UI - Standard
+	public static final String UI_Standard_DoNotShow = "UI.Standard.DoNotShow";
+
+	// UI - Layout - Classic - Theme - Enum
+	public static final String UI_Layout_Classic_Theme_BaseName = "UI.Layout.Classic.Theme.";
+
+	// UI - Window - Main
+	public static final String UI_Window_Main_CloseRequest = "UI.Window.Main.CloseRequest";
+	public static final String UI_Window_Main_PageButton = "UI.Window.Main.PageButton";
+
+	// UI - Dialog - Launch
+	public static final String UI_Dialog_Launch_Info = "UI.Dialog.Launch.Info";
+
+	// UI - Window - Settings
+	public static final String UI_Window_Settings_Gen_Title = "UI.Window.Settings.Gen.Title";
+	public static final String UI_Window_Settings_Gen_CacheSize = "UI.Window.Settings.Gen.CacheSize";
+	public static final String UI_Window_Settings_Mapping_Title = "UI.Window.Settings.Mapping.Title";
+	public static final String UI_Window_Settings_Midi_Title = "UI.Window.Settings.Midi.Title";
+	public static final String UI_Window_Settings_Layout_Title = "UI.Window.Settings.Layout.Title";
+	public static final String UI_Window_Settings_Player_Title = "UI.Window.Settings.Player.Title";
+	public static final String UI_Window_Settings_Audio_Title = "UI.Window.Settings.Audio.Title";
+	public static final String UI_Window_Settings_Updates_Title = "UI.Window.Settings.Updates.Title";
+
+	// UI - Dialogs - DragAndDrop
+	public static final String UI_Dialog_DragAndDrop_Header = "UI.Dialog.DragAndDrop.Header";
+	public static final String UI_Dialog_DragAndDrop_Content = "UI.Dialog.DragAndDrop.Content";
+	public static final String UI_Dialog_DragAndDrop_Button = "UI.Dialog.DragAndDrop.Button";
+
+	// UI - Dialog - NewProfile
+	public static final String UI_Dialog_NewProfile_Content = "UI.Dialog.NewProfile.Content";
+
+	// UI - Dialog - NewProject
+	public static final String UI_Dialog_NewProject_Content = "UI.Dialog.NewProject.Content";
+
+	// UI - Dialog - Import
+	public static final String UI_Dialog_Import_ReplaceProfile_Content = "UI.Dialog.Import.ReplaceProfile.Content";
+	public static final String UI_Dialog_Import_ReplaceProfile_Skip = "UI.Dialog.Import.ReplaceProfile.Skip";
+	public static final String UI_Dialog_Import_ReplaceProfile_Rename = "UI.Dialog.Import.ReplaceProfile.Rename";
+	public static final String UI_Dialog_Import_ReplaceProfile_ReplaceContent = "UI.Dialog.Import.ReplaceProfile.ReplaceContent";
+	public static final String UI_Dialog_Import_ReplaceProject_ReplaceContent = "UI.Dialog.Import.ReplaceProject.ReplaceContent";
+	public static final String UI_Dialog_Import_ReplaceMedia_Content = "UI.Dialog.Import.ReplaceMedia.Content";
+	public static final String UI_Dialog_Import_ReplaceMedia_Copy = "UI.Dialog.Import.ReplaceMedia.Copy";
+	public static final String UI_Dialog_Import_ReplaceMedia_Skip = "UI.Dialog.Import.ReplaceMedia.Skip";
+
+	// UI - Dialog - ProjectManager
+	public static final String UI_Dialog_ProjectManager_Delete_Content = "UI.Dialog.ProjectManager.Delete.Content";
+
+	// UI - Dialog - Profile
+	public static final String UI_Dialog_Profile_Delete_Content = "UI.Dialog.Profile.Delete.Content";
+
+	// UI - Dialog - Info
+	public static final String UI_Dialog_Info_Header = "UI.Dialog.Info.Header";
+	public static final String UI_Dialog_Info_Content = "UI.Dialog.Info.Content";
+
+	// UI - Dialog - Feedback
+	public static final String UI_Dialog_Feedback_Content = "UI.Dialog.Feedback.Content";
+
+	// UI - Placeholder
+	public static final String UI_Placeholder_Project = "UI.Placeholder.Project";
+	public static final String UI_Placeholder_Preset = "UI.Placeholder.Preset";
+	public static final String UI_Placeholder_Plugins = "UI.Placeholder.Plugins";
+	public static final String UI_Placeholder_Updates = "UI.Placeholder.Updates";
+	public static final String UI_Placeholder_ErrorSummary = "UI.Placeholder.ErrorSummary";
+
+	// Info - MIDI
+	public static final String Info_Midi_Device_Connected = "Info.Midi.Device.Connected";
+
+	// Info - Settings
+	public static final String Info_Settings_ResetWarning = "Info.Settings.ResetWarning";
+	public static final String Info_Settings_CacheDelete = "Info.Settings.CacheDelete";
+
+	// Info - Print
+	public static final String Info_Print_Header = "Info.Print.Header";
+
+	// Error - Standard
+	public static final String Error_Standard_Gen = "Error.Standard.Gen";
+	public static final String Error_Standard_NameInUse = "Error.Standard.NameInUse";
+
+	// Error - Settings
+	public static final String Error_Settings_CacheSize = "Error.Settings.CacheSize";
+	public static final String Error_Settings_CacheClear = "Error.Settings.CacheClear";
+
+	// Error - Profile
+	public static final String Error_Profile_Create = "Error.Profile.Create";
+	public static final String Error_Profile_NotFound = "Error.Profile.NotFound";
+	public static final String Error_Profile_Save = "Error.Profile.Save";
+	public static final String Error_Profile_Delete = "Error.Profile.Delete";
+	public static final String Error_Profile_SmallScreen = "Error.Profile.SmallScreen";
+
+	// Error - Preset
+	public static final String Error_Preset_Import = "Error.Preset.Import";
+	public static final String Error_Preset_Export = "Error.Preset.Export";
+
+	// Error - Project
+	public static final String Error_Project_Create = "Error.Project.Create";
+	public static final String Error_Project_NotFound = "Error.Project.NotFound";
+	public static final String Error_Project_Open = "Error.Project.Open";
+	public static final String Error_Project_Save = "Error.Project.Save";
+	public static final String Error_Project_Rename = "Error.Project.Rename";
+	public static final String Error_Project_Delete = "Error.Project.Delete";
+	public static final String Error_Project_Export = "Error.Project.Export";
+
+	// Error - Pad
+	public static final String Error_Pad_BaseName = "Error.Pad.";
+
+	// Error - Fix
+	public static final String Error_Fix_NewFile = "Error.Fix.NewFile";
+
+	// Error - Midi
+	public static final String Error_Midi_Settings_Unkown = "Error.Midi.Settings.Unkown";
+	public static final String Error_Midi_Device_Busy = "Error.Midi.Device.Busy";
+	public static final String Error_Midi_Device_Unavailible = "Error.Midi.Device.Unavailible";
+	public static final String Error_Midi_Record_Fail = "Error.Midi.Record.Fail";
+	public static final String Error_Midi_Send = "Error.Midi.Send";
+
+	// Error - Plugins
+	public static final String Error_Plugins_Download = "Error.Plugins.Download";
+
+	/*
+	 * NEU
+	 */
+
+	// Mapper
+	public static final String Mapper_Keyboard_Name = "Mapper.Keyboard.Name";
+	public static final String Mapper_Midi_Name = "Mapper.Midi.Name";
+	public static final String Mapper_Keyboard_toString = "Mapper.Keyboard.toString";
+	public static final String Mapper_Midi_toString = "Mapper.Midi.toString";
+
+	// Info - Mapper
+	public static final String Info_Mapper_PressKey = "Info.Mapper.PressKey";
+
+	// UI - Window - PadSettings
+	public static final String UI_Window_PadSettings_General_Title = "UI.Window.PadSettings.General.Title";
+	public static final String UI_Window_PadSettings_Player_Title = "UI.Window.PadSettings.Player.Title";
+	public static final String UI_Window_PadSettings_Layout_Title = "UI.Window.PadSettings.Layout.Title";
+	public static final String UI_Window_PadSettings_Trigger_Title = "UI.Window.PadSettings.Trigger.Title";
+
+	// Actions
+	public static final String Action_Cart_toString = "Action.Cart.toString";
+	public static final String Action_Page_toString = "Action.Page.toString";
+	public static final String Action_Navigate_toString = "Action.Navigate.toString";
+	public static final String Action_Cart_Name = "Action.Cart.Name";
+	public static final String Action_Page_Name = "Action.Page.Name";
+	public static final String Action_Navigate_Name = "Action.Navigate.Name";
+
+	// Content
+	public static final String Content_Empty = "Content.Empyt";
+	public static final String Content_Audio_Name = "Content.Audio.Name";
+
+	// NavigationType - Enum
+	public static final String NavigationType_BaseName = "NavigationType.";
+
+	// ControlMode - Enum
+	public static final String CartAction_Mode_BaseName = "CartAction.Mode.";
+
+	// UI - Dialog - AutoUpdate
+	public static final String UI_Dialog_AutoUpdate_Header = "UI.Dialog.AutoUpdate.Header";
+	public static final String UI_Dialog_AutoUpdate_Content = "UI.Dialog.AutoUpdate.Content";
+
+	// Error - Layout
+	public static final String Error_Layout_Load = "Error.Layout.Load";
+
+	// UI - Dialog - Update
+	public static final String UI_Dialog_Update_Cell = "UI.Dialog.Update.Cell";
+	public static final String UI_Window_Settings_Updates_CurrentVersion = "UI.Window.Settings.Updates.CurrentVersion";
+	public static final String UI_Window_Settings_Updates_NewVersion = "UI.Window.Settings.Updates.NewVersion";
+
+	// Error - Update - Downlaod
+	public static final String Error_Update_Download = "Error.Update.Download";
+
+	// Layout
+	public static final String Layout_Modern_Name = "Layout.Modern.Name";
+	public static final String Layout_Classic_Name = "Layout.Classic.Name";
+
+	// Trigger
+	public static final String TriggerPoint_toString = "TriggerPoint.toString";
+	public static final String Trigger_Cart_Name = "Trigger.Cart.Name";
+	public static final String Trigger_Volume_Name = "Trigger.Volume.Name";
+
+	// TriggerPoint - Enum
+	public static final String TriggerPoint_BaseName = "TriggerPoint.";
+}
diff --git a/PlayWall/src/de/tobias/playpad/VersionUpdater.java b/PlayWall/src/de/tobias/playpad/VersionUpdater.java
new file mode 100644
index 0000000000000000000000000000000000000000..183b998e9cd90623b87e27f53430a5a0ced73fc8
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/VersionUpdater.java
@@ -0,0 +1,228 @@
+package de.tobias.playpad;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.SAXReader;
+import org.dom4j.io.XMLWriter;
+
+import de.tobias.playpad.action.Mapping;
+import de.tobias.playpad.action.cartaction.CartAction;
+import de.tobias.playpad.action.cartaction.CartAction.ControlMode;
+import de.tobias.playpad.action.feedback.DoubleSimpleFeedback;
+import de.tobias.playpad.action.mapper.MidiMapper;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.utils.application.App;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.application.update.UpdateService;
+
+public class VersionUpdater implements UpdateService {
+
+	@Override
+	public void update(App app, long oldVersion, long newVersion) {
+		System.out.println("Update");
+		if (oldVersion <= 18) {
+			SAXReader reader = new SAXReader();
+			Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "Profiles.xml");
+
+			try {
+				Document document = reader.read(Files.newInputStream(path));
+				Element root = document.getRootElement();
+				for (Object object : root.elements("Document")) {
+					Element element = (Element) object;
+					String name = element.getStringValue();
+
+					UUID uuid = UUID.randomUUID();
+
+					Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, name);
+					Path newProjectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, uuid + Project.FILE_EXTENSION);
+					Files.createDirectories(newProjectPath);
+
+					Files.move(projectPath, newProjectPath);
+
+					ProjectReference projectReference = new ProjectReference(uuid, name, ProfileReference.getProfiles().get(0));
+					ProjectReference.addProject(projectReference);
+
+					convertProject(newProjectPath);
+				}
+
+				ProjectReference.saveProjects();
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+
+		if (oldVersion <= 23) {
+			System.out.println("Update Data");
+			Path configPath = app.getPath(PathType.CONFIGURATION);
+			SAXReader reader = new SAXReader();
+			try {
+				Document document = reader.read(Files.newInputStream(configPath.resolve("Profiles.xml")));
+				for (Object profileObj : document.getRootElement().elements("Profile")) {
+					if (profileObj instanceof Element) {
+						String name = ((Element) profileObj).getStringValue();
+						System.out.println("Start Profile: " + name);
+						UUID uuid = UUID.randomUUID();
+
+						Path profileOldPath = app.getPath(PathType.CONFIGURATION, name);
+						Path profileNewPath = app.getPath(PathType.CONFIGURATION, uuid.toString());
+
+						Files.move(profileOldPath, profileNewPath);
+
+						convertMidiToMapping(profileNewPath);
+
+						ProfileReference profileReference = new ProfileReference(uuid, name);
+						ProfileReference.addProfile(profileReference);
+						System.out.println("Finish Profile: " + name + " (" + uuid + ")");
+					}
+				}
+			} catch (DocumentException | IOException e1) {
+				e1.printStackTrace();
+			}
+
+			try {
+				Document document = reader.read(Files.newInputStream(configPath.resolve("Projects.xml")));
+				for (Object projectObj : document.getRootElement().elements("Project")) {
+					if (projectObj instanceof Element) {
+						try {
+							String name = ((Element) projectObj).getStringValue();
+							Path projectPath = app.getPath(PathType.DOCUMENTS, name);
+							System.out.println("Start Project: " + projectPath);
+
+							UUID uuid = UUID.randomUUID();
+							Path newProjectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, uuid + Project.FILE_EXTENSION);
+
+							Files.move(projectPath, newProjectPath);
+
+							ProjectReference projectReference = new ProjectReference(uuid, projectPath.getFileName().toString(),
+									ProfileReference.getProfiles().get(0));
+							ProjectReference.addProject(projectReference);
+
+							convertProject(newProjectPath);
+							System.out.println("End Project: " + projectPath + " (" + uuid + ")");
+						} catch (DocumentException | URISyntaxException e) {
+							e.printStackTrace();
+						}
+					}
+				}
+			} catch (IOException | DocumentException e) {
+				e.printStackTrace();
+			}
+			try {
+				ProfileReference.saveProfiles();
+				ProjectReference.saveProjects();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	public void convertMidiToMapping(Path configPath) throws DocumentException, IOException {
+		SAXReader reader = new SAXReader();
+		Document midiDocument = reader.read(Files.newInputStream(configPath.resolve("Midi.xml")));
+
+		List<Mapping> mappings = new ArrayList<>();
+
+		for (Object presetObj : midiDocument.getRootElement().elements("Preset")) {
+			Element presetElement = (Element) presetObj;
+			String name = presetElement.attributeValue("name");
+
+			Mapping mapping = new Mapping(false, null);
+			mapping.setName(name);
+			mapping.setUuid(UUID.randomUUID());
+
+			for (Object midiObj : presetElement.elements("Midi")) {
+				Element midiElement = (Element) midiObj;
+				int command = Integer.valueOf(midiElement.attributeValue("command"));
+				int key = Integer.valueOf(midiElement.attributeValue("channel"));
+
+				if (midiElement.attributeValue("type") != null) {
+					if (midiElement.attributeValue("type").equals("de.tobias.playpad.model.midi.type.PlayStopActionType")) {
+						Element actionElement = midiElement.element("Action");
+						if (actionElement.attributeValue("class").equals("de.tobias.playpad.model.midi.CartAction")) {
+							int cart = Integer.valueOf(actionElement.element("CartID").getStringValue());
+
+							CartAction action = new CartAction(cart, ControlMode.PLAY_STOP);
+							mapping.addActionIfNotContains(action);
+
+							MidiMapper mapper = new MidiMapper(command, key);
+							action.addMapper(mapper);
+
+							Element feedbackEventElement = actionElement.element("Feedback");
+							Element feedbackDefaultElement = midiElement.element("Feedback");
+
+							int feedbackEvent = Integer.valueOf(feedbackEventElement.element("MidiVelocity").getStringValue());
+							int feedbackDefault = Integer.valueOf(feedbackDefaultElement.element("MidiVelocity").getStringValue());
+
+							DoubleSimpleFeedback doubleSimpleFeedback = new DoubleSimpleFeedback(feedbackDefault, feedbackEvent);
+							mapper.setFeedback(doubleSimpleFeedback);
+						}
+					}
+				}
+			}
+			mappings.add(mapping);
+		}
+
+		Document mappingDocument = DocumentHelper.createDocument();
+		Element rootElement = mappingDocument.addElement("List");
+
+		for (Mapping mapping : mappings) {
+			Element mappingElement = rootElement.addElement("Mapping");
+			mapping.save(mappingElement);
+		}
+
+		XMLWriter writer = new XMLWriter(Files.newOutputStream(configPath.resolve("Mapping.xml")), OutputFormat.createPrettyPrint());
+		writer.write(mappingDocument);
+		writer.close();
+
+		Files.delete(configPath.resolve("Midi.xml"));
+	}
+
+	public void convertProject(Path path) throws DocumentException, IOException, URISyntaxException {
+		SAXReader reader = new SAXReader();
+		Document oldDocument = reader.read(Files.newInputStream(path));
+		Document newDocument = DocumentHelper.createDocument();
+
+		Element newRootElement = newDocument.addElement("Project");
+
+		for (Object oldPadObj : oldDocument.getRootElement().elements("Pad")) {
+			try {
+				Element oldPadElement = (Element) oldPadObj;
+				Element newPadElement = newRootElement.addElement("Pad");
+
+				newPadElement.addAttribute("index", oldPadElement.attributeValue("index"));
+				newPadElement.addAttribute("name", oldPadElement.element("Title").getStringValue());
+				newPadElement.addAttribute("status", oldPadElement.element("State").getStringValue());
+
+				String file = oldPadElement.element("Path").getStringValue();
+				URI uri = new URI(file);
+				newPadElement.addElement("Content").addAttribute("type", "audio").addText(Paths.get(uri).toString());
+
+				Element newSettingsElement = newPadElement.addElement("Settings");
+				newSettingsElement.addElement("Volume").addText(oldPadElement.element("Volume").getStringValue());
+				newSettingsElement.addElement("Loop").addText(oldPadElement.element("Loop").getStringValue());
+				if (oldPadElement.element("TimeMode") != null)
+					newSettingsElement.addElement("TimeMode").addText(oldPadElement.element("TimeMode").getStringValue());
+			} catch (Exception e) {}
+		}
+
+		XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint());
+		writer.write(newDocument);
+		writer.close();
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/MappingUtils.java b/PlayWall/src/de/tobias/playpad/action/MappingUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..a455969b8ec932bff1cc255c43a8c0e8784e1753
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/MappingUtils.java
@@ -0,0 +1,42 @@
+package de.tobias.playpad.action;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.tobias.playpad.action.mapper.KeyboardMapper;
+import de.tobias.playpad.action.mapper.Mapper;
+import de.tobias.playpad.action.mapper.MidiMapper;
+import javafx.scene.input.KeyCode;
+
+public class MappingUtils {
+
+	public static List<Action> getActionsForKey(KeyCode code, Mapping mapping) {
+		List<Action> actions = new ArrayList<>();
+		for (Action action : mapping.keySet()) {
+			for (Mapper mapper : mapping.get(action)) {
+				if (mapper instanceof KeyboardMapper) {
+					KeyboardMapper keyMapper = (KeyboardMapper) mapper;
+					if (keyMapper.getCode() == code) {
+						actions.add(action);
+					}
+				}
+			}
+		}
+		return actions;
+	}
+
+	public static List<Action> getActionsForMidi(int cmd, int key, Mapping mapping) {
+		List<Action> actions = new ArrayList<>();
+		for (Action action : mapping.keySet()) {
+			for (Mapper mapper : mapping.get(action)) {
+				if (mapper instanceof MidiMapper) {
+					MidiMapper midiMapper = (MidiMapper) mapper;
+					if (midiMapper.getCommand() == cmd && midiMapper.getKey() == key) {
+						actions.add(action);
+					}
+				}
+			}
+		}
+		return actions;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/actions/NavigateAction.java b/PlayWall/src/de/tobias/playpad/action/actions/NavigateAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..b4c9e005d4ad67297301d689e39bef045c7d9ab6
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/actions/NavigateAction.java
@@ -0,0 +1,121 @@
+package de.tobias.playpad.action.actions;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.InputType;
+import de.tobias.playpad.action.connect.NavigateActionConnect;
+import de.tobias.playpad.action.feedback.FeedbackMessage;
+import de.tobias.playpad.action.feedback.FeedbackType;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.util.Localization;
+import javafx.application.Platform;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class NavigateAction extends Action {
+
+	public enum NavigationType {
+		PREVIOUS,
+		NEXT;
+
+		public String toString() {
+			return Localization.getString(Strings.NavigationType_BaseName + name());
+		};
+	}
+
+	private NavigationType action;
+
+	public NavigateAction() {
+		action = NavigationType.NEXT;
+	}
+
+	public NavigateAction(NavigationType type) {
+		this.action = type;
+	}
+
+	public NavigationType getAction() {
+		return action;
+	}
+
+	public void setAction(NavigationType action) {
+		this.action = action;
+	}
+
+	@Override
+	public String getType() {
+		return NavigateActionConnect.TYPE;
+	}
+
+	@Override
+	public void initFeedback(Project project, IMainViewController controller) {
+		handleFeedback(FeedbackMessage.STANDARD);
+	}
+
+	@Override
+	public void clearFeedback() {
+		handleFeedback(FeedbackMessage.OFF);
+	}
+
+	@Override
+	public void performAction(InputType type, Project project, IMainViewController mainViewController) {
+		if (type == InputType.PRESSED) {
+			switch (this.action) {
+			case PREVIOUS:
+				Platform.runLater(() -> mainViewController.showPage(mainViewController.getPage() - 1));
+				break;
+			case NEXT:
+				Platform.runLater(() -> mainViewController.showPage(mainViewController.getPage() + 1));
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	@Override
+	public FeedbackType geFeedbackType() {
+		return FeedbackType.SINGLE;
+	}
+
+	private static final String TYPE = "action";
+
+	@Override
+	public void load(Element root) {
+		action = NavigationType.valueOf(root.attributeValue(TYPE));
+	}
+
+	@Override
+	public void save(Element root) {
+		root.addAttribute(TYPE, action.name());
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof NavigateAction) {
+			return ((NavigateAction) obj).getAction() == action;
+		}
+		return super.equals(obj);
+	}
+
+	@Override
+	public String toString() {
+		return Localization.getString(Strings.Action_Navigate_toString, action.toString());
+	}
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty(toString());
+	}
+
+	@Override
+	public Action cloneAction() throws CloneNotSupportedException {
+		NavigateAction actionClone = (NavigateAction) super.clone();
+
+		actionClone.action = this.action;
+
+		return actionClone;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/actions/PageAction.java b/PlayWall/src/de/tobias/playpad/action/actions/PageAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..6cc149eb532554103b8b7f3b1badf41ab10b11f3
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/actions/PageAction.java
@@ -0,0 +1,108 @@
+package de.tobias.playpad.action.actions;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.InputType;
+import de.tobias.playpad.action.connect.PageActionConnect;
+import de.tobias.playpad.action.feedback.FeedbackMessage;
+import de.tobias.playpad.action.feedback.FeedbackType;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.util.Localization;
+import javafx.application.Platform;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class PageAction extends Action {
+
+	private int page;
+
+	public PageAction() {
+		this.page = 0;
+	}
+
+	public PageAction(int page) {
+		super();
+		this.page = page;
+	}
+
+	public int getPage() {
+		return page;
+	}
+
+	public void setPage(int page) {
+		this.page = page;
+	}
+
+	@Override
+	public String getType() {
+		return PageActionConnect.TYPE;
+	}
+
+	@Override
+	public void initFeedback(Project project, IMainViewController controller) {
+		int page = controller.getPage();
+		if (page == this.page) {
+			handleFeedback(FeedbackMessage.EVENT);
+		} else {
+			handleFeedback(FeedbackMessage.STANDARD);
+		}
+	}
+
+	@Override
+	public void clearFeedback() {
+		handleFeedback(FeedbackMessage.OFF);
+	}
+
+	@Override
+	public void performAction(InputType type, Project project, IMainViewController mainViewController) {
+		if (type == InputType.PRESSED) {
+			Platform.runLater(() -> mainViewController.showPage(page));
+		}
+	}
+
+	@Override
+	public FeedbackType geFeedbackType() {
+		return FeedbackType.DOUBLE;
+	}
+
+	private static final String PAGE = "page";
+
+	@Override
+	public void load(Element root) {
+		page = Integer.valueOf(root.attributeValue(PAGE));
+	}
+
+	@Override
+	public void save(Element root) {
+		root.addAttribute(PAGE, String.valueOf(page));
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof PageAction) {
+			return ((PageAction) obj).getPage() == page;
+		}
+		return super.equals(obj);
+	}
+
+	@Override
+	public String toString() {
+		return Localization.getString(Strings.Action_Page_toString, String.valueOf(page + 1));
+	}
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty(toString());
+	}
+
+	public Action cloneAction() throws CloneNotSupportedException {
+		PageAction action = (PageAction) super.clone();
+
+		action.page = page;
+
+		return action;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java b/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..5dd5cf62b8df9d6766281d5ab0a85ce8dcb0531c
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java
@@ -0,0 +1,254 @@
+package de.tobias.playpad.action.cartaction;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.InputType;
+import de.tobias.playpad.action.connect.CartActionConnect;
+import de.tobias.playpad.action.feedback.FeedbackType;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.Durationable;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.viewcontroller.actions.CartActionViewController;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class CartAction extends Action {
+
+	public enum ControlMode {
+		PLAY_PAUSE,
+		PLAY_STOP,
+		PLAY_HOLD;
+	}
+
+	private int cart;
+	private ControlMode mode;
+	private boolean autoFeedbackColors;
+
+	private transient Pad pad;
+	private transient PadStatusFeedbackListener padStatusFeedbackListener = new PadStatusFeedbackListener();
+	private transient PadPositionWarningListener padPositionListener = new PadPositionWarningListener(this);
+
+	public CartAction() {
+		this.cart = 0;
+		this.mode = ControlMode.PLAY_STOP;
+		this.autoFeedbackColors = true;
+	}
+
+	public CartAction(int cart, ControlMode mode) {
+		this.cart = cart;
+		this.mode = mode;
+		this.autoFeedbackColors = true;
+	}
+
+	public int getCart() {
+		return cart;
+	}
+
+	public void setCart(int cart) {
+		this.cart = cart;
+	}
+
+	public ControlMode getMode() {
+		return mode;
+	}
+
+	public void setMode(ControlMode mode) {
+		this.mode = mode;
+	}
+
+	public boolean isAutoFeedbackColors() {
+		return autoFeedbackColors;
+	}
+
+	public void setAutoFeedbackColors(boolean autoFeedbackColors) {
+		this.autoFeedbackColors = autoFeedbackColors;
+	}
+
+	// Helper
+	public Pad getPad() {
+		return pad;
+	}
+
+	@Override
+	public void initFeedback(Project project, IMainViewController controller) {
+		Pad pad = project.getPad(cart);
+		setPad(pad);
+		// init first feedback
+		padStatusFeedbackListener.changed(null, null, pad.getStatus());
+	}
+
+	@Override
+	public void clearFeedback() {
+		setPad(null);
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof CartAction) {
+			CartAction action2 = (CartAction) obj;
+			if (action2.cart == cart) {
+				return true;
+			}
+		}
+		return super.equals(obj);
+	}
+
+	@Override
+	public String getType() {
+		return CartActionConnect.TYPE;
+	}
+
+	@Override
+	public void performAction(InputType type, Project project, IMainViewController mainViewController) {
+		setPad(project.getPad(cart));
+
+		// wird nur ausgeführt, wenn das Pad ein Content hat und sichtbar in der GUI (Gilt für MIDI und Keyboard)
+		if (pad.getContent() != null && pad.getContent().isPadLoaded() && pad.isPadVisible()) {
+			switch (mode) {
+			case PLAY_STOP:
+				if (type == InputType.PRESSED) {
+					if (pad.getStatus() == PadStatus.PLAY) {
+						pad.setStatus(PadStatus.STOP);
+					} else {
+						// Allow the listener to send the feedback
+						padPositionListener.setSend(false);
+
+						pad.setStatus(PadStatus.PLAY);
+					}
+				}
+				break;
+			case PLAY_HOLD:
+				if (type == InputType.PRESSED) {
+					if (pad.getStatus() == PadStatus.READY) {
+						// Allow the listener to send the feedback
+						padPositionListener.setSend(false);
+
+						pad.setStatus(PadStatus.PLAY);
+					}
+				} else if (type == InputType.RELEASED) {
+					if (pad.getStatus() == PadStatus.PLAY) {
+						pad.setStatus(PadStatus.STOP);
+					}
+				}
+				break;
+			case PLAY_PAUSE:
+				if (type == InputType.PRESSED) {
+					if (pad.getStatus() == PadStatus.PLAY) {
+						pad.setStatus(PadStatus.PAUSE);
+					} else {
+						// Allow the listener to send the feedback
+						padPositionListener.setSend(false);
+
+						pad.setStatus(PadStatus.PLAY);
+					}
+				}
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	@Override
+	public FeedbackType geFeedbackType() {
+		return FeedbackType.DOUBLE;
+	}
+
+	private static final String CART_ID = "id";
+	private static final String CONTROL_MDOE = "mode";
+	private static final String AUTO_FEEDBACK_COLORS = "autoColor";
+
+	@Override
+	public void load(Element root) {
+		cart = Integer.valueOf(root.attributeValue(CART_ID));
+		mode = ControlMode.valueOf(root.attributeValue(CONTROL_MDOE));
+		autoFeedbackColors = Boolean.valueOf(root.attributeValue(AUTO_FEEDBACK_COLORS));
+	}
+
+	@Override
+	public void save(Element root) {
+		root.addAttribute(CART_ID, String.valueOf(cart));
+		root.addAttribute(CONTROL_MDOE, mode.name());
+		root.addAttribute(AUTO_FEEDBACK_COLORS, String.valueOf(autoFeedbackColors));
+	}
+
+	public void setPad(Pad newPad) {
+		Pad oldPad = this.pad;
+		if (newPad == null || !newPad.equals(oldPad) || oldPad == null) {
+			// Remove old Listener
+			if (oldPad != null) {
+				if (oldPad.getContent() != null) {
+					if (oldPad.getContent() instanceof Durationable) {
+						Durationable durationable = (Durationable) oldPad.getContent();
+						durationable.positionProperty().removeListener(padPositionListener);
+					}
+				}
+				oldPad.statusProperty().removeListener(padStatusFeedbackListener);
+			}
+
+			this.pad = newPad;
+
+			if (newPad != null) {
+				// Add new listener
+				if (newPad.getContent() != null) {
+					if (newPad.getContent() instanceof Durationable) {
+						padPositionListener.setPad(newPad);
+						Durationable durationable = (Durationable) newPad.getContent();
+						durationable.positionProperty().addListener(padPositionListener);
+					}
+				}
+				padStatusFeedbackListener.setAction(this);
+				newPad.statusProperty().addListener(padStatusFeedbackListener);
+			}
+		}
+	}
+
+	// Listener
+	public PadPositionWarningListener getPadPositionListener() {
+		return padPositionListener;
+	}
+
+	public PadStatusFeedbackListener getPadStatusFeedbackListener() {
+		return padStatusFeedbackListener;
+	}
+
+	// Helper
+	@Override
+	public Action cloneAction() throws CloneNotSupportedException {
+		CartAction action = (CartAction) super.clone();
+
+		action.autoFeedbackColors = autoFeedbackColors;
+		action.cart = cart;
+		action.mode = mode;
+
+		return action;
+	}
+
+	// UI Helper
+	@Override
+	public String toString() {
+		return Localization.getString(Strings.Action_Cart_toString, String.valueOf(cart + 1));
+	}
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty(toString());
+	}
+
+	private static CartActionViewController cartActionViewController;
+
+	@Override
+	public ContentViewController getSettingsViewController() {
+		if (cartActionViewController == null) {
+			cartActionViewController = new CartActionViewController();
+		}
+		cartActionViewController.setCartAction(this);
+		return cartActionViewController;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java b/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..65f551b6321c8e46fa49d35b40072c15239f6f3c
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java
@@ -0,0 +1,56 @@
+package de.tobias.playpad.action.cartaction;
+
+import de.tobias.playpad.action.feedback.FeedbackMessage;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.Warning;
+import de.tobias.playpad.pad.conntent.Durationable;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.util.Duration;
+
+public class PadPositionWarningListener implements ChangeListener<Duration> {
+
+	private Pad pad;
+	private CartAction action;
+
+	boolean send = false;
+
+	public PadPositionWarningListener(CartAction action) {
+		this.action = action;
+	}
+
+	public void setPad(Pad pad) {
+		this.pad = pad;
+	}
+
+	@Override
+	public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
+		// Nur wenn Pad Sichtbar ist
+		if (pad != null && pad.isPadVisible()) {
+			if (pad.getContent() instanceof Durationable) {
+				Durationable durationable = (Durationable) pad.getContent();
+
+				// Warning nur wenn kein Loop
+				if (!pad.isLoop()) {
+					// Warning
+					Warning warning = pad.getWarning();
+					Duration totalDuration = durationable.getDuration();
+					if (totalDuration != null) {
+						Duration rest = totalDuration.subtract(newValue);
+						double seconds = rest.toSeconds();
+
+						if (warning.getTime().toSeconds() > seconds && !send) {
+							action.handleFeedback(FeedbackMessage.WARNING);
+						}
+						send = true;
+					}
+				}
+			}
+		}
+	}
+
+	public void setSend(boolean send) {
+		this.send = send;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java b/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..63510122a06d136e3e4553a2866429fea6050bab
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java
@@ -0,0 +1,64 @@
+package de.tobias.playpad.action.cartaction;
+
+import de.tobias.playpad.action.feedback.FeedbackMessage;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.Durationable;
+import de.tobias.playpad.pad.Warning;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.util.Duration;
+
+public class PadStatusFeedbackListener implements ChangeListener<PadStatus> {
+
+	private CartAction action;
+
+	public void setAction(CartAction action) {
+		this.action = action;
+	}
+
+	@Override
+	public void changed(ObservableValue<? extends PadStatus> observable, PadStatus oldValue, PadStatus newValue) {
+		if (action != null) {
+			Pad pad = action.getPad();
+			if (pad.isPadVisible()) {
+				switch (newValue) {
+				case EMPTY: case ERROR:
+					action.handleFeedback(FeedbackMessage.OFF);
+					break;
+				case PAUSE:
+					action.handleFeedback(FeedbackMessage.STANDARD);
+					break;
+				case PLAY:
+					action.handleFeedback(FeedbackMessage.EVENT);
+
+					// Wenn Cart in Warning Zeitbereich und vomn Pause zu Play wechselt
+					try {
+						if (pad.getContent() instanceof Durationable) {
+							Durationable durationable = (Durationable) pad.getContent();
+							if (!pad.isLoop()) {
+								Warning warning = pad.getWarning();
+								Duration rest = durationable.getDuration().subtract(durationable.getPosition());
+								double seconds = rest.toSeconds();
+
+								if (warning.getTime().toSeconds() > seconds) {
+									action.handleFeedback(FeedbackMessage.WARNING);
+								}
+							}
+						}
+					} catch (Exception e) {}
+					break;
+				case READY:
+					action.handleFeedback(FeedbackMessage.STANDARD);
+					break;
+				case STOP:
+					action.handleFeedback(FeedbackMessage.STANDARD);
+					break;
+				default:
+					break;
+
+				}
+			}
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/connect/CartActionConnect.java b/PlayWall/src/de/tobias/playpad/action/connect/CartActionConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ceffddd45ab3f71657482af6db248b1deaa623f
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/connect/CartActionConnect.java
@@ -0,0 +1,78 @@
+package de.tobias.playpad.action.connect;
+
+import java.util.List;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.ActionConnect;
+import de.tobias.playpad.action.ActionDisplayable;
+import de.tobias.playpad.action.ActionType;
+import de.tobias.playpad.action.Mapping;
+import de.tobias.playpad.action.cartaction.CartAction;
+import de.tobias.playpad.action.cartaction.CartAction.ControlMode;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.playpad.viewcontroller.IMappingTabViewController;
+import de.tobias.playpad.viewcontroller.actions.CartActionsViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.scene.Node;
+import javafx.scene.control.TreeItem;
+
+public class CartActionConnect extends ActionConnect implements ActionDisplayable {
+
+	public static final String TYPE = "CART";
+
+	@Override
+	public TreeItem<ActionDisplayable> getTreeViewForActions(List<Action> actions, Mapping mapping) {
+		TreeItem<ActionDisplayable> rootItem = new TreeItem<>(this);
+		return rootItem;
+	}
+
+	@Override
+	public void initActionType(Mapping mapping, Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+		int pads = profileSettings.getColumns() * profileSettings.getRows() * profileSettings.getPageCount();
+
+		for (int i = 0; i < pads; i++) {
+			CartAction action = new CartAction(i, ControlMode.PLAY_STOP);
+			mapping.addActionIfNotContains(action);
+		}
+	}
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty(Localization.getString(Strings.Action_Cart_Name));
+	}
+
+	@Override
+	public Node getGraphics() {
+		return new FontIcon(FontAwesomeType.TH);
+	}
+
+	// Settings View (Übersicht mit den Buttons). Die Buttons rufen dann die jeweilige CartAction auf. Da muss dann auch die MapperView
+	// manuell gesetzt werden.
+	@Override
+	public ContentViewController getActionSettingsViewController(Mapping mapping, IMappingTabViewController controller) {
+		return new CartActionsViewController(mapping, controller);
+	}
+
+	@Override
+	public Action newInstance() {
+		return new CartAction();
+	}
+
+	@Override
+	public ActionType geActionType() {
+		return ActionType.CONTROL;
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/connect/NavigateActionConnect.java b/PlayWall/src/de/tobias/playpad/action/connect/NavigateActionConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..43c8993ad95b68351a98cd8bf7e8acea2a96cfb0
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/connect/NavigateActionConnect.java
@@ -0,0 +1,85 @@
+package de.tobias.playpad.action.connect;
+
+import java.util.Collections;
+import java.util.List;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.ActionConnect;
+import de.tobias.playpad.action.ActionDisplayable;
+import de.tobias.playpad.action.ActionType;
+import de.tobias.playpad.action.Mapping;
+import de.tobias.playpad.action.actions.NavigateAction;
+import de.tobias.playpad.action.actions.NavigateAction.NavigationType;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.ui.icon.MaterialDesignIcon;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.scene.Node;
+import javafx.scene.control.TreeItem;
+
+public class NavigateActionConnect extends ActionConnect implements ActionDisplayable {
+
+	public static final String TYPE = "NAVIGATE";
+
+	@Override
+	public TreeItem<ActionDisplayable> getTreeViewForActions(List<Action> actions, Mapping mapping) {
+		TreeItem<ActionDisplayable> rootItem = new TreeItem<>(this);
+
+		Collections.sort(actions, (o1, o2) ->
+		{
+			if (o1 instanceof NavigateAction && o2 instanceof NavigateAction) {
+				NavigateAction c1 = (NavigateAction) o1;
+				NavigateAction c2 = (NavigateAction) o2;
+				return Long.compare(c1.getAction().ordinal(), c2.getAction().ordinal());
+			} else {
+				return -1;
+			}
+		});
+
+		for (Action action : actions) {
+			TreeItem<ActionDisplayable> actionItem = new TreeItem<>(action);
+			rootItem.getChildren().add(actionItem);
+		}
+		return rootItem;
+	}
+
+	@Override
+	public void initActionType(Mapping mapping, Profile profile) {
+		mapping.addActionIfNotContains(new NavigateAction(NavigationType.PREVIOUS));
+		mapping.addActionIfNotContains(new NavigateAction(NavigationType.NEXT));
+	}
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty(Localization.getString(Strings.Action_Navigate_Name));
+	}
+
+	@Override
+	public Node getGraphics() {
+		return new FontIcon(MaterialDesignIcon.FONT_FILE, MaterialDesignIcon.NAVIGATION);
+	}
+
+	@Override
+	public ContentViewController getSettingsViewController() {
+		return null;
+	}
+
+	@Override
+	public Action newInstance() {
+		return new NavigateAction();
+	}
+
+	@Override
+	public ActionType geActionType() {
+		return ActionType.CONTROL;
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/connect/PageActionConnect.java b/PlayWall/src/de/tobias/playpad/action/connect/PageActionConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..7323dca268b9da3fb05725de777c13f833ba21ec
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/connect/PageActionConnect.java
@@ -0,0 +1,90 @@
+package de.tobias.playpad.action.connect;
+
+import java.util.Collections;
+import java.util.List;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.ActionConnect;
+import de.tobias.playpad.action.ActionDisplayable;
+import de.tobias.playpad.action.ActionType;
+import de.tobias.playpad.action.Mapping;
+import de.tobias.playpad.action.actions.PageAction;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.scene.Node;
+import javafx.scene.control.TreeItem;
+
+public class PageActionConnect extends ActionConnect implements ActionDisplayable {
+
+	public static final String TYPE = "PAGE";
+
+	@Override
+	public TreeItem<ActionDisplayable> getTreeViewForActions(List<Action> actions, Mapping mapping) {
+		TreeItem<ActionDisplayable> rootItem = new TreeItem<>(this);
+
+		Collections.sort(actions, (o1, o2) ->
+		{
+			if (o1 instanceof PageAction && o2 instanceof PageAction) {
+				PageAction c1 = (PageAction) o1;
+				PageAction c2 = (PageAction) o2;
+				return Long.compare(c1.getPage(), c2.getPage());
+			} else {
+				return -1;
+			}
+		});
+
+		for (Action action : actions) {
+			TreeItem<ActionDisplayable> actionItem = new TreeItem<>(action);
+			rootItem.getChildren().add(actionItem);
+		}
+
+		return rootItem;
+	}
+
+	@Override
+	public void initActionType(Mapping mapping, Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+		int pages = profileSettings.getPageCount();
+		for (int i = 0; i < pages; i++) {
+			PageAction action = new PageAction(i);
+			mapping.addActionIfNotContains(action);
+		}
+	}
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty(Localization.getString(Strings.Action_Page_Name));
+	}
+
+	@Override
+	public Node getGraphics() {
+		return new FontIcon(FontAwesomeType.FILE_TEXT);
+	}
+
+	@Override
+	public ContentViewController getSettingsViewController() {
+		return null;
+	}
+
+	@Override
+	public Action newInstance() {
+		return new PageAction();
+	}
+
+	@Override
+	public ActionType geActionType() {
+		return ActionType.CONTROL;
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/mapper/KeyboardMapper.java b/PlayWall/src/de/tobias/playpad/action/mapper/KeyboardMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..4777e9ef78d5aaf08b4e5b9e999a49e2ab6626ba
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/mapper/KeyboardMapper.java
@@ -0,0 +1,120 @@
+package de.tobias.playpad.action.mapper;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.viewcontroller.mapper.KeyboardMapperViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.StringUtils;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.scene.input.KeyCode;
+
+public class KeyboardMapper extends Mapper {
+
+	private KeyCode code;
+	private String key;
+
+	public KeyboardMapper() {
+		this.code = KeyCode.A;
+		this.key = "A";
+		updateDisplayProperty();
+	}
+
+	public KeyboardMapper(KeyCode code, String key) {
+		this.code = code;
+		this.key = key;
+		updateDisplayProperty();
+	}
+
+	public KeyCode getCode() {
+		return code;
+	}
+
+	public void setCode(KeyCode code) {
+		this.code = code;
+		updateDisplayProperty();
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+		updateDisplayProperty();
+	}
+
+	@Override
+	public String getType() {
+		return KeyboardMapperConnect.TYPE;
+	}
+
+	public String getReadableName() {
+		if (!StringUtils.isStringNotVisable(getKey())) {
+			return getKey();
+		} else {
+			return getCode().getName();
+		}
+	}
+
+	// Not Used for Keyboards
+	@Override
+	protected void initFeedback() {}
+
+	private static final String KEY = "key";
+	private static final String CODE = "code";
+
+	@Override
+	public void load(Element element, Action action) {
+		key = element.attributeValue(KEY);
+		code = KeyCode.valueOf(element.attributeValue(CODE));
+	}
+
+	@Override
+	public void save(Element element, Action action) {
+		element.addAttribute(KEY, key);
+		element.addAttribute(CODE, code.name());
+	}
+
+	@Override
+	public String toString() {
+		return Localization.getString(Strings.Mapper_Keyboard_toString, getReadableName());
+	}
+
+	private StringProperty displayProperty = new SimpleStringProperty();
+
+	@Override
+	public StringProperty displayProperty() {
+		updateDisplayProperty();
+		return displayProperty;
+	}
+
+	private void updateDisplayProperty() {
+		displayProperty.set(toString());
+	}
+
+	private KeyboardMapperViewController settingsViewController;
+
+	@Override
+	public ContentViewController getSettingsViewController() {
+		if (settingsViewController == null) {
+			settingsViewController = new KeyboardMapperViewController();
+		}
+		settingsViewController.setMapper(this);
+		return settingsViewController;
+	}
+
+	@Override
+	public Mapper cloneMapper() throws CloneNotSupportedException {
+		KeyboardMapper mapper = (KeyboardMapper) super.clone();
+
+		mapper.code = code;
+		mapper.key = key;
+		mapper.displayProperty = new SimpleStringProperty();
+
+		return mapper;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/mapper/KeyboardMapperConnect.java b/PlayWall/src/de/tobias/playpad/action/mapper/KeyboardMapperConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..89bec3547663841b401e36f5101152151a38aa6b
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/mapper/KeyboardMapperConnect.java
@@ -0,0 +1,29 @@
+package de.tobias.playpad.action.mapper;
+
+import de.tobias.playpad.Strings;
+import de.tobias.utils.util.Localization;
+
+public class KeyboardMapperConnect extends MapperConnect {
+
+	public static final String TYPE = "KEYBOARD";
+
+	@Override
+	public MapperViewController getQuickSettingsViewController(Mapper mapper) {
+		return null;
+	}
+
+	@Override
+	public Mapper createNewMapper() {
+		return new KeyboardMapper();
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public String toString() {
+		return Localization.getString(Strings.Mapper_Keyboard_Name);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..7cc2b7e3b2d70465dc1e894b82fe269826c83a4b
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java
@@ -0,0 +1,225 @@
+package de.tobias.playpad.action.mapper;
+
+import java.util.Optional;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.feedback.ColorAssociator;
+import de.tobias.playpad.action.feedback.DisplayableFeedbackColor;
+import de.tobias.playpad.action.feedback.DoubleSimpleFeedback;
+import de.tobias.playpad.action.feedback.Feedback;
+import de.tobias.playpad.action.feedback.FeedbackMessage;
+import de.tobias.playpad.action.feedback.FeedbackType;
+import de.tobias.playpad.action.feedback.SingleSimpleFeedback;
+import de.tobias.playpad.action.mididevice.Device;
+import de.tobias.playpad.action.mididevice.DeviceColorAssociatorConnector;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.viewcontroller.mapper.MidiMapperViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class MidiMapper extends Mapper implements ColorAssociator, MapperFeedbackable {
+
+	private int command;
+	private int key;
+
+	private Feedback feedback;
+	private FeedbackType feedbackType;
+
+	public MidiMapper() {
+		this.command = 0;
+		this.key = 0;
+
+		updateDisplayProperty();
+	}
+
+	public MidiMapper(int command, int key) {
+		this.command = command;
+		this.key = key;
+		updateDisplayProperty();
+	}
+
+	public int getCommand() {
+		return command;
+	}
+
+	public void setCommand(int command) {
+		this.command = command;
+		updateDisplayProperty();
+	}
+
+	public int getKey() {
+		return key;
+	}
+
+	public void setKey(int key) {
+		this.key = key;
+		updateDisplayProperty();
+	}
+
+	@Override
+	protected void initFeedback() {
+		if (feedback == null || this.feedbackType != super.feedbackType) {
+			if (super.feedbackType == FeedbackType.SINGLE) {
+				feedback = new SingleSimpleFeedback();
+			} else if (super.feedbackType == FeedbackType.DOUBLE) {
+				feedback = new DoubleSimpleFeedback();
+			}
+		}
+		this.feedbackType = super.feedbackType;
+	}
+
+	public Feedback getFeedback() {
+		return feedback;
+	}
+
+	public void setFeedback(Feedback feedback) {
+		this.feedback = feedback;
+	}
+
+	@Override
+	public void handleFeedback(FeedbackMessage type) {
+		Midi.getInstance().getMidiDevice().ifPresent(device -> device.handleFeedback(type, key, feedback));
+	}
+
+	@Override
+	public String getType() {
+		return MidiMapperConnect.TYPE;
+	}
+
+	// Feedback, abhängig vom Device
+	@Override
+	public boolean supportFeedback() {
+		Optional<Device> midiDevice = Midi.getInstance().getMidiDevice();
+		if (midiDevice.isPresent()) {
+			return midiDevice.get().supportFeedback();
+		}
+		return false;
+	}
+
+	@Override
+	public void setColor(FeedbackMessage feedbackMessage, int value) {
+		if (feedbackMessage == FeedbackMessage.STANDARD || feedbackMessage == FeedbackMessage.EVENT) {
+			feedback.setFeedback(feedbackMessage, value);
+		} else {
+			throw new IllegalArgumentException("Unexpected Message Type.");
+		}
+	}
+
+	@Override
+	public DisplayableFeedbackColor[] getColors() {
+		Optional<Device> midiDevice = Midi.getInstance().getMidiDevice();
+		if (midiDevice.isPresent()) {
+			Device device = midiDevice.get();
+			if (device instanceof DeviceColorAssociatorConnector) {
+				return ((DeviceColorAssociatorConnector) device).getColors();
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public DisplayableFeedbackColor getDefaultEventColor() {
+		Optional<Device> midiDevice = Midi.getInstance().getMidiDevice();
+		if (midiDevice.isPresent()) {
+			Device device = midiDevice.get();
+			if (device instanceof DeviceColorAssociatorConnector) {
+				return ((DeviceColorAssociatorConnector) device).getDefaultEventColor();
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public DisplayableFeedbackColor getDefaultStandardColor() {
+		Optional<Device> midiDevice = Midi.getInstance().getMidiDevice();
+		if (midiDevice.isPresent()) {
+			Device device = midiDevice.get();
+			if (device instanceof DeviceColorAssociatorConnector) {
+				return ((DeviceColorAssociatorConnector) device).getDefaultStandardColor();
+			}
+		}
+		return null;
+	}
+
+	private static final String MIDI_COMMAND = "command";
+	private static final String MIDI_KEY = "key";
+	private static final String FEEDBACK = "Feedback";
+
+	@Override
+	public void load(Element element, Action action) {
+		String commandValue = element.attributeValue(MIDI_COMMAND);
+		String keyValue = element.attributeValue(MIDI_KEY);
+
+		if (commandValue != null) {
+			command = Integer.valueOf(commandValue);
+		}
+		if (keyValue != null) {
+			key = Integer.valueOf(keyValue);
+		}
+
+		Element feedbackElement = element.element(FEEDBACK);
+		setFeedbackType(action.geFeedbackType());
+		if (feedback != null) {
+			feedback.load(feedbackElement);
+		} else {
+			initFeedback();
+		}
+	}
+
+	@Override
+	public void save(Element element, Action action) {
+		element.addAttribute(MIDI_COMMAND, String.valueOf(command));
+		element.addAttribute(MIDI_KEY, String.valueOf(key));
+
+		Element feedbackElement = element.addElement(FEEDBACK);
+		if (feedback != null) {
+			feedback.save(feedbackElement);
+		}
+	}
+
+	@Override
+	public String toString() {
+		return Localization.getString(Strings.Mapper_Midi_toString, key);
+	}
+
+	private StringProperty displayProperty = new SimpleStringProperty();
+
+	@Override
+	public StringProperty displayProperty() {
+		updateDisplayProperty();
+		return displayProperty;
+	}
+
+	private MidiMapperViewController settingsViewController;
+
+	@Override
+	public ContentViewController getSettingsViewController() {
+		if (settingsViewController == null) {
+			settingsViewController = new MidiMapperViewController();
+		}
+		settingsViewController.setMapper(this);
+		return settingsViewController;
+	}
+
+	private void updateDisplayProperty() {
+		displayProperty.set(toString());
+	}
+
+	@Override
+	public Mapper cloneMapper() throws CloneNotSupportedException {
+		MidiMapper mapper = (MidiMapper) super.clone();
+
+		mapper.command = command;
+		mapper.feedback = feedback.cloneFeedback();
+		mapper.key = key;
+
+		mapper.displayProperty = new SimpleStringProperty();
+
+		return mapper;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapperConnect.java b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapperConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..f9f169dd42791b3c686c9656ad5056ca0c6098fe
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapperConnect.java
@@ -0,0 +1,40 @@
+package de.tobias.playpad.action.mapper;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.utils.util.Localization;
+
+public class MidiMapperConnect extends MapperConnect implements MapperConnectFeedbackable {
+
+	public static final String TYPE = "MIDI";
+
+	@Override
+	public MapperViewController getQuickSettingsViewController(Mapper mapper) {
+		return null;
+	}
+
+	@Override
+	public Mapper createNewMapper() {
+		return new MidiMapper();
+	}
+
+	@Override
+	public void initFeedbackType() {
+		Midi.getInstance().getMidiDevice().ifPresent(device -> device.initFeedback());
+	}
+
+	@Override
+	public void clearFeedbackType() {
+		Midi.getInstance().getMidiDevice().ifPresent(device -> device.clearFeedback());
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public String toString() {
+		return Localization.getString(Strings.Mapper_Midi_Name);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/mapper/listener/KeyboardHandler.java b/PlayWall/src/de/tobias/playpad/action/mapper/listener/KeyboardHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..953b862132bb4ab8fdd2d03dde4ccec0c31a2c33
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/mapper/listener/KeyboardHandler.java
@@ -0,0 +1,67 @@
+package de.tobias.playpad.action.mapper.listener;
+
+import java.util.List;
+
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.InputType;
+import de.tobias.playpad.action.MappingUtils;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import javafx.event.EventHandler;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+
+public class KeyboardHandler implements EventHandler<KeyEvent> {
+
+	private Project project;
+	private IMainViewController mainViewController;
+
+	public KeyboardHandler(Project project, IMainViewController mainViewController) {
+		this.project = project;
+		this.mainViewController = mainViewController;
+
+		mainViewController.getParent().getScene().setOnKeyPressed(this);
+		mainViewController.getParent().getScene().setOnKeyReleased(this);
+		mainViewController.getParent().getScene().setOnKeyTyped(this);
+	}
+
+	private boolean[] keys = new boolean[KeyCode.values().length];
+
+	@Override
+	public void handle(KeyEvent event) {
+		if (!event.isShortcutDown()) {
+			KeyCode code = null;
+			InputType type = null;
+
+			if (event.getEventType() == KeyEvent.KEY_PRESSED) {
+				code = event.getCode();
+				type = InputType.PRESSED;
+
+				if (keys[code.ordinal()] == true) {
+					return;
+				}
+
+				keys[code.ordinal()] = true;
+			} else if (event.getEventType() == KeyEvent.KEY_RELEASED) {
+				code = event.getCode();
+				type = InputType.RELEASED;
+
+				keys[code.ordinal()] = false;
+			}
+
+			// Only execute this, then the right event is triggered and this var is set
+			if (code != null) {
+				List<Action> actions = MappingUtils.getActionsForKey(code, Profile.currentProfile().getMappings().getActiveMapping());
+
+				for (Action action : actions) {
+					action.performAction(type, project, mainViewController);
+				}
+			}
+		}
+	}
+
+	public void setProject(Project project) {
+		this.project = project;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/action/mapper/listener/MidiHandler.java b/PlayWall/src/de/tobias/playpad/action/mapper/listener/MidiHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..b63415aed4d0a04705785ab898cf57971ebb42de
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/action/mapper/listener/MidiHandler.java
@@ -0,0 +1,66 @@
+package de.tobias.playpad.action.mapper.listener;
+
+import java.util.List;
+
+import javax.sound.midi.MidiMessage;
+
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.InputType;
+import de.tobias.playpad.action.MappingUtils;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.midi.MidiListener;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import javafx.application.Platform;
+
+/**
+ * Diese Klasse Verwaltet den MIDI Input und führt die Actions aus.
+ * 
+ * @author tobias
+ *
+ */
+public class MidiHandler implements MidiListener {
+
+	private final Midi midi;
+
+	private IMainViewController mainView;
+	private Project project;
+
+	public MidiHandler(Midi midi, IMainViewController mainView, Project project) {
+		this.midi = midi;
+		this.mainView = mainView;
+		this.project = project;
+	}
+
+	/**
+	 * Midi Input Listener
+	 */
+	@Override
+	public void onMidiAction(MidiMessage message) {
+		int cmd = message.getMessage()[0];
+		int key = message.getMessage()[1];
+
+		// Custom Midi Listener
+		midi.getMidiDevice().ifPresent(device -> device.onMidiMessage(message));
+
+		InputType type;
+		if (message.getMessage()[2] != 0) {
+			type = InputType.PRESSED;
+		} else {
+			type = InputType.RELEASED;
+		}
+
+		Platform.runLater(() ->
+		{
+			List<Action> actions = MappingUtils.getActionsForMidi(cmd, key, Profile.currentProfile().getMappings().getActiveMapping());
+			for (Action action : actions) {
+				action.performAction(type, project, mainView);
+			}
+		});
+	}
+
+	public void setProject(Project project) {
+		this.project = project;
+	}
+}
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..86f4617ea6b350352eca1a0b6540cce72cf89102
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java
@@ -0,0 +1,252 @@
+package de.tobias.playpad.audio;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.DataLine.Info;
+import javax.sound.sampled.FloatControl;
+import javax.sound.sampled.Mixer;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.content.AudioContent;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.utils.util.FileUtils;
+import javafx.application.Platform;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.util.Duration;
+import javazoom.jl.converter.Converter;
+import javazoom.jl.decoder.JavaLayerException;
+
+public class ClipAudioHandler extends AudioHandler {
+
+	public static final String NAME = "Clip";
+	private static final String MP3 = "mp3";
+
+	private Mixer mixer;
+	private Clip clip;
+	private FloatControl volumeControl;
+
+	private ObjectProperty<Duration> durationProperty;
+	private ObjectProperty<Duration> positionProperty;
+
+	private transient boolean pause;
+	private transient boolean stop;
+
+	private static final int SLEEP_TIME_POSITION = 50;
+	private static Thread positionThread;
+	private static List<ClipAudioHandler> playedHandlers = new ArrayList<>();
+
+	static {
+		positionThread = new Thread(() ->
+		{
+			while (true) {
+				try {
+					if (playedHandlers.isEmpty()) {
+						synchronized (positionThread) {
+							positionThread.wait();
+						}
+					}
+
+					for (Iterator<ClipAudioHandler> iterator = playedHandlers.iterator(); iterator.hasNext();) {
+						ClipAudioHandler handler = iterator.next();
+						Pad pad = handler.getContent().getPad();
+
+						if (handler.clip != null) {
+							if (handler.clip.getMicrosecondLength() == handler.clip.getMicrosecondPosition() || !handler.pause || handler.stop) {
+								if (!pad.isLoop()) {
+									pad.setEof(true);
+
+									// Remove from Loop and Stop
+									iterator.remove();
+									Platform.runLater(() -> pad.setStatus(PadStatus.STOP));
+								}
+							}
+						}
+
+						// Update der Zeit
+						Platform.runLater(() -> handler.positionProperty.set(Duration.millis(handler.clip.getMicrosecondPosition() / 1000.0)));
+					}
+
+					Thread.sleep(SLEEP_TIME_POSITION);
+				} catch (InterruptedException e) {} catch (ConcurrentModificationException e) {} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		});
+
+		positionThread.start();
+	}
+
+	public ClipAudioHandler(PadContent content) {
+		super(content);
+		durationProperty = new SimpleObjectProperty<>();
+		positionProperty = new SimpleObjectProperty<>();
+	}
+
+	@Override
+	public void play() {
+		if (!pause) {
+			clip.setFramePosition(0);
+			pause = false;
+		}
+		stop = false;
+
+		if (getContent().getPad().isLoop())
+			clip.loop(Clip.LOOP_CONTINUOUSLY); // Loop
+		else
+			clip.start(); // Einfach Play
+
+		boolean start = false;
+		if (playedHandlers.isEmpty()) {
+			start = true;
+		}
+
+		if (!playedHandlers.contains(this))
+			playedHandlers.add(this);
+		if (start) {
+			synchronized (positionThread) {
+				positionThread.notify();
+			}
+		}
+	}
+
+	@Override
+	public void pause() {
+		clip.stop();
+		pause = true;
+		if (playedHandlers.contains(this))
+			playedHandlers.remove(this);
+	}
+
+	@Override
+	public void stop() {
+		clip.stop();
+		stop = true;
+		pause = false;
+		if (playedHandlers.contains(this))
+			playedHandlers.remove(this);
+	}
+
+	@Override
+	public Duration getPosition() {
+		return positionProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> positionProperty() {
+		return positionProperty;
+	}
+
+	@Override
+	public Duration getDuration() {
+		return durationProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> durationProperty() {
+		return durationProperty;
+	}
+
+	@Override
+	public void setVolume(double volume, double masterVolume) {
+		setVolume(masterVolume * volume);
+	}
+
+	/**
+	 * Lineaer to dB
+	 * 
+	 * @param volume
+	 *            [0, 1]
+	 */
+	private void setVolume(double volume) {
+		if (volumeControl != null) {
+			if (volume == 1.0) {
+				volumeControl.setValue(0);
+			} else if (volume == 0.0) {
+				volumeControl.setValue(volumeControl.getMinimum());
+			} else {
+				float newValue = (float) (Math.log10(volume) * 20.0);
+				if (newValue > volumeControl.getMinimum())
+					volumeControl.setValue(newValue);
+				else
+					volumeControl.setValue(volumeControl.getMinimum());
+			}
+		}
+	}
+
+	@Override
+	public boolean isMediaLoaded() {
+		return clip != null;
+	}
+
+	@Override
+	public void loadMedia() {
+		mixer = AudioSystem.getMixer(AudioSystem.getMixerInfo()[0]);
+
+		DataLine.Info info = new Info(Clip.class, null);
+		try {
+			clip = (Clip) mixer.getLine(info);
+
+			Path path = ((AudioContent) getContent()).getPath();
+			URL url = path.toUri().toURL();
+
+			// Convert wenn mp3
+			if (FileUtils.getFileExtention(url.getFile()).toLowerCase().endsWith(MP3)) {
+				Path wavPath = Profile.currentProfile().getProfileSettings().getCachePath().resolve(path.getFileName().toString() + ".wav");
+				url = convertMp3ToWav(path, wavPath, getContent().getPad());
+			}
+
+			AudioContent content = (AudioContent) getContent();
+			AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
+
+			clip.open(audioInputStream);
+			volumeControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
+
+			durationProperty.set(Duration.millis(clip.getMicrosecondLength() / 1000.0));
+			content.getPad().setStatus(PadStatus.READY);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	private static URL convertMp3ToWav(Path orgPath, Path wavPath, Pad pad) throws JavaLayerException, URISyntaxException, IOException {
+		if (Files.notExists(wavPath)) {
+			Files.createDirectories(wavPath.getParent());
+			Files.createFile(wavPath);
+
+			Converter converter = new Converter();
+			converter.convert(orgPath.toString(), wavPath.toString());
+		}
+		return wavPath.toUri().toURL();
+	}
+
+	@Override
+	public void unloadMedia() {
+		clip.close();
+		mixer.close();
+
+		clip = null;
+		mixer = null;
+	}
+
+	@Override
+	public void updateVolume(double masterVolume) {
+		setVolume(getContent().getPad().getVolume(), masterVolume);
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0428e4db1774e8be59177263e9308bd682ca5a6
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java
@@ -0,0 +1,19 @@
+package de.tobias.playpad.audio;
+
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.viewcontroller.AudioTypeViewController;
+import de.tobias.playpad.viewcontroller.audio.ClipSettingsViewController;
+
+public class ClipAudioHandlerConnect extends AudioHandlerConnect {
+
+	@Override
+	public AudioHandler createAudioHandler(PadContent content) {
+		return new ClipAudioHandler(content);
+	}
+
+	@Override
+	public AudioTypeViewController getAudioViewController() {
+		return new ClipSettingsViewController();
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe5f86b0ab1ec417e8431d1f733b0ecdd54c1edb
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java
@@ -0,0 +1,160 @@
+package de.tobias.playpad.audio;
+
+import java.nio.file.Path;
+
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.content.AudioContent;
+import javafx.application.Platform;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.scene.media.AudioEqualizer;
+import javafx.scene.media.Media;
+import javafx.scene.media.MediaPlayer;
+import javafx.util.Duration;
+
+public class JavaFXAudioHandler extends AudioHandler implements Equalizable {
+
+	public static final String NAME = "Java FX Media";
+
+	private Media media;
+	private MediaPlayer player;
+
+	private ObjectProperty<Duration> durationProperty;
+
+	private BooleanProperty loadedProperty;
+
+	public JavaFXAudioHandler(PadContent content) {
+		super(content);
+
+		media = null;
+		player = null;
+		durationProperty = new SimpleObjectProperty<>();
+
+		loadedProperty = new SimpleBooleanProperty();
+	}
+
+	@Override
+	public void play() {
+		player.play();
+	}
+
+	@Override
+	public void pause() {
+		player.pause();
+	}
+
+	@Override
+	public void stop() {
+		player.stop();
+	}
+
+	@Override
+	public AudioEqualizer getAudioEqualizer() {
+		return player.getAudioEqualizer();
+	}
+
+	@Override
+	public Duration getPosition() {
+		return player.getCurrentTime();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> positionProperty() {
+		return player.currentTimeProperty();
+	}
+
+	@Override
+	public Duration getDuration() {
+		return durationProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> durationProperty() {
+		return durationProperty;
+	}
+
+	@Override
+	public void setVolume(double volume, double masterVolume) {
+		if (player != null)
+			player.setVolume(volume * masterVolume);
+	}
+
+	@Override
+	public boolean isMediaLoaded() {
+		return player != null;
+	}
+
+	@Override
+	public void loadMedia() {
+		Platform.runLater(() ->
+		{
+			if (getContent().getPad().isPadVisible()) {
+				getContent().getPad().getController().getParent().setBusy(true);
+			}
+		});
+
+		// Old Player
+		if (player != null) {
+			getContent().stop();
+		}
+
+		Path path = ((AudioContent) getContent()).getPath();
+		media = new Media(path.toFile().toURI().toString());
+		player = new MediaPlayer(media);
+
+		// Player Listener
+		player.setOnReady(() ->
+		{
+			durationProperty.set(player.getTotalDuration());
+			getContent().getPad().setStatus(PadStatus.READY);
+			loadedProperty.set(true);
+
+			Platform.runLater(() ->
+			{
+				if (getContent().getPad().isPadVisible()) {
+					getContent().getPad().getController().getParent().setBusy(false);
+				}
+			});
+		});
+
+		player.setOnError(() ->
+		{
+			Platform.runLater(() ->
+			{
+				if (getContent().getPad().isPadVisible()) {
+					getContent().getPad().getController().getParent().setBusy(false);
+				}
+			});
+			loadedProperty.set(false);
+			getContent().getPad().throwException(path, player.getError());
+		});
+		player.setOnEndOfMedia(() ->
+		{
+			if (!getContent().getPad().isLoop()) {
+				getContent().getPad().setEof(true);
+				getContent().getPad().setStatus(PadStatus.STOP);
+			} else {
+				// Loop
+				player.seek(Duration.ZERO);
+			}
+		});
+	}
+
+	@Override
+	public void unloadMedia() {
+		player = null;
+		media = null;
+		durationProperty.set(null);
+		loadedProperty.set(false);
+	}
+
+	@Override
+	public void updateVolume(double masterVolume) {
+		if (player != null)
+			player.setVolume(getContent().getPad().getVolume() * masterVolume);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/audio/JavaFXHandlerConnect.java b/PlayWall/src/de/tobias/playpad/audio/JavaFXHandlerConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a5e3fb8cfc71d87b064285e4d8057a43472639b
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/audio/JavaFXHandlerConnect.java
@@ -0,0 +1,17 @@
+package de.tobias.playpad.audio;
+
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.viewcontroller.AudioTypeViewController;
+
+public class JavaFXHandlerConnect extends AudioHandlerConnect {
+
+	@Override
+	public AudioHandler createAudioHandler(PadContent content) {
+		return new JavaFXAudioHandler(content);
+	}
+
+	@Override
+	public AudioTypeViewController getAudioViewController() {
+		return null;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..e375c5e2f14febcc47be7684330bea5ac67dfb83
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java
@@ -0,0 +1,333 @@
+package de.tobias.playpad.audio;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer.Info;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.content.AudioContent;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.utils.util.FileUtils;
+import javafx.application.Platform;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.util.Duration;
+import javazoom.jl.converter.Converter;
+import javazoom.jl.decoder.JavaLayerException;
+import kuusisto.tinysound.Music;
+import kuusisto.tinysound.TinySound;
+
+public class TinyAudioHandler extends AudioHandler {
+
+	public static final String SOUND_CARD = "SoundCard";
+
+	public static final String NAME = "Java Audiostream";
+	private static final String MP3 = "mp3";
+	private static final int SLEEP_TIME_POSITION = 50;
+
+	private static ExecutorService executorService;
+
+	private static Thread positionThread;
+	private static List<TinyAudioHandler> playedHandlers = new ArrayList<>();
+
+	static {
+		positionThread = new Thread(() ->
+		{
+			while (true) {
+				try {
+					if (playedHandlers.isEmpty()) {
+						synchronized (positionThread) {
+							positionThread.wait();
+						}
+					}
+
+					for (Iterator<TinyAudioHandler> iterator = playedHandlers.iterator(); iterator.hasNext();) {
+						TinyAudioHandler handler = iterator.next();
+						Pad pad = handler.getContent().getPad();
+
+						if (handler.music != null) {
+							if (!handler.music.playing()) {
+								if (!pad.isLoop()) {
+									pad.setEof(true);
+
+									// Remove from Loop and Stop
+									iterator.remove();
+									Platform.runLater(() -> pad.setStatus(PadStatus.STOP));
+								}
+							}
+						}
+
+						// Differenz seit Play bis jetzt
+						long diff = System.currentTimeMillis() - handler.start;
+
+						Duration position = Duration.millis(diff);
+
+						// Für Loop wieder am Anfang anfangen -> Wenn Aktuelle Position
+						if (handler.duration.isNotNull().get()) {
+							if (position.greaterThan(handler.duration.get())) {
+								position.subtract(handler.duration.get());
+								handler.start += handler.duration.get().toMillis();
+							}
+						}
+
+						// Update der Zeit
+						Platform.runLater(() -> handler.position.set(position));
+					}
+
+					Thread.sleep(SLEEP_TIME_POSITION);
+				} catch (InterruptedException e) {} catch (ConcurrentModificationException e) {} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		});
+
+		positionThread.start();
+
+		executorService = Executors.newFixedThreadPool(1);
+		Runtime.getRuntime().addShutdownHook(new Thread(() -> executorService.shutdown()));
+	}
+
+	private Music music;
+	private boolean pause; // Play fängt immer vorne an. Wenn diese Variable True ist dann wird Resume aufgerufen
+
+	private ObjectProperty<Duration> duration;
+	private ObjectProperty<Duration> position;
+	private long start;
+
+	private BooleanProperty loadedProperty;
+
+	public TinyAudioHandler(PadContent content) {
+		super(content);
+
+		duration = new SimpleObjectProperty<>();
+		position = new SimpleObjectProperty<>();
+		loadedProperty = new SimpleBooleanProperty();
+	}
+
+	@Override
+	public void play() {
+		if (music != null) {
+			if (!pause) {
+				if (!getContent().getPad().isLoop()) {
+					music.play(false); // Kein Loop
+				} else {
+					music.play(true); // Mit Loop
+				}
+				Platform.runLater(() -> position.set(Duration.ZERO));
+				start = System.currentTimeMillis();
+			} else {
+				music.resume();
+				start = (long) (System.currentTimeMillis() - position.get().toMillis());
+			}
+			pause = false;
+
+			boolean start = false;
+			if (playedHandlers.isEmpty()) {
+				start = true;
+			}
+
+			if (!playedHandlers.contains(this))
+				playedHandlers.add(this);
+			if (start) {
+				synchronized (positionThread) {
+					positionThread.notify();
+				}
+			}
+		}
+	}
+
+	@Override
+	public void pause() {
+		if (music != null) {
+			music.pause();
+			if (playedHandlers.contains(this))
+				playedHandlers.remove(this);
+			pause = true;
+		}
+	}
+
+	@Override
+	public void stop() {
+		if (music != null) {
+			music.stop();
+			if (playedHandlers.contains(this))
+				playedHandlers.remove(this);
+			pause = false;
+		}
+	}
+
+	@Override
+	public Duration getPosition() {
+		return position.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> positionProperty() {
+		return position;
+	}
+
+	@Override
+	public Duration getDuration() {
+		return duration.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> durationProperty() {
+		return duration;
+	}
+
+	@Override
+	public void setVolume(double volume, double masterVolume) {
+		if (music != null) {
+			music.setVolume(volume * masterVolume);
+		}
+	}
+
+	@Override
+	public boolean isMediaLoaded() {
+		return loadedProperty.get();
+	}
+
+	@Override
+	public void loadMedia() {
+		initTinySound();
+
+		unloadMedia();
+		Platform.runLater(() ->
+		{
+			if (getContent().getPad().isPadVisible()) {
+				getContent().getPad().getController().getParent().setBusy(true);
+			}
+		});
+
+		executorService.submit(() ->
+		{
+			Path path = ((AudioContent) getContent()).getPath();
+			try {
+				URL url = path.toUri().toURL();
+
+				// Convert wenn mp3
+				if (FileUtils.getFileExtention(url.getFile()).toLowerCase().endsWith(MP3)) {
+					Path wavPath = Profile.currentProfile().getProfileSettings().getCachePath().resolve(path.getFileName().toString() + ".wav");
+					url = convertMp3ToWav(path, wavPath, getContent().getPad());
+				}
+
+				// Load
+				music = TinySound.loadMusic(url, true);
+				calcDuration(url);
+
+				Platform.runLater(() ->
+				{
+					loadedProperty.set(true);
+					getContent().getPad().setStatus(PadStatus.READY);
+				});
+			} catch (Exception e) {
+				loadedProperty.set(false);
+				getContent().getPad().throwException(path, e);
+				e.printStackTrace();
+			} finally {
+				Platform.runLater(() ->
+				{
+					if (getContent().getPad().isPadVisible()) {
+						getContent().getPad().getController().getParent().setBusy(false);
+					}
+				});
+			}
+		});
+	}
+
+	private void calcDuration(URL url) throws UnsupportedAudioFileException, IOException {
+		AudioInputStream iStr = AudioSystem.getAudioInputStream(url);
+		double max = 1000.0 * (double) iStr.getFrameLength() / (double) iStr.getFormat().getFrameRate();
+		Duration duration = Duration.millis(max);
+		Platform.runLater(() -> this.duration.set(duration));
+		iStr.close();
+	}
+
+	private static URL convertMp3ToWav(Path orgPath, Path wavPath, Pad pad) throws JavaLayerException, URISyntaxException, IOException {
+		if (Files.notExists(wavPath)) {
+			Files.createDirectories(wavPath.getParent());
+			Files.createFile(wavPath);
+
+			Converter converter = new Converter();
+			converter.convert(orgPath.toString(), wavPath.toString());
+		}
+		return wavPath.toUri().toURL();
+	}
+
+	@Override
+	public void unloadMedia() {
+		if (music != null) {
+			music.unload();
+			music = null;
+		}
+		Platform.runLater(() -> duration.set(null));
+		loadedProperty.set(false);
+	}
+
+	@Override
+	public void updateVolume(double masterVolume) {
+		if (music != null) {
+			music.setVolume(getContent().getPad().getVolume() * masterVolume);
+		}
+	}
+
+	public void setMusic(Music music, URL url) throws UnsupportedAudioFileException, IOException {
+		this.music = music;
+		calcDuration(url);
+		loadedProperty.set(true);
+	}
+
+	private static String audioCardName;
+
+	private void initTinySound() {
+		String audioCardName = (String) Profile.currentProfile().getProfileSettings().getAudioUserInfo().get(SOUND_CARD);
+
+		if (TinyAudioHandler.audioCardName != null) {
+			if (!TinyAudioHandler.audioCardName.equals(audioCardName)) {
+				TinySound.shutdown();
+			}
+		}
+
+		if (!TinySound.isInitialized()) {
+			// INIT
+			try {
+				// Init mit spezieler Sound Card
+				for (Info info : AudioSystem.getMixerInfo()) {
+					if (info.getName().equals(audioCardName)) {
+						TinyAudioHandler.audioCardName = audioCardName;
+
+						TinySound.init(info);
+						break;
+					}
+				}
+
+			} catch (SecurityException | IllegalArgumentException | LineUnavailableException e) {
+				e.printStackTrace();
+			}
+			// Init mit Default Sound Card, wenn keine Ausgewählt wurde
+			if (!TinySound.isInitialized()) {
+				TinySound.init();
+			}
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c97f5f9288fd6981970433cdd61503952aac39d
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java
@@ -0,0 +1,19 @@
+package de.tobias.playpad.audio;
+
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.viewcontroller.AudioTypeViewController;
+import de.tobias.playpad.viewcontroller.audio.TinySoundSettingsViewController;
+
+public class TinyAudioHandlerConnect extends AudioHandlerConnect {
+
+	@Override
+	public AudioHandler createAudioHandler(PadContent content) {
+		return new TinyAudioHandler(content);
+	}
+
+	@Override
+	public AudioTypeViewController getAudioViewController() {
+		return new TinySoundSettingsViewController();
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java
new file mode 100644
index 0000000000000000000000000000000000000000..3dc08fb0240b1e8654b6de673f749e8d27b2db8e
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java
@@ -0,0 +1,238 @@
+package de.tobias.playpad.layout.classic;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.Layout;
+import de.tobias.playpad.pad.Warning;
+import de.tobias.playpad.pad.view.IPadViewController;
+import de.tobias.playpad.viewcontroller.IPadView;
+import de.tobias.utils.util.ColorXMLUtils;
+import javafx.application.Platform;
+import javafx.scene.paint.Color;
+
+public class ClassicCartLayout extends Layout implements CartLayout {
+
+	public static final String TYPE = "classic";
+
+	private Color backgroundColor = Color.TRANSPARENT;
+	private Color playbackColor = Color.web("#ffb48bbb");
+	private Color warnColor = Color.web("#ff8888bb");
+	private Color fadeColor = Color.web("#ffea86bb");
+	private Color accentColor = Color.BLACK;
+
+	private Color infoLabelColor = Color.BLACK;
+	private Color titleLabelColor = Color.BLACK;
+
+	public Color getBackgroundColor() {
+		return backgroundColor;
+	}
+
+	public void setBackgroundColor(Color backgroundColor) {
+		this.backgroundColor = backgroundColor;
+	}
+
+	public Color getPlaybackColor() {
+		return playbackColor;
+	}
+
+	public void setPlaybackColor(Color playbackColor) {
+		this.playbackColor = playbackColor;
+	}
+
+	public Color getWarnColor() {
+		return warnColor;
+	}
+
+	public void setWarnColor(Color warnColor) {
+		this.warnColor = warnColor;
+	}
+
+	public Color getFadeColor() {
+		return fadeColor;
+	}
+
+	public void setFadeColor(Color fadeColor) {
+		this.fadeColor = fadeColor;
+	}
+
+	public Color getInfoLabelColor() {
+		return infoLabelColor;
+	}
+
+	public void setInfoLabelColor(Color idLabelColor) {
+		this.infoLabelColor = idLabelColor;
+	}
+
+	public Color getTitleLabelColor() {
+		return titleLabelColor;
+	}
+
+	public void setTitleLabelColor(Color titleLabelColor) {
+		this.titleLabelColor = titleLabelColor;
+	}
+
+	public Color getAccentColor() {
+		return accentColor;
+	}
+
+	public void setAccentColor(Color accentColor) {
+		this.accentColor = accentColor;
+	}
+
+	public void reset() {
+		backgroundColor = Color.TRANSPARENT;
+		playbackColor = Color.web("#ffb48bbb");
+		warnColor = Color.web("#ff8888bb");
+		fadeColor = Color.web("#ffea86bb");
+
+		accentColor = Color.BLACK;
+		infoLabelColor = Color.BLACK;
+		titleLabelColor = Color.BLACK;
+	}
+
+	public void load(Element rootElement) {
+		setBackgroundColor(ColorXMLUtils.load(rootElement.element("BackgroundColor")));
+		setPlaybackColor(ColorXMLUtils.load(rootElement.element("PlaybackColor")));
+		setWarnColor(ColorXMLUtils.load(rootElement.element("WarnColor")));
+		setFadeColor(ColorXMLUtils.load(rootElement.element("FadeColor")));
+		setAccentColor(ColorXMLUtils.load(rootElement.element("AccentColor")));
+
+		Element indexLabelEmement = rootElement.element("InfoLabel");
+		if (indexLabelEmement != null) {
+			setInfoLabelColor(ColorXMLUtils.load(indexLabelEmement.element("Color")));
+		}
+
+		Element titleLabelElement = rootElement.element("TitleLabel");
+		if (titleLabelElement != null) {
+			setTitleLabelColor(ColorXMLUtils.load(titleLabelElement.element("Color")));
+		}
+	}
+
+	public void save(Element element) {
+		ColorXMLUtils.save(element.addElement("BackgroundColor"), backgroundColor);
+		ColorXMLUtils.save(element.addElement("PlaybackColor"), playbackColor);
+		ColorXMLUtils.save(element.addElement("WarnColor"), warnColor);
+		ColorXMLUtils.save(element.addElement("FadeColor"), fadeColor);
+		ColorXMLUtils.save(element.addElement("AccentColor"), accentColor);
+
+		Element indexLabelElement = element.addElement("InfoLabel");
+		ColorXMLUtils.save(indexLabelElement.addElement("Color"), infoLabelColor);
+
+		Element titleLabelElement = element.addElement("TitleLabel");
+		ColorXMLUtils.save(titleLabelElement.addElement("Color"), titleLabelColor);
+	}
+
+	public void save(Path path) throws UnsupportedEncodingException, IOException {
+		Document document = DocumentHelper.createDocument();
+		Element rootElement = document.addElement("layout");
+		save(rootElement);
+
+		XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint());
+		writer.write(document);
+		writer.close();
+	}
+
+	@Override
+	public CartLayout clone() throws CloneNotSupportedException {
+		ClassicCartLayout layout = (ClassicCartLayout) super.clone();
+
+		layout.backgroundColor = Color.color(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(),
+				backgroundColor.getOpacity());
+		layout.playbackColor = Color.color(playbackColor.getRed(), playbackColor.getGreen(), playbackColor.getBlue(),
+				playbackColor.getOpacity());
+		layout.warnColor = Color.color(warnColor.getRed(), warnColor.getGreen(), warnColor.getBlue(), warnColor.getOpacity());
+		layout.fadeColor = Color.color(fadeColor.getRed(), fadeColor.getGreen(), fadeColor.getBlue(), fadeColor.getOpacity());
+		layout.infoLabelColor = Color.color(infoLabelColor.getRed(), infoLabelColor.getGreen(), infoLabelColor.getBlue(),
+				infoLabelColor.getOpacity());
+		layout.titleLabelColor = Color.color(titleLabelColor.getRed(), titleLabelColor.getGreen(), titleLabelColor.getBlue(),
+				titleLabelColor.getOpacity());
+
+		return layout;
+	}
+
+	public String convertToCss(String classSufix, boolean fullCss) {
+		StringBuilder builder = new StringBuilder();
+
+		if (classSufix.isEmpty()) {
+			builder.append(".fonticon {\n");
+			builder.append("\t-fx-text-fill: " + accentColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".progress-bar {\n");
+			builder.append("\t-fx-accent: " + accentColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".slider .thumb {\n");
+			builder.append("-fx-base: " + accentColor + ";\n");
+			builder.append("}\n");
+		}
+
+		if (fullCss) {
+			builder.append(".pad" + classSufix + " {\n");
+			builder.append("\t-fx-background-color: " + backgroundColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + ":" + PseudoClasses.PLAY_CALSS.getPseudoClassName() + " {\n");
+			builder.append("\t-fx-background-color: " + playbackColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + ":" + PseudoClasses.WARN_CLASS.getPseudoClassName() + " {\n");
+			builder.append("\t-fx-background-color: " + warnColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + ":" + PseudoClasses.FADE_CLASS.getPseudoClassName() + " {\n");
+			builder.append("\t-fx-background-color: " + fadeColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + "-info {\n");
+			builder.append("\t-fx-text-fill: " + infoLabelColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + "-title {\n");
+			builder.append("\t-fx-text-fill: " + titleLabelColor + ";\n");
+			builder.append("}\n");
+
+		}
+
+		return builder.toString().replace("0x", "#");
+	}
+
+	@Override
+	public void handleWarning(IPadViewController controller, Warning warning) {
+		final IPadView view = controller.getParent();
+
+		try {
+			while (true) {
+				Platform.runLater(() ->
+				{
+					view.pseudoClassState(PseudoClasses.WARN_CLASS, true);
+					view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+				});
+				Thread.sleep(500);
+				Platform.runLater(() ->
+				{
+					view.pseudoClassState(PseudoClasses.PLAY_CALSS, true);
+					view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+				});
+				Thread.sleep(500);
+			}
+		} catch (InterruptedException e) {
+			Platform.runLater(() ->
+			{
+				view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+				view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			});
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/classic/ClassicGlobalLayout.java b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicGlobalLayout.java
new file mode 100644
index 0000000000000000000000000000000000000000..8618a813cab625a4dca5d5aa260e161fa59be595
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicGlobalLayout.java
@@ -0,0 +1,374 @@
+package de.tobias.playpad.layout.classic;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.GlobalLayout;
+import de.tobias.playpad.layout.Layout;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.Warning;
+import de.tobias.playpad.pad.view.IPadViewController;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.viewcontroller.IPadView;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.util.ColorXMLUtils;
+import javafx.application.Platform;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+
+public class ClassicGlobalLayout extends Layout implements GlobalLayout {
+
+	public static final double minWidth = 180;
+	public static final double minHeight = 100;
+
+	public static final String TYPE = "classic";
+
+	private ObjectProperty<Theme> themeProperty = new SimpleObjectProperty<>(Theme.LIGHT);
+	private boolean customLayout = false;
+
+	private Color backgroundColor = Color.TRANSPARENT;
+	private Color playbackColor = Color.web("#ffb48bbb");
+	private Color warnColor = Color.web("#ff8888bb");
+	private Color fadeColor = Color.web("#ffea86bb");
+
+	private Color accentColor = Color.BLACK;
+
+	private int infoLabelFontSize = 13;
+	private Color infoLabelColor = Color.BLACK;
+
+	private int titleLabelFontSize = 13;
+	private Color titleLabelColor = Color.BLACK;
+
+	public Color getBackgroundColor() {
+		return backgroundColor;
+	}
+
+	public void setBackgroundColor(Color backgroundColor) {
+		this.backgroundColor = backgroundColor;
+	}
+
+	public Color getPlaybackColor() {
+		return playbackColor;
+	}
+
+	public void setPlaybackColor(Color playbackColor) {
+		this.playbackColor = playbackColor;
+	}
+
+	public Color getWarnColor() {
+		return warnColor;
+	}
+
+	public void setWarnColor(Color warnColor) {
+		this.warnColor = warnColor;
+	}
+
+	public Color getFadeColor() {
+		return fadeColor;
+	}
+
+	public void setFadeColor(Color fadeColor) {
+		this.fadeColor = fadeColor;
+	}
+
+	public Color getInfoLabelColor() {
+		return infoLabelColor;
+	}
+
+	public void setInfoLabelColor(Color idLabelColor) {
+		this.infoLabelColor = idLabelColor;
+	}
+
+	public int getInfoLabelFontSize() {
+		return infoLabelFontSize;
+	}
+
+	public void setInfoLabelFontSize(int idLabelFontSize) {
+		this.infoLabelFontSize = idLabelFontSize;
+	}
+
+	public int getTitleLabelFontSize() {
+		return titleLabelFontSize;
+	}
+
+	public void setTitleLabelFontSize(int titleLabelFontSize) {
+		this.titleLabelFontSize = titleLabelFontSize;
+	}
+
+	public Color getTitleLabelColor() {
+		return titleLabelColor;
+	}
+
+	public void setTitleLabelColor(Color titleLabelColor) {
+		this.titleLabelColor = titleLabelColor;
+	}
+
+	public Color getAccentColor() {
+		return accentColor;
+	}
+
+	public void setAccentColor(Color accentColor) {
+		this.accentColor = accentColor;
+	}
+
+	public Theme getTheme() {
+		return themeProperty.get();
+	}
+
+	public void setTheme(Theme theme) {
+		themeProperty.set(theme);
+	}
+
+	public ObjectProperty<Theme> themeProperty() {
+		return themeProperty;
+	}
+
+	public boolean isCustomLayout() {
+		return customLayout;
+	}
+
+	public void setCustomLayout(boolean customLayout) {
+		this.customLayout = customLayout;
+	}
+
+	@Override
+	public double getMinHeight(int rows) {
+		return rows * minHeight;
+	}
+
+	@Override
+	public double getMinWidth(int columns) {
+		return columns * minWidth;
+	}
+
+	@Override
+	public double getPadHeight() {
+		return minHeight;
+	}
+
+	@Override
+	public double getPadWidth() {
+		return minWidth;
+	}
+
+	public void reset() {
+		themeProperty = new SimpleObjectProperty<>(Theme.LIGHT);
+		customLayout = false;
+
+		backgroundColor = Color.TRANSPARENT;
+		playbackColor = Color.web("#ffb48bbb");
+		warnColor = Color.web("#ff8888bb");
+		fadeColor = Color.web("#ffea86bb");
+
+		accentColor = Color.BLACK;
+
+		infoLabelFontSize = 13;
+		infoLabelColor = Color.BLACK;
+
+		titleLabelFontSize = 13;
+		titleLabelColor = Color.BLACK;
+	}
+
+	@Override
+	public void load(Element rootElement) {
+		if (rootElement.element("Theme") != null)
+			try {
+				setTheme(Theme.valueOf(rootElement.element("Theme").getStringValue()));
+			} catch (IllegalArgumentException e) {
+				setTheme(Theme.LIGHT);
+			}
+
+		if (rootElement.element("CustomLayout") != null)
+			setCustomLayout(Boolean.valueOf(rootElement.element("CustomLayout").getStringValue()));
+
+		setBackgroundColor(ColorXMLUtils.load(rootElement.element("BackgroundColor")));
+		setPlaybackColor(ColorXMLUtils.load(rootElement.element("PlaybackColor")));
+		setWarnColor(ColorXMLUtils.load(rootElement.element("WarnColor")));
+		setFadeColor(ColorXMLUtils.load(rootElement.element("FadeColor")));
+		setAccentColor(ColorXMLUtils.load(rootElement.element("AccentColor")));
+
+		Element indexLabelEmement = rootElement.element("InfoLabel");
+		if (indexLabelEmement != null) {
+			setInfoLabelColor(ColorXMLUtils.load(indexLabelEmement.element("Color")));
+			setInfoLabelFontSize(Integer.valueOf(indexLabelEmement.element("FontSize").getStringValue()));
+		}
+
+		Element titleLabelElement = rootElement.element("TitleLabel");
+		if (titleLabelElement != null) {
+			setTitleLabelColor(ColorXMLUtils.load(titleLabelElement.element("Color")));
+			setTitleLabelFontSize(Integer.valueOf(titleLabelElement.element("FontSize").getStringValue()));
+		}
+	}
+
+	@Override
+	public void save(Element element) {
+		element.addElement("Theme").addText(themeProperty.get().name());
+		element.addElement("CustomLayout").addText(String.valueOf(customLayout));
+
+		ColorXMLUtils.save(element.addElement("BackgroundColor"), backgroundColor);
+		ColorXMLUtils.save(element.addElement("PlaybackColor"), playbackColor);
+		ColorXMLUtils.save(element.addElement("WarnColor"), warnColor);
+		ColorXMLUtils.save(element.addElement("FadeColor"), fadeColor);
+		ColorXMLUtils.save(element.addElement("AccentColor"), accentColor);
+
+		Element indexLabelElement = element.addElement("InfoLabel");
+		ColorXMLUtils.save(indexLabelElement.addElement("Color"), infoLabelColor);
+		indexLabelElement.addElement("FontSize").addText(String.valueOf(infoLabelFontSize));
+
+		Element titleLabelElement = element.addElement("TitleLabel");
+		ColorXMLUtils.save(titleLabelElement.addElement("Color"), titleLabelColor);
+		titleLabelElement.addElement("FontSize").addText(String.valueOf(titleLabelFontSize));
+	}
+
+	@Override
+	public GlobalLayout clone() throws CloneNotSupportedException {
+		ClassicGlobalLayout layout = (ClassicGlobalLayout) super.clone();
+
+		layout.backgroundColor = Color.color(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(),
+				backgroundColor.getOpacity());
+		layout.playbackColor = Color.color(playbackColor.getRed(), playbackColor.getGreen(), playbackColor.getBlue(),
+				playbackColor.getOpacity());
+		layout.warnColor = Color.color(warnColor.getRed(), warnColor.getGreen(), warnColor.getBlue(), warnColor.getOpacity());
+		layout.fadeColor = Color.color(fadeColor.getRed(), fadeColor.getGreen(), fadeColor.getBlue(), fadeColor.getOpacity());
+		layout.infoLabelColor = Color.color(infoLabelColor.getRed(), infoLabelColor.getGreen(), infoLabelColor.getBlue(),
+				infoLabelColor.getOpacity());
+		layout.titleLabelColor = Color.color(titleLabelColor.getRed(), titleLabelColor.getGreen(), titleLabelColor.getBlue(),
+				titleLabelColor.getOpacity());
+		layout.infoLabelFontSize = infoLabelFontSize;
+		layout.titleLabelFontSize = titleLabelFontSize;
+
+		return layout;
+	}
+
+	public String convertToCSS(String classSufix, boolean fullCss) {
+		StringBuilder builder = new StringBuilder();
+
+		if (classSufix.isEmpty()) {
+			builder.append(".fonticon {\n");
+			builder.append("\t-fx-text-fill: " + accentColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".progress-bar {\n");
+			builder.append("\t-fx-accent: " + accentColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".slider .thumb {\n");
+			builder.append("\t-fx-base: " + accentColor + ";\n");
+			builder.append("}\n");
+		}
+
+		if (fullCss) {
+			builder.append(".pad" + classSufix + " {\n");
+			builder.append("\t-fx-background-color: " + backgroundColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + ":play {\n");
+			builder.append("\t-fx-background-color: " + playbackColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + ":warn {\n");
+			builder.append("\t-fx-background-color: " + warnColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + ":fade {\n");
+			builder.append("\t-fx-background-color: " + fadeColor + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + "-info {\n");
+			builder.append("\t-fx-text-fill: " + infoLabelColor + ";\n");
+			builder.append("\t-fx-font-size: " + infoLabelFontSize + ";\n");
+			builder.append("}\n");
+
+			builder.append(".pad" + classSufix + "-title {\n");
+			builder.append("\t-fx-text-fill: " + titleLabelColor + ";\n");
+			builder.append("\t-fx-font-size: " + titleLabelFontSize + ";\n");
+			builder.append("}\n");
+		}
+
+		return builder.toString().replace("0x", "#");
+	}
+
+	@Override
+	public void applyCss(Stage stage) {
+		// Clear Old
+		stage.getScene().getStylesheets().clear();
+
+		// Add Build in Default
+		stage.getScene().getStylesheets().add("de/tobias/playpad/assets/style.css");
+		stage.getScene().getStylesheets().add("de/tobias/playpad/assets/classic_style.css");
+		stage.getScene().getStylesheets().add(themeProperty.get().getCss());
+
+		// User Settings
+		Path userCss = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "style.css");
+		if (Files.exists(userCss))
+			stage.getScene().getStylesheets().add(userCss.toUri().toString());
+	}
+
+	@Override
+	public void applyCssMainView(IMainViewController controller, Stage stage, Project project) {
+		applyCss(stage);
+
+		// Hard Settings
+		controller.setGridColor(accentColor);
+
+		Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "custom_style.css");
+
+		// Globale CSS -> Immer Akzent, und wenn isCustomLayout dann alles
+		String css = convertToCSS("", isCustomLayout());
+
+		// Pad Spezelles Layout immer
+		for (Pad pad : project.getPads().values()) {
+			if (pad.isCustomLayout()) {
+				CartLayout layoutOpt = pad.getLayout();
+				css += "\n" + layoutOpt.convertToCss(String.valueOf(pad.getIndex()), true);
+			}
+		}
+
+		// Speichern der generierten CSS Datei
+		try {
+			Files.write(path, css.getBytes());
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		stage.getScene().getStylesheets().remove(path.toUri().toString());
+		stage.getScene().getStylesheets().add(path.toUri().toString());
+	}
+
+	@Override
+	public void handleWarning(IPadViewController controller, Warning warning) {
+		final IPadView view = controller.getParent();
+
+		try {
+			while (true) {
+				Platform.runLater(() ->
+				{
+					view.pseudoClassState(PseudoClasses.WARN_CLASS, true);
+					view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+				});
+				Thread.sleep(500);
+				Platform.runLater(() ->
+				{
+					view.pseudoClassState(PseudoClasses.PLAY_CALSS, true);
+					view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+				});
+				Thread.sleep(500);
+			}
+		} catch (InterruptedException e) {
+			Platform.runLater(() ->
+			{
+				view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+				view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			});
+		}
+	}
+}
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/layout/classic/ClassicLayoutConnect.java b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicLayoutConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..bab85710670ae3f9ddc79b6bd7392721f15c0b1b
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicLayoutConnect.java
@@ -0,0 +1,49 @@
+package de.tobias.playpad.layout.classic;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.GlobalLayout;
+import de.tobias.playpad.layout.LayoutConnect;
+import de.tobias.playpad.viewcontroller.CartLayoutViewController;
+import de.tobias.playpad.viewcontroller.GlobalLayoutViewController;
+import de.tobias.playpad.viewcontroller.layout.ClassicLayoutCartViewController;
+import de.tobias.playpad.viewcontroller.layout.ClassicLayoutGlobalViewController;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class ClassicLayoutConnect extends LayoutConnect {
+
+	private static final String TYPE = "classic";
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty(Localization.getString(Strings.Layout_Classic_Name));
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public CartLayout newCartLayout() {
+		return new ClassicCartLayout();
+	}
+
+	@Override
+	public GlobalLayout newGlobalLayout() {
+		return new ClassicGlobalLayout();
+	}
+
+	@Override
+	public CartLayoutViewController getCartLayoutViewController(CartLayout cartLayout) {
+		return new ClassicLayoutCartViewController(cartLayout);
+	}
+
+	@Override
+	public GlobalLayoutViewController getGlobalLayoutViewController(GlobalLayout globalLayout) {
+		return new ClassicLayoutGlobalViewController(globalLayout);
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/classic/Theme.java b/PlayWall/src/de/tobias/playpad/layout/classic/Theme.java
new file mode 100644
index 0000000000000000000000000000000000000000..4405ffb716d1456eb44b7eab7970664a05864c49
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/classic/Theme.java
@@ -0,0 +1,37 @@
+package de.tobias.playpad.layout.classic;
+
+import javafx.scene.paint.Color;
+
+public enum Theme {
+
+	DARK("Dark.css", Color.RED, Color.rgb(40, 40, 40)),
+	TWILIGHT("Twilight.css", Color.rgb(200, 200, 255), Color.rgb(40, 40, 50)),
+	LIGHT("Light.css", Color.BLACK, Color.TRANSPARENT);
+
+	private String name;
+	private Color color;
+	private Color backgrond;
+
+	private Theme(String name, Color color, Color background) {
+		this.name = name;
+		this.color = color;
+		this.backgrond = background;
+	}
+
+	public Color getGridColor() {
+		return color;
+	}
+
+	public Color getBackground() {
+		return backgrond;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getCss() {
+		return "de/tobias/playpad/assets/style/" + name;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/modern/ModernColor.java b/PlayWall/src/de/tobias/playpad/layout/modern/ModernColor.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e94e20e47a289072a6e8c0856f6370d35a798ea
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/modern/ModernColor.java
@@ -0,0 +1,113 @@
+package de.tobias.playpad.layout.modern;
+
+import de.tobias.playpad.DisplayableColor;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.CycleMethod;
+import javafx.scene.paint.LinearGradient;
+import javafx.scene.paint.Paint;
+import javafx.scene.paint.Stop;
+
+public enum ModernColor implements DisplayableColor {
+
+	// - Color Hi -- Color Low -- Font ---- Button -- Bar BG -- Bar Track
+	RED1("#ef9a9a", "#ef5350", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+	RED2("#ef5350", "#e53935", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+	RED3("#e53935", "#c62828", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+
+	// --------- BG ------ PLAY ----- Font ---- Button -- Bar BG -- Bar Track
+	DARK_RED1("#D92349", "#AD2039", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+	DARK_RED2("#C92349", "#8D2039", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+	DARK_RED3("#A90329", "#6D0019", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+
+	// ---- BG ------ PLAY ----- Font ---- Button -- Bar BG -- Bar Track
+	PINK1("#f48fb1", "#ec407a", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+	PINK2("#ec407a", "#d81b60", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+	PINK3("#d81b60", "#ad1457", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+
+	// -------- BG ------ PLAY ----- Font ---- Button -- Bar BG -- Bar Track
+	PURPLE1("#ce93d8", "#ab47bc", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+	PURPLE2("#ab47bc", "#8e24aa", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+	PURPLE3("#8e24aa", "#6a1b9a", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#000000"),
+
+	// ---- BG ------ PLAY ----- Font ---- Button -- Bar BG -- Bar Track
+	LIGHT_BLUE1("#80deea", "#26c6da", "#000000", "#000000", "#FFFFFF", "#000000"),
+	LIGHT_BLUE2("#26c6da", "#00acc1", "#000000", "#000000", "#FFFFFF", "#000000"),
+	LIGHT_BLUE3("#00acc1", "#00838f", "#000000", "#000000", "#FFFFFF", "#000000"),
+
+	// ---- BG ------ PLAY ----- Font ---- Button -- Bar BG -- Bar Track
+	BLUE1("#90caf9", "#42a5f5", "#000000", "#000000", "#FFFFFF", "#000000"),
+	BLUE2("#42a5f5", "#1e88e5", "#000000", "#000000", "#FFFFFF", "#000000"),
+	BLUE3("#1e88e5", "#1565c0", "#000000", "#000000", "#FFFFFF", "#000000"),
+
+	// ------------ BG ------ PLAY ----- Font ---- Button --- Bar BG -- Bar Track
+	LIGHT_GREEN1("#c5e1a5", "#9ccc65", "#000000", "#000000", "#FFFFFF", "#000000"),
+	LIGHT_GREEN2("#9ccc65", "#7cb342", "#000000", "#000000", "#FFFFFF", "#000000"),
+	LIGHT_GREEN3("#7cb342", "#558b2f", "#000000", "#000000", "#FFFFFF", "#000000"),
+
+	// ------- BG ------ PLAY ------ Font ---- Button -- Bar BG -- Bar Track
+	YELLOW1("#fff59d", "#ffee58", "#000000", "#000000", "#FFFFFF", "#000000"),
+	YELLOW2("#ffee58", "#fdd835", "#000000", "#000000", "#FFFFFF", "#000000"),
+	YELLOW3("#fdd835", "#f9a825", "#000000", "#000000", "#FFFFFF", "#000000"),
+
+	// ------- BG ------ PLAY ----- Font ---- Button -- Bar BG -- Bar Track
+	ORANGE1("#ffcc80", "#ffa726", "#000000", "#000000", "#FFFFFF", "#000000"),
+	ORANGE2("#ffa726", "#fb8c00", "#000000", "#000000", "#FFFFFF", "#000000"),
+	ORANGE3("#fb8c00", "#ef6c00", "#000000", "#000000", "#FFFFFF", "#000000"),
+
+	// ---- BG ------ PLAY ----- Font ---- Button --- Bar BG --- Bar Track
+	GRAY1("#eeeeee", "#cccccc", "#000000", "#000000", "#000000", "#FFFFFF"),
+	GRAY2("#cccccc", "#aaaaaa", "#000000", "#000000", "#000000", "#FFFFFF"),
+	GRAY3("#555555", "#333333", "#FFFFFF", "#FFFFFF", "#000000", "#FFFFFF");
+
+	private final String colorHi;
+	private final String colorLow;
+	private final String fontColor;
+	private final String buttonColor;
+	private final String playbarColor;
+	private final String playbarTrackColor;
+
+	private ModernColor(String colorHi, String colorLow, String fontColor, String buttonColor, String playbarColor, String playbarTrackColor) {
+		this.colorHi = colorHi;
+		this.colorLow = colorLow;
+		this.fontColor = fontColor;
+		this.buttonColor = buttonColor;
+		this.playbarColor = playbarColor;
+		this.playbarTrackColor = playbarTrackColor;
+	}
+
+	public String getColorHi() {
+		return colorHi;
+	}
+
+	public String getColorLow() {
+		return colorLow;
+	}
+
+	public String getFontColor() {
+		return fontColor;
+	}
+
+	public String getButtonColor() {
+		return buttonColor;
+	}
+
+	public String getPlaybarColor() {
+		return playbarColor;
+	}
+
+	public String getPlaybarTrackColor() {
+		return playbarTrackColor;
+	}
+
+	@Override
+	public Paint getPaint() {
+		LinearGradient gradient = new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE, new Stop(0, Color.web(colorHi)),
+				new Stop(1, Color.web(colorLow)));
+		return gradient;
+	}
+
+	public String linearGradient() {
+		return "linear-gradient(" + getColorHi() + "," + getColorLow() + ")";
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutAnimator.java b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutAnimator.java
new file mode 100644
index 0000000000000000000000000000000000000000..e8fd950c69c7eedee044131e901a02c2266cef73
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutAnimator.java
@@ -0,0 +1,131 @@
+package de.tobias.playpad.layout.modern;
+
+import java.util.HashMap;
+
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.layout.FadeableColor;
+import de.tobias.playpad.pad.view.IPadViewController;
+import de.tobias.playpad.viewcontroller.IPadView;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
+import javafx.application.Platform;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.util.Duration;
+
+public class ModernLayoutAnimator {
+
+	// alles nur static, neine objecte von der Klasse
+	private ModernLayoutAnimator() {}
+
+	private static HashMap<Integer, Timeline> timelines = new HashMap<>();
+
+	public static void animateFade(IPadViewController padViewController, FadeableColor startColor, FadeableColor endColor, Duration duration) {
+		int index = padViewController.getPad().getIndex();
+
+		if (timelines.containsKey(index)) {
+			timelines.get(index).stop();
+		}
+
+		ChangeListener<FadeableColor> fadeListener = new ChangeListener<FadeableColor>() {
+
+			@Override
+			public void changed(ObservableValue<? extends FadeableColor> observable, FadeableColor oldValue, FadeableColor newValue) {
+				padViewController.getParent().setStyle("-fx-background-color: " + newValue.toString() + ";");
+			}
+		};
+
+		ObjectProperty<FadeableColor> backgroundColor = new SimpleObjectProperty<>();
+		backgroundColor.addListener(fadeListener);
+
+		Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(0), new KeyValue(backgroundColor, startColor)),
+				new KeyFrame(duration, new KeyValue(backgroundColor, endColor)));
+
+		timeline.playFromStart();
+		timeline.setOnFinished(event ->
+		{
+			backgroundColor.removeListener(fadeListener);
+			padViewController.getParent().setStyle("");
+			timelines.remove(index);
+		});
+
+		// Memory
+		timelines.put(index, timeline);
+
+	}
+
+	public static void animateWarn(IPadViewController padViewController, FadeableColor startColor, FadeableColor endColor, Duration duration) {
+		int index = padViewController.getPad().getIndex();
+
+		if (timelines.containsKey(index)) {
+			timelines.get(index).stop();
+		}
+
+		ChangeListener<FadeableColor> fadeListener = new ChangeListener<FadeableColor>() {
+
+			@Override
+			public void changed(ObservableValue<? extends FadeableColor> observable, FadeableColor oldValue, FadeableColor newValue) {
+				padViewController.getParent().setStyle("-fx-background-color: " + newValue.toString() + ";");
+			}
+		};
+
+		ObjectProperty<FadeableColor> backgroundColor = new SimpleObjectProperty<>();
+		backgroundColor.addListener(fadeListener);
+
+		Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(0), new KeyValue(backgroundColor, startColor)),
+				new KeyFrame(Duration.seconds(0.125), new KeyValue(backgroundColor, startColor)),
+				new KeyFrame(Duration.seconds(0.5), new KeyValue(backgroundColor, endColor)),
+				new KeyFrame(Duration.seconds(0.625), new KeyValue(backgroundColor, endColor)));
+
+		timeline.setAutoReverse(true);
+		timeline.setCycleCount((int) (duration.toSeconds() / 0.625));
+		timeline.playFromStart();
+
+		timeline.setOnFinished(event ->
+		{
+			backgroundColor.removeListener(fadeListener);
+			padViewController.getParent().setStyle("");
+			timelines.remove(index);
+		});
+
+		// Memory
+		timelines.put(index, timeline);
+	}
+
+	public static void stopAnimation(IPadViewController controller) {
+		int index = controller.getPad().getIndex();
+
+		if (timelines.containsKey(index)) {
+			timelines.get(index).stop();
+		}
+	}
+
+	public static void warnFlash(IPadViewController controller) {
+		final IPadView view = controller.getParent();
+		try {
+			while (true) {
+				Platform.runLater(() ->
+				{
+					view.pseudoClassState(PseudoClasses.WARN_CLASS, true);
+					view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+				});
+				Thread.sleep(500);
+				Platform.runLater(() ->
+				{
+					view.pseudoClassState(PseudoClasses.PLAY_CALSS, true);
+					view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+				});
+				Thread.sleep(500);
+			}
+		} catch (InterruptedException e) {
+			Platform.runLater(() ->
+			{
+				view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+				view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			});
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba428cd1ed0aa3fee3b07a80e85156cd552c1fda
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java
@@ -0,0 +1,199 @@
+package de.tobias.playpad.layout.modern;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.FadeableColor;
+import de.tobias.playpad.layout.Layout;
+import de.tobias.playpad.layout.LayoutColorAssociator;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.Warning;
+import de.tobias.playpad.pad.conntent.Durationable;
+import de.tobias.playpad.pad.view.IPadViewController;
+import javafx.scene.paint.Color;
+import javafx.util.Duration;
+
+public class ModernLayoutCart extends Layout implements CartLayout, LayoutColorAssociator {
+
+	public static final String TYPE = "modern";
+
+	public static final double minWidth = 205;
+	public static final double minHeight = 110;
+
+	private ModernColor backgroundColor = ModernColor.GRAY1;
+	private ModernColor playColor = ModernColor.RED1;
+
+	private boolean isWarnAnimation = true;
+
+	public ModernColor getBackgroundColor() {
+		return backgroundColor;
+	}
+
+	public void setBackgroundColor(ModernColor backgroundColor) {
+		this.backgroundColor = backgroundColor;
+	}
+
+	public ModernColor getPlayColor() {
+		return playColor;
+	}
+
+	public void setPlayColor(ModernColor playColor) {
+		this.playColor = playColor;
+	}
+
+	public boolean isWarnAnimation() {
+		return isWarnAnimation;
+	}
+
+	public void setWarnAnimation(boolean isWarnAnimation) {
+		this.isWarnAnimation = isWarnAnimation;
+	}
+
+	public void reset() {
+		backgroundColor = ModernColor.GRAY1;
+		playColor = ModernColor.RED1;
+
+		isWarnAnimation = true;
+	}
+
+	@Override
+	public void load(Element rootElement) {
+		Element backgroundElement = rootElement.element("BackgroundColor");
+		if (backgroundElement != null) {
+			try {
+				backgroundColor = ModernColor.valueOf(backgroundElement.getStringValue());
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			}
+		}
+
+		Element playElement = rootElement.element("PlayColor");
+		if (playElement != null) {
+			try {
+				playColor = ModernColor.valueOf(playElement.getStringValue());
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			}
+		}
+
+		Element animationElement = rootElement.element("Animation");
+		if (animationElement != null) {
+			Element warnAnimationElement = animationElement.element("Warn");
+			if (warnAnimationElement != null) {
+				isWarnAnimation = Boolean.valueOf(warnAnimationElement.getStringValue());
+			}
+		}
+	}
+
+	@Override
+	public void save(Element rootElement) {
+		rootElement.addElement("BackgroundColor").addText(backgroundColor.name());
+		rootElement.addElement("PlayColor").addText(playColor.name());
+		Element animationElement = rootElement.addElement("Animation");
+		animationElement.addElement("Warn").addText(String.valueOf(isWarnAnimation));
+	}
+
+	// Warn Handler -> Animation oder Blinken
+	@Override
+	public void handleWarning(IPadViewController controller, Warning warning) {
+		if (isWarnAnimation) {
+			warnAnimation(controller, warning);
+		} else {
+			ModernLayoutAnimator.warnFlash(controller);
+		}
+	}
+
+	@Override
+	public void stopWarning(IPadViewController controller) {
+		ModernLayoutAnimator.stopAnimation(controller);
+	}
+
+	private void warnAnimation(IPadViewController controller, Warning warning) {
+		FadeableColor stopColor = new FadeableColor(this.backgroundColor.getColorHi(), this.backgroundColor.getColorLow());
+		FadeableColor playColor = new FadeableColor(this.playColor.getColorHi(), this.playColor.getColorLow());
+
+		Duration warnDuration = warning.getTime();
+		Pad pad = controller.getPad();
+
+		if (pad.getContent() instanceof Durationable) {
+			if (warnDuration.greaterThan(((Durationable) pad.getContent()).getDuration())) {
+				warnDuration = ((Durationable) pad.getContent()).getDuration();
+			}
+		}
+
+		ModernLayoutAnimator.animateWarn(controller, playColor, stopColor, warnDuration);
+	}
+
+	// Cart Layout
+	@Override
+	public String convertToCss(String prefix, boolean full) {
+		StringBuilder builder = new StringBuilder();
+
+		startStyleClass(builder, "pad" + prefix + "-icon");
+		addStyleParameter(builder, "-fx-text-fill", backgroundColor.getButtonColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix + "-playbar .track");
+		addStyleParameter(builder, "-fx-base", backgroundColor.getPlaybarColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix + "-playbar .bar");
+		addStyleParameter(builder, "-fx-background-color", backgroundColor.getPlaybarTrackColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix);
+		addStyleParameter(builder, "-fx-background-color", backgroundColor.linearGradient());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix + "-info");
+		addStyleParameter(builder, "-fx-text-fill", backgroundColor.getFontColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix + "-title");
+		addStyleParameter(builder, "-fx-text-fill", backgroundColor.getFontColor());
+		endStyleClass(builder);
+
+		buildCss(builder, PseudoClasses.PLAY_CALSS.getPseudoClassName(), prefix, playColor);
+		buildCss(builder, PseudoClasses.WARN_CLASS.getPseudoClassName(), prefix, backgroundColor);
+
+		return builder.toString().replace("0x", "#");
+	}
+
+	private void buildCss(StringBuilder builder, String state, String prefix, ModernColor color) {
+		startStyleClass(builder, "pad" + prefix + "-info:" + state);
+		addStyleParameter(builder, "-fx-text-fill", color.getFontColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix + "-title:" + state);
+		addStyleParameter(builder, "-fx-text-fill", color.getFontColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix + ":" + state);
+		addStyleParameter(builder, "-fx-background-color", color.linearGradient());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix + "-playbar:" + state + " .track");
+		addStyleParameter(builder, "-fx-base", color.getPlaybarColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix + "-playbar:" + state + " .bar");
+		addStyleParameter(builder, "-fx-background-color", color.getPlaybarTrackColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad" + prefix + "-icon:" + state);
+		addStyleParameter(builder, "-fx-text-fill", color.getButtonColor());
+		endStyleClass(builder);
+	}
+
+	// Color Associator
+	@Override
+	public Color getAssociatedEventColor() {
+		return Color.web(playColor.getColorHi());
+	}
+
+	@Override
+	public Color getAssociatedStandardColor() {
+		return Color.web(backgroundColor.getColorHi());
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutConnect.java b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..d26077ad8100763c42f1b2cd49046670f49cf4bd
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutConnect.java
@@ -0,0 +1,49 @@
+package de.tobias.playpad.layout.modern;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.GlobalLayout;
+import de.tobias.playpad.layout.LayoutConnect;
+import de.tobias.playpad.viewcontroller.CartLayoutViewController;
+import de.tobias.playpad.viewcontroller.GlobalLayoutViewController;
+import de.tobias.playpad.viewcontroller.layout.ModernLayoutCartViewController;
+import de.tobias.playpad.viewcontroller.layout.ModernLayoutGlobalViewController;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class ModernLayoutConnect extends LayoutConnect {
+
+	private static final String TYPE = "modern";
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty(Localization.getString(Strings.Layout_Modern_Name));
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public CartLayout newCartLayout() {
+		return new ModernLayoutCart();
+	}
+
+	@Override
+	public GlobalLayout newGlobalLayout() {
+		return new ModernLayoutGlobal();
+	}
+
+	@Override
+	public CartLayoutViewController getCartLayoutViewController(CartLayout cartLayout) {
+		return new ModernLayoutCartViewController(cartLayout);
+	}
+
+	@Override
+	public GlobalLayoutViewController getGlobalLayoutViewController(GlobalLayout globalLayout) {
+		return new ModernLayoutGlobalViewController(globalLayout);
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutGlobal.java b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutGlobal.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae5f91bca5f85098511dbbff5f8fb2827996bb0a
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutGlobal.java
@@ -0,0 +1,316 @@
+package de.tobias.playpad.layout.modern;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.FadeableColor;
+import de.tobias.playpad.layout.GlobalLayout;
+import de.tobias.playpad.layout.Layout;
+import de.tobias.playpad.layout.LayoutColorAssociator;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.Warning;
+import de.tobias.playpad.pad.conntent.Durationable;
+import de.tobias.playpad.pad.view.IPadViewController;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+import javafx.util.Duration;
+
+public class ModernLayoutGlobal extends Layout implements GlobalLayout, LayoutColorAssociator {
+
+	public static final String TYPE = "modern";
+
+	public static final double minWidth = 205;
+	public static final double minHeight = 110;
+
+	private ModernColor backgroundColor = ModernColor.GRAY1;
+	private ModernColor playColor = ModernColor.RED1;
+
+	private boolean isWarnAnimation = true;
+
+	private int infoFontSize = 14;
+	private int titleFontSize = 16;
+
+	public ModernColor getBackgroundColor() {
+		return backgroundColor;
+	}
+
+	public void setBackgroundColor(ModernColor backgroundColor) {
+		this.backgroundColor = backgroundColor;
+	}
+
+	public ModernColor getPlayColor() {
+		return playColor;
+	}
+
+	public void setPlayColor(ModernColor playColor) {
+		this.playColor = playColor;
+	}
+
+	public boolean isWarnAnimation() {
+		return isWarnAnimation;
+	}
+
+	public void setWarnAnimation(boolean isWarnAnimation) {
+		this.isWarnAnimation = isWarnAnimation;
+	}
+
+	public int getInfoFontSize() {
+		return infoFontSize;
+	}
+
+	public void setInfoFontSize(int infoFontSize) {
+		this.infoFontSize = infoFontSize;
+	}
+
+	public int getTitleFontSize() {
+		return titleFontSize;
+	}
+
+	public void setTitleFontSize(int titleFontSize) {
+		this.titleFontSize = titleFontSize;
+	}
+
+	@Override
+	public double getMinHeight(int rows) {
+		return rows * minHeight;
+	}
+
+	@Override
+	public double getMinWidth(int columns) {
+		return columns * minWidth;
+	}
+
+	@Override
+	public double getPadHeight() {
+		return minHeight;
+	}
+
+	@Override
+	public double getPadWidth() {
+		return minWidth;
+	}
+
+	public void reset() {
+		backgroundColor = ModernColor.GRAY1;
+		playColor = ModernColor.RED1;
+
+		isWarnAnimation = true;
+		
+		infoFontSize = 14;
+		titleFontSize = 16;
+	}
+
+	private String convertToCSS() {
+		StringBuilder builder = new StringBuilder();
+
+		startStyleClass(builder, "pad-icon");
+		addStyleParameter(builder, "-fx-text-fill", backgroundColor.getButtonColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad-playbar .track");
+		addStyleParameter(builder, "-fx-base", backgroundColor.getPlaybarColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad-playbar .bar");
+		addStyleParameter(builder, "-fx-background-color", backgroundColor.getPlaybarTrackColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad");
+		addStyleParameter(builder, "-fx-background-color", backgroundColor.linearGradient());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad-info");
+		addStyleParameter(builder, "-fx-text-fill", backgroundColor.getFontColor());
+		addStyleParameter(builder, "-fx-font-size", infoFontSize);
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad-title");
+		addStyleParameter(builder, "-fx-text-fill", backgroundColor.getFontColor());
+		addStyleParameter(builder, "-fx-font-size", titleFontSize);
+		endStyleClass(builder);
+
+		buildStateCss(builder, PseudoClasses.PLAY_CALSS.getPseudoClassName(), playColor);
+		buildStateCss(builder, PseudoClasses.WARN_CLASS.getPseudoClassName(), backgroundColor);
+
+		return builder.toString().replace("0x", "#");
+	}
+
+	private void buildStateCss(StringBuilder builder, String state, ModernColor color) {
+		startStyleClass(builder, "pad-info:" + state);
+		addStyleParameter(builder, "-fx-text-fill", color.getFontColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad-title:" + state);
+		addStyleParameter(builder, "-fx-text-fill", color.getFontColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad:" + state);
+		addStyleParameter(builder, "-fx-background-color", color.linearGradient());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad-playbar:" + state + " .track");
+		addStyleParameter(builder, "-fx-base", color.getPlaybarColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad-playbar:" + state + " .bar");
+		addStyleParameter(builder, "-fx-background-color", color.getPlaybarTrackColor());
+		endStyleClass(builder);
+
+		startStyleClass(builder, "pad-icon:" + state);
+		addStyleParameter(builder, "-fx-text-fill", color.getButtonColor());
+		endStyleClass(builder);
+	}
+
+	@Override
+	public void applyCss(Stage stage) {
+		// Clear Old
+		stage.getScene().getStylesheets().clear();
+
+		// Add Build in Default
+		stage.getScene().getStylesheets().add("de/tobias/playpad/assets/style.css");
+		stage.getScene().getStylesheets().add("de/tobias/playpad/assets/modern_style.css");
+
+		// User Settings
+		Path userCss = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "style.css");
+		if (Files.exists(userCss))
+			stage.getScene().getStylesheets().add(userCss.toUri().toString());
+	}
+
+	@Override
+	public void applyCssMainView(IMainViewController controller, Stage stage, Project project) {
+		applyCss(stage);
+
+		controller.setGridColor(Color.TRANSPARENT);
+
+		Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "custom_style.css");
+
+		String css = convertToCSS();
+
+		// Pad Spezelles Layout immer
+		for (Pad pad : project.getPads().values()) {
+			if (pad.isCustomLayout()) {
+				CartLayout layoutOpt = pad.getLayout(Profile.currentProfile().getProfileSettings().getLayoutType());
+				css += "\n" + layoutOpt.convertToCss(String.valueOf(pad.getIndex()), true);
+			}
+		}
+
+		// Speichern der generierten CSS Datei
+		try {
+			Files.write(path, css.getBytes());
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		stage.getScene().getStylesheets().remove(path.toUri().toString());
+		stage.getScene().getStylesheets().add(path.toUri().toString());
+	}
+
+	@Override
+	public void load(Element rootElement) {
+		Element backgroundElement = rootElement.element("BackgroundColor");
+		if (backgroundElement != null) {
+			try {
+				backgroundColor = ModernColor.valueOf(backgroundElement.getStringValue());
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			}
+		}
+
+		Element playElement = rootElement.element("PlayColor");
+		if (playElement != null) {
+			try {
+				playColor = ModernColor.valueOf(playElement.getStringValue());
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			}
+		}
+
+		Element animationElement = rootElement.element("Animation");
+		if (animationElement != null) {
+			Element warnAnimationElement = animationElement.element("Warn");
+			if (warnAnimationElement != null) {
+				isWarnAnimation = Boolean.valueOf(warnAnimationElement.getStringValue());
+			}
+		}
+
+		Element infoFontSizeElement = rootElement.element("InfoFontSize");
+		if (infoFontSizeElement != null) {
+			try {
+				infoFontSize = Integer.valueOf(infoFontSizeElement.getStringValue());
+			} catch (NumberFormatException e) {
+				e.printStackTrace();
+			}
+		}
+
+		Element titleFontSizeElement = rootElement.element("TitleFontSize");
+		if (titleFontSizeElement != null) {
+			try {
+				infoFontSize = Integer.valueOf(titleFontSizeElement.getStringValue());
+			} catch (NumberFormatException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	@Override
+	public void save(Element rootElement) {
+		rootElement.addElement("BackgroundColor").addText(backgroundColor.name());
+		rootElement.addElement("PlayColor").addText(playColor.name());
+		Element animationElement = rootElement.addElement("Animation");
+		animationElement.addElement("Warn").addText(String.valueOf(isWarnAnimation));
+		rootElement.addElement("InfoFontSize").addText(String.valueOf(infoFontSize));
+		rootElement.addElement("TitleFontSize").addText(String.valueOf(titleFontSize));
+	}
+
+	// Warn Handler -> Animation oder Blinken
+	@Override
+	public void handleWarning(IPadViewController controller, Warning warning) {
+		if (isWarnAnimation) {
+			warnAnimation(controller, warning);
+		} else {
+			ModernLayoutAnimator.warnFlash(controller);
+		}
+	}
+
+	@Override
+	public void stopWarning(IPadViewController controller) {
+		ModernLayoutAnimator.stopAnimation(controller);
+	}
+
+	private void warnAnimation(IPadViewController controller, Warning warning) {
+		FadeableColor stopColor = new FadeableColor(this.backgroundColor.getColorHi(), this.backgroundColor.getColorLow());
+		FadeableColor playColor = new FadeableColor(this.playColor.getColorHi(), this.playColor.getColorLow());
+
+		Duration warnDuration = warning.getTime();
+		Pad pad = controller.getPad();
+
+		if (pad.getContent() instanceof Durationable) {
+			if (warnDuration.greaterThan(((Durationable) pad.getContent()).getDuration())) {
+				warnDuration = ((Durationable) pad.getContent()).getDuration();
+			}
+		}
+
+		ModernLayoutAnimator.animateWarn(controller, playColor, stopColor, warnDuration);
+	}
+
+	// Color Associator
+	@Override
+	public Color getAssociatedEventColor() {
+		return Color.web(playColor.getColorHi());
+	}
+
+	@Override
+	public Color getAssociatedStandardColor() {
+		return Color.web(backgroundColor.getColorHi());
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/midi/device/PD12.java b/PlayWall/src/de/tobias/playpad/midi/device/PD12.java
new file mode 100644
index 0000000000000000000000000000000000000000..df4ceb01d9a4883b17752afdbab848abdae5c03d
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/midi/device/PD12.java
@@ -0,0 +1,60 @@
+package de.tobias.playpad.midi.device;
+
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.SysexMessage;
+
+import de.tobias.playpad.action.feedback.DisplayableFeedbackColor;
+import de.tobias.playpad.action.feedback.Feedback;
+import de.tobias.playpad.action.feedback.FeedbackMessage;
+import de.tobias.playpad.action.mididevice.Device;
+import de.tobias.playpad.settings.Profile;
+import javafx.application.Platform;
+
+public class PD12 extends Device {
+
+	public static final String NAME = "PD 12";
+
+	@Override
+	public String getName() {
+		return NAME;
+	}
+
+	@Override
+	public boolean supportFeedback() {
+		return false;
+	}
+
+	@Override
+	public void onMidiMessage(MidiMessage message) {
+		if (message instanceof SysexMessage) {
+			if (message.getMessage().length == 8) {
+				if (message.getMessage()[0] == -16 && message.getMessage()[1] == 127 && message.getMessage()[2] == 127
+						&& message.getMessage()[3] == 4 && message.getMessage()[4] == 1 && message.getMessage()[5] == 0
+						&& message.getMessage()[7] == -9) {
+					int volume = message.getMessage()[6];
+					double volume_ = volume / 127.0;
+					Platform.runLater(() -> Profile.currentProfile().getProfileSettings().setVolume(volume_));
+				}
+			}
+		}
+	}
+
+	@Override
+	public void handleFeedback(FeedbackMessage type, int key, Feedback feedback) {}
+
+	@Override
+	public void initFeedback() {}
+
+	@Override
+	public void clearFeedback() {}
+
+	@Override
+	public DisplayableFeedbackColor getColor(int id) {
+		return null;
+	}
+
+	@Override
+	public DisplayableFeedbackColor[] getColors() {
+		return null;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e2d50338664957373c7f1e6ca4d6a66718e5017
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java
@@ -0,0 +1,279 @@
+package de.tobias.playpad.pad.content;
+
+import java.io.FileNotFoundException;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.audio.AudioHandler;
+import de.tobias.playpad.audio.AudioRegistry;
+import de.tobias.playpad.audio.Equalizable;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.Durationable;
+import de.tobias.playpad.pad.conntent.Fadeable;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.conntent.Pauseable;
+import de.tobias.playpad.project.ProjectExporter;
+import de.tobias.playpad.settings.Profile;
+import javafx.animation.Transition;
+import javafx.application.Platform;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.scene.media.AudioEqualizer;
+import javafx.util.Duration;
+
+public class AudioContent extends PadContent implements Pauseable, Durationable, Fadeable, Equalizable {
+
+	private static final String TYPE = "audio";
+
+	private Path path;
+	private AudioHandler audioHandler;
+
+	private ObjectProperty<Duration> durationProperty = new SimpleObjectProperty<>();
+	private ObjectProperty<Duration> positionProperty = new SimpleObjectProperty<>();
+
+	private ChangeListener<Number> volumeListener;
+
+	private transient Transition transition;
+
+	public AudioContent(Pad pad) {
+		super(pad);
+		volumeListener = (a, b, c) ->
+		{
+			audioHandler.setVolume(c.doubleValue(), Profile.currentProfile().getProfileSettings().getVolume());
+		};
+	}
+
+	public AudioContent(Pad pad, Path path) {
+		this(pad);
+		this.path = path;
+	}
+
+	public Path getPath() {
+		return path;
+	}
+
+	public void setPath(Path path) {
+		this.path = path;
+	}
+
+	@Override
+	public void handlePath(Path path) {
+		unloadMedia();
+		setPath(path);
+		loadMedia();
+	}
+
+	@Override
+	public void setMasterVolume(double masterVolume) {
+		if (audioHandler != null) {
+			audioHandler.setVolume(getPad().getVolume(), masterVolume);
+		}
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public void play() {
+		getPad().setEof(false);
+		audioHandler.play();
+	}
+
+	@Override
+	public void pause() {
+		audioHandler.pause();
+	}
+
+	@Override
+	public boolean stop() {
+		audioHandler.stop();
+		return true;
+	}
+
+	@Override
+	public void fadeIn() {
+		if (transition != null) {
+			transition.stop();
+		}
+
+		if (getPad().getFade().getFadeIn().toMillis() > 0) {
+			double masterVolume = Profile.currentProfile().getProfileSettings().getVolume();
+			audioHandler.setVolume(0, masterVolume);
+			transition = new Transition() {
+
+				{
+					setCycleDuration(getPad().getFade().getFadeIn());
+				}
+
+				@Override
+				protected void interpolate(double frac) {
+					audioHandler.setVolume(frac * getPad().getVolume(), masterVolume);
+				}
+			};
+			transition.setOnFinished(e ->
+			{
+				transition = null;
+			});
+			transition.play();
+		}
+	}
+
+	@Override
+	public void fadeOut(Runnable onFinish) {
+		if (transition != null) {
+			transition.stop();
+		}
+
+		if (getPad().getFade().getFadeOut().toMillis() > 0) {
+			transition = new Transition() {
+
+				{
+					setCycleDuration(getPad().getFade().getFadeOut());
+				}
+
+				@Override
+				protected void interpolate(double frac) {
+					double masterVolume = Profile.currentProfile().getProfileSettings().getVolume();
+					audioHandler.setVolume(getPad().getVolume() - frac * getPad().getVolume(), masterVolume);
+				}
+			};
+			transition.setOnFinished(event ->
+			{
+				onFinish.run();
+
+				double masterVolume = Profile.currentProfile().getProfileSettings().getVolume();
+				audioHandler.setVolume(getPad().getVolume(), masterVolume);
+				transition = null;
+			});
+			transition.play();
+		} else {
+			onFinish.run();
+		}
+	}
+
+	@Override
+	public boolean isFading() {
+		if (transition != null) {
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public AudioEqualizer getAudioEqualizer() {
+		if (audioHandler instanceof Equalizable) {
+			return ((Equalizable) audioHandler).getAudioEqualizer();
+		}
+		return null;
+	}
+
+	@Override
+	public boolean isPadLoaded() {
+		return audioHandler.isMediaLoaded();
+	}
+
+	@Override
+	public Duration getDuration() {
+		return durationProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> durationProperty() {
+		return durationProperty;
+	}
+
+	@Override
+	public Duration getPosition() {
+		return positionProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> positionProperty() {
+		return positionProperty;
+	}
+
+	@Override
+	public void loadMedia() {
+		audioHandler = AudioRegistry.geAudioType().createAudioHandler(this);
+		if (Files.exists(path)) {
+			audioHandler.loadMedia();
+
+			durationProperty.bind(audioHandler.durationProperty());
+			positionProperty.bind(audioHandler.positionProperty());
+
+			getPad().volumeProperty().addListener(volumeListener);
+		} else {
+			getPad().throwException(path, new FileNotFoundException());
+		}
+	}
+
+	@Override
+	public void unloadMedia() {
+		durationProperty.unbind();
+		positionProperty.unbind();
+
+		getPad().volumeProperty().removeListener(volumeListener);
+
+		if (audioHandler != null)
+			audioHandler.unloadMedia();
+		try {
+			getPad().setStatus(PadStatus.EMPTY);
+		} catch (Exception e) {
+			Platform.runLater(() -> getPad().setStatus(PadStatus.EMPTY));
+		}
+	}
+
+	@Override
+	public void load(Element element) {
+		path = Paths.get(element.getStringValue());
+	}
+
+	@Override
+	public void save(Element element) {
+		element.addText(path.toString());
+	}
+
+	@Override
+	public void importMedia(Path mediaFolder, FileSystem zipfs, Element element) {
+		String fileName = Paths.get(element.getStringValue()).getFileName().toString();
+		Path mediaFile = zipfs.getPath(ProjectExporter.mediaFolder, fileName);
+		if (Files.exists(mediaFile)) {
+			Path desFile = mediaFolder.resolve(fileName);
+
+			try {
+				if (Files.notExists(desFile.getParent())) {
+					Files.createDirectories(desFile.getParent());
+				}
+				Files.copy(mediaFile, desFile, StandardCopyOption.REPLACE_EXISTING);
+
+				element.setText(desFile.toString());
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	@Override
+	public void exportMedia(FileSystem mediaFolder, Element element) {
+		Path desPath = mediaFolder.getPath(ProjectExporter.mediaFolder, path.getFileName().toString());
+		try {
+			if (Files.notExists(desPath.getParent())) {
+				Files.createDirectories(desPath.getParent());
+			}
+			Files.copy(path, desPath, StandardCopyOption.REPLACE_EXISTING);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java b/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..9566b9095e2e83096c5b08b2f62cc679883465d8
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java
@@ -0,0 +1,105 @@
+package de.tobias.playpad.pad.content;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.pad.view.IPadContentView;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.viewcontroller.option.AudioTabViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.TextAlignment;
+
+public class AudioContentConnect extends PadContentConnect {
+
+	public static final String TYPE = "audio";
+	public static final String[] FILE_EXTENSION = { "*.mp3", "*.wav" };
+
+	private FontIcon icon;
+
+	public AudioContentConnect() {
+		icon = new FontIcon(FontAwesomeType.MUSIC);
+		icon.setSize(30);
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public PadContent newInstance(Pad pad) {
+		return new AudioContent(pad);
+	}
+
+	@Override
+	public String[] getSupportedTypes() {
+		return FILE_EXTENSION;
+	}
+
+	@Override
+	public IPadContentView getPadContentPreview(Pad pad, Pane parentNode) {
+		if (pad.getContent() != null) {
+			AudioContentView view = new AudioContentView(pad, parentNode);
+
+			return view;
+		} else {
+			return null;
+		}
+	}
+
+	@Override
+	public SettingsTabViewController getSettingsTabViewController(boolean activePlayer) {
+		return new AudioTabViewController(activePlayer);
+	}
+
+	private class AudioContentView implements IPadContentView {
+
+		private Label nameLabel;
+
+		public AudioContentView(Pad pad, Pane parentNode) {
+			nameLabel = new Label();
+			nameLabel.textProperty().bind(pad.nameProperty());
+
+			nameLabel.setWrapText(true);
+			nameLabel.setAlignment(Pos.CENTER);
+			nameLabel.setTextAlignment(TextAlignment.CENTER);
+
+			nameLabel.prefWidthProperty().bind(parentNode.widthProperty());
+			nameLabel.setMaxHeight(Double.MAX_VALUE);
+			VBox.setVgrow(nameLabel, Priority.ALWAYS);
+		}
+
+		@Override
+		public Node getNode() {
+			return nameLabel;
+		}
+
+		@Override
+		public void unconnect() {
+			nameLabel.textProperty().unbind();
+		}
+	}
+
+	// UI - DnD
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty(Localization.getString(Strings.Content_Audio_Name));
+	}
+
+	@Override
+	public Node getGraphics() {
+		return icon;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java b/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf6bbc47811da7668d9c046ce1c68610dd02528d
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java
@@ -0,0 +1,41 @@
+package de.tobias.playpad.pad.drag;
+
+import de.tobias.playpad.project.Project;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.scene.Node;
+
+public class MoveDragMode extends PadDragMode {
+
+	private static final String TYPE = "move";
+
+	private FontIcon icon;
+
+	public MoveDragMode() {
+		icon = new FontIcon(FontAwesomeType.ARROWS);
+		icon.setSize(30);
+	}
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty("Tauschen"); // TODO Localize
+	}
+
+	@Override
+	public Node getGraphics() {
+		return icon;
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public void handle(int oldPad, int newPad, Project project) {
+		project.movePads(oldPad, newPad);
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java b/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..a01255fe87f135bd006b9e9cc8c3c6672ac07d8d
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java
@@ -0,0 +1,41 @@
+package de.tobias.playpad.pad.drag;
+
+import de.tobias.playpad.project.Project;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.scene.Node;
+
+public class ReplaceDragMode extends PadDragMode {
+
+	private static final String TYPE = "replace";
+
+	private FontIcon icon;
+
+	public ReplaceDragMode() {
+		icon = new FontIcon(FontAwesomeType.ARROW_CIRCLE_RIGHT);
+		icon.setSize(30);
+	}
+
+	@Override
+	public StringProperty displayProperty() {
+		return new SimpleStringProperty("Ersetzen"); // TODO Localize
+	}
+
+	@Override
+	public Node getGraphics() {
+		return icon;
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public void handle(int oldPad, int newPad, Project project) {
+		project.replacePads(oldPad, newPad);
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/pad/listener/PadContentListener.java b/PlayWall/src/de/tobias/playpad/pad/listener/PadContentListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..54a756291bf94eadf7604b74b0df646beb44b913
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/pad/listener/PadContentListener.java
@@ -0,0 +1,53 @@
+package de.tobias.playpad.pad.listener;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.conntent.Durationable;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.viewcontroller.pad.PadViewController;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+public class PadContentListener implements ChangeListener<PadContent> {
+
+	private Pad pad;
+	private PadViewController controller;
+
+	public PadContentListener(PadViewController controller) {
+		this.controller = controller;
+	}
+
+	public void setPad(Pad pad) {
+		this.pad = pad;
+	}
+
+	@Override
+	public void changed(ObservableValue<? extends PadContent> observable, PadContent oldValue, PadContent newValue) {
+		// wenn Content change, update preview & buttons
+		controller.getParent().setPreviewContent(pad);
+		controller.getParent().addDefaultButton(pad);
+
+		controller.updateButtonDisable();
+		controller.updateTimeLabel();
+
+		// Remove old listener
+		if (oldValue != null && oldValue instanceof Durationable) {
+			Durationable oldDurationable = (Durationable) oldValue;
+			oldDurationable.durationProperty().removeListener(controller.getPadDurationListener());
+			oldDurationable.positionProperty().removeListener(controller.getPadPositionListener());
+		}
+
+		// set new content listener / bindings
+		if (newValue instanceof Durationable) {
+			controller.getParent().showPlaybar(true);
+
+			Durationable durationable = (Durationable) newValue;
+			durationable.durationProperty().addListener(controller.getPadDurationListener());
+			durationable.positionProperty().addListener(controller.getPadPositionListener());
+
+			// Init Duration
+			controller.getPadDurationListener().changed(null, null, durationable.getDuration());
+		} else {
+			controller.getParent().showPlaybar(false);
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/pad/listener/PadDurationListener.java b/PlayWall/src/de/tobias/playpad/pad/listener/PadDurationListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..2058d3a1e30e520e032487d185561cdb0f8f6b33
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/pad/listener/PadDurationListener.java
@@ -0,0 +1,22 @@
+package de.tobias.playpad.pad.listener;
+
+import de.tobias.playpad.viewcontroller.pad.PadViewController;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.util.Duration;
+
+public class PadDurationListener implements ChangeListener<Duration> {
+
+	private PadViewController controller;
+
+	public PadDurationListener(PadViewController controller) {
+		this.controller = controller;
+	}
+
+	@Override
+	public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
+		if (controller != null) {
+			controller.updateTimeLabel();
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java b/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..40e9b5b6a491b1fbe583d035f07b546ea85c283a
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java
@@ -0,0 +1,106 @@
+package de.tobias.playpad.pad.listener;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.Warning;
+import de.tobias.playpad.pad.conntent.Durationable;
+import de.tobias.playpad.pad.conntent.Fadeable;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.pad.PadViewController;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.util.Duration;
+
+public class PadPositionListener implements ChangeListener<Duration>, Runnable {
+
+	private Pad pad;
+	private PadViewController controller;
+
+	public PadPositionListener(PadViewController controller) {
+		this.controller = controller;
+	}
+
+	public void setPad(Pad pad) {
+		this.pad = pad;
+	}
+
+	boolean send = false;
+	private Thread warningThread;
+
+	@Override
+	public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
+		if (oldValue == Duration.ZERO) {
+			setSend(false);
+		}
+
+		// Progressbar (Prozente)
+		if (pad != null) {
+			// Zeit aktualiesieren bei Play und wenn Fade Out ist
+			if (pad.getContent() instanceof Durationable && (pad.getStatus() == PadStatus.PLAY
+					|| (pad.getContent() instanceof Fadeable && ((Fadeable) pad.getContent()).isFading()))) {
+
+				Durationable durationable = (Durationable) pad.getContent();
+				Duration totalDuration = durationable.getDuration();
+
+				double value = newValue.toMillis() / totalDuration.toMillis();
+				controller.getParent().getPlayBar().setProgress(value);
+
+				// Label (Restlaufzeit)
+				controller.updateTimeLabel();
+
+				// Warning nur wenn kein Loop und nur wenn Play, da sonst schon anderer Zustand und Warning nicht mehr richtig Reseted wird
+				if (!pad.isLoop() && pad.getStatus() == PadStatus.PLAY) {
+					// Warning
+					Warning warning = pad.getWarning();
+					Duration rest = durationable.getDuration().subtract(newValue);
+					double seconds = rest.toSeconds();
+
+					if (warning.getTime().toSeconds() > seconds && !send) {
+						startWarningThread();
+						send = true;
+					}
+				}
+			}
+		}
+	}
+
+	public void setSend(boolean send) {
+		this.send = send;
+	}
+
+	/*
+	 * EoF GUI Flash
+	 */
+	@Override
+	public void run() {
+		Warning warning = pad.getWarning();
+
+		if (pad.isCustomLayout()) {
+			pad.getLayout().handleWarning(controller, warning);
+		} else {
+			Profile.currentProfile().currentLayout().handleWarning(controller, warning);
+		}
+	}
+
+	protected void startWarningThread() {
+		if (warningThread != null) {
+			warningThread.interrupt();
+		}
+		warningThread = new Thread(this);
+		warningThread.start();
+	}
+
+	public void stopWaning() {
+		if (warningThread != null) {
+			warningThread.interrupt();
+			warningThread = null;
+		}
+
+		if (pad.isCustomLayout()) {
+			pad.getLayout().stopWarning(controller);
+		} else {
+			Profile.currentProfile().currentLayout().stopWarning(controller);
+		}
+		controller.getParent().setStyle("");
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/pad/listener/PadStatusListener.java b/PlayWall/src/de/tobias/playpad/pad/listener/PadStatusListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..117e2aa04ccf8572531368b51767dc99feb5b06c
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/pad/listener/PadStatusListener.java
@@ -0,0 +1,75 @@
+package de.tobias.playpad.pad.listener;
+
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.viewcontroller.pad.PadViewController;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
+public class PadStatusListener implements ChangeListener<PadStatus> {
+
+	private PadViewController controller;
+
+	public PadStatusListener(PadViewController controller) {
+		this.controller = controller;
+	}
+
+	@Override
+	public void changed(ObservableValue<? extends PadStatus> observable, PadStatus oldValue, PadStatus newValue) {
+		controller.updateButtonDisable();
+		controller.updateTimeLabel();
+		controller.getParent().setErrorLabelActive(false);
+
+		switch (newValue) {
+		case PLAY:
+			// Reset Warning Feedback for UI
+			controller.getPadPositionListener().setSend(false);
+
+			// UI Styling
+			controller.getParent().pseudoClassState(PseudoClasses.PLAY_CALSS, true);
+			break;
+
+		case PAUSE:
+			controller.getPadPositionListener().stopWaning();
+			controller.getParent().pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.FADE_CLASS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.WARN_CLASS, false);
+			break;
+
+		case STOP:
+			controller.getPadPositionListener().stopWaning();
+			controller.getParent().pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.FADE_CLASS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.WARN_CLASS, false);
+			controller.getParent().setStyle("");
+			break;
+
+		case READY:
+			controller.getPadPositionListener().stopWaning();
+			controller.getParent().pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.FADE_CLASS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.WARN_CLASS, false);
+			controller.getParent().setStyle(""); // Cleanup from warning UI
+			break;
+		case ERROR:
+			controller.getParent().setErrorLabelActive(true);
+
+			controller.getPadPositionListener().stopWaning();
+			controller.getParent().pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.FADE_CLASS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.WARN_CLASS, false);
+			controller.getParent().setStyle(""); // Cleanup from warning UI
+			break;
+
+		case EMPTY:
+			controller.getPadPositionListener().stopWaning();
+			controller.getParent().pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.FADE_CLASS, false);
+			controller.getParent().pseudoClassState(PseudoClasses.WARN_CLASS, false);
+			controller.getParent().setStyle(""); // Cleanup from warning UI
+			break;
+		default:
+			break;
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItem.java b/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItem.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7e056734a4a0985f231369a7ec3e77018f886b4
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItem.java
@@ -0,0 +1,167 @@
+package de.tobias.playpad.trigger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.tigger.TriggerItem;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+
+public class CartTriggerItem extends TriggerItem {
+
+	private List<Integer> carts;
+	private boolean allCarts;
+	private PadStatus newStatus; // Only Play, Pause, Stop
+
+	public CartTriggerItem() {
+		newStatus = PadStatus.PLAY;
+		allCarts = false;
+		carts = new ArrayList<Integer>() {
+
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public boolean add(Integer e) {
+				if (!contains(e))
+					return super.add(e);
+				else
+					return false;
+			}
+		};
+	}
+
+	public List<Integer> getCarts() {
+		return carts;
+	}
+
+	public boolean isAllCarts() {
+		return allCarts;
+	}
+
+	public void setAllCarts(boolean allCarts) {
+		this.allCarts = allCarts;
+	}
+
+	public PadStatus getNewStatus() {
+		return newStatus;
+	}
+
+	public void setNewStatus(PadStatus newStatus) {
+		if (newStatus == PadStatus.PLAY || newStatus == PadStatus.PAUSE || newStatus == PadStatus.STOP)
+			this.newStatus = newStatus;
+	}
+
+	@Override
+	public String getType() {
+		return CartTriggerItemConnect.TYPE;
+	}
+
+	@Override
+	public void performAction(Pad pad, Project project, IMainViewController controller, Profile profile) {
+		if (allCarts) {
+			for (Pad cart : project.getPads().values()) {
+				if (cart.getIndex() != pad.getIndex())
+					cart.setStatus(newStatus);
+			}
+		} else {
+			for (int cart : carts) {
+				if (cart != pad.getIndex())
+					project.getPad(cart).setStatus(newStatus);
+			}
+		}
+	}
+
+	private static final String CART_ELEMENT = "Cart";
+	private static final String STATUS_ATTR = "Status";
+	private static final String ALLCARTS_ATTR = "all";
+
+	@Override
+	public void load(Element element) {
+		super.load(element);
+
+		if (element.attributeValue(STATUS_ATTR) != null)
+			setNewStatus(PadStatus.valueOf(element.attributeValue(STATUS_ATTR)));
+		if (element.attributeValue(ALLCARTS_ATTR) != null)
+			setAllCarts(Boolean.valueOf(element.attributeValue(ALLCARTS_ATTR)));
+
+		for (Object cartObj : element.elements(CART_ELEMENT)) {
+			if (cartObj instanceof Element) {
+				Element cartElement = (Element) cartObj;
+				carts.add(Integer.valueOf(cartElement.getStringValue()));
+			}
+		}
+	}
+
+	@Override
+	public void save(Element element) {
+		super.save(element);
+
+		element.addAttribute(STATUS_ATTR, newStatus.name());
+		element.addAttribute(ALLCARTS_ATTR, String.valueOf(allCarts));
+
+		for (int cart : carts) {
+			Element cartElement = element.addElement(CART_ELEMENT);
+			cartElement.addText(String.valueOf(cart));
+		}
+	}
+
+	public void setCartsString(String string) {
+		if (string != null) {
+			carts.clear();
+			string = string.replace(" ", "");
+			for (String part : string.split(",")) {
+				if (part.contains("-")) {
+					if (part.split("-").length == 2) {
+						int start = Integer.valueOf(part.split("-")[0]);
+						int end = Integer.valueOf(part.split("-")[1]);
+
+						for (int i = start; i <= end; i++) {
+							carts.add(i - 1);
+						}
+					}
+				} else {
+					int cart = Integer.valueOf(part);
+					carts.add(cart - 1);
+				}
+			}
+			carts.sort(Integer::compareTo);
+		}
+	}
+
+	public String getCartsString() {
+		String string = "";
+		int startValue = -1;
+
+		for (int i = 0; i < carts.size(); i++) {
+			if (i + 1 < carts.size()) {
+				if (carts.get(i) + 1 == carts.get(i + 1)) {
+					if (startValue == -1) {
+						startValue = carts.get(i);
+					}
+				} else {
+					if (startValue != -1)
+						string += (startValue + 1) + "-" + (carts.get(i) + 1) + ",";
+					else
+						string += (carts.get(i) + 1) + ",";
+					startValue = -1;
+
+				}
+			} else {
+				if (startValue == -1) {
+					string += (carts.get(i) + 1) + ",";
+				} else {
+					string += (startValue + 1) + "-" + (carts.get(i) + 1) + ",";
+				}
+			}
+		}
+		if (string.isEmpty()) {
+			return null;
+		}
+		return string.substring(0, string.length() - 1);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItemConnect.java b/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItemConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..873488ad8610e1abe8d583607b298e4bcbf0d249
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItemConnect.java
@@ -0,0 +1,34 @@
+package de.tobias.playpad.trigger;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.tigger.Trigger;
+import de.tobias.playpad.tigger.TriggerItem;
+import de.tobias.playpad.tigger.TriggerItemConnect;
+import de.tobias.playpad.viewcontroller.option.pad.trigger.CartTriggerViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+
+public class CartTriggerItemConnect extends TriggerItemConnect {
+
+	public final static String TYPE = "Cart";
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public TriggerItem newInstance(Trigger trigger) {
+		return new CartTriggerItem();
+	}
+
+	@Override
+	public ContentViewController getSettingsController(TriggerItem item) {
+		return new CartTriggerViewController((CartTriggerItem) item);
+	}
+
+	@Override
+	public String toString() {
+		return Localization.getString(Strings.Trigger_Cart_Name);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/trigger/TriggerWrapper.java b/PlayWall/src/de/tobias/playpad/trigger/TriggerWrapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..039e62de4361faa4ec38ca83756d1b65171e74d4
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/trigger/TriggerWrapper.java
@@ -0,0 +1,50 @@
+package de.tobias.playpad.trigger;
+
+import de.tobias.playpad.Displayable;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.tigger.Trigger;
+import de.tobias.playpad.tigger.TriggerItem;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class TriggerWrapper implements Displayable {
+
+	private Trigger trigger;
+
+	public TriggerWrapper(Trigger trigger) {
+		this.trigger = trigger;
+		updateString();
+	}
+
+	public Trigger getTrigger() {
+		return trigger;
+	}
+
+	private StringProperty displayable = new SimpleStringProperty();
+
+	@Override
+	public StringProperty displayProperty() {
+		return displayable;
+	}
+
+	public void addItem(TriggerItem triggerItem) {
+		trigger.addItem(triggerItem);
+		updateString();
+	}
+
+	public void removeItem(TriggerItem item) {
+		trigger.removeItem(item);
+		updateString();
+	}
+
+	private void updateString() {
+		displayable.set(toString());
+	}
+
+	@Override
+	public String toString() {
+		String triggerPointName = Localization.getString(Strings.TriggerPoint_BaseName + trigger.getTriggerPoint().name());
+		return Localization.getString(Strings.TriggerPoint_toString, triggerPointName, trigger.getItems().size());
+	}
+}
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6124d754ebfdca60885c9e0f5633e050d45d6ed
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java
@@ -0,0 +1,20 @@
+package de.tobias.playpad.trigger;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.tigger.TriggerItem;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+
+public class VolumeTriggerItem extends TriggerItem {
+
+	@Override
+	public String getType() {
+		return VolumeTriggerItemConnect.TYPE;
+	}
+
+	@Override
+	public void performAction(Pad pad, Project project, IMainViewController controller, Profile profile) {
+
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItemConnect.java b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItemConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c242e425d7461f1e5a0f4f0ff9e99b09f67b517
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItemConnect.java
@@ -0,0 +1,33 @@
+package de.tobias.playpad.trigger;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.tigger.Trigger;
+import de.tobias.playpad.tigger.TriggerItem;
+import de.tobias.playpad.tigger.TriggerItemConnect;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+
+public class VolumeTriggerItemConnect extends TriggerItemConnect {
+
+	public final static String TYPE = "Volume";
+	
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public TriggerItem newInstance(Trigger trigger) {
+		return new VolumeTriggerItem();
+	}
+
+	@Override
+	public ContentViewController getSettingsController(TriggerItem item) {
+		return null;
+	}
+
+	@Override
+	public String toString() {
+		return Localization.getString(Strings.Trigger_Volume_Name);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/view/ColorView.java b/PlayWall/src/de/tobias/playpad/view/ColorView.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff09b68021852c4ebf68451ece4cb165c952fccf
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/view/ColorView.java
@@ -0,0 +1,48 @@
+package de.tobias.playpad.view;
+
+import java.util.function.Consumer;
+
+import de.tobias.playpad.DisplayableColor;
+import javafx.geometry.Insets;
+import javafx.scene.layout.GridPane;
+import javafx.scene.shape.Rectangle;
+
+public class ColorView extends GridPane {
+
+	public ColorView(DisplayableColor startColor, DisplayableColor[] colors, Consumer<DisplayableColor> finish) {
+		double size = Math.sqrt(colors.length);
+		int iSize = (int) size;
+		if (size != iSize) {
+			iSize++;
+		}
+
+		setVgap(5);
+		setHgap(5);
+
+		setPadding(new Insets(5));
+
+		int index = 0;
+		for (int y = 0; y < iSize; y++) {
+			for (int x = 0; x < iSize; x++) {
+				if (index < colors.length) {
+					DisplayableColor color = colors[index++];
+
+					// Style in CSS
+					Rectangle rectangle = new Rectangle(40, 40);
+					rectangle.setFill(color.getPaint());
+
+					rectangle.getStyleClass().add("color-view-item");
+
+					// Gestrichelte Linie
+					if (color == startColor) {
+						rectangle.getStrokeDashArray().addAll(3.0);
+					}
+
+					// EventHandler
+					rectangle.setOnMouseReleased(event -> finish.accept(color));
+					add(rectangle, x, y);
+				}
+			}
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/view/EmptyPadView.java b/PlayWall/src/de/tobias/playpad/view/EmptyPadView.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc05c503e6d240fbad846193c16dfb10064b2c40
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/view/EmptyPadView.java
@@ -0,0 +1,23 @@
+package de.tobias.playpad.view;
+
+import de.tobias.playpad.Strings;
+import de.tobias.utils.util.Localization;
+import javafx.geometry.Pos;
+import javafx.scene.control.Label;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.TextAlignment;
+
+public class EmptyPadView extends Label {
+
+	public EmptyPadView(Pane parent) {
+		super(Localization.getString(Strings.Content_Empty));
+		setWrapText(true);
+		setAlignment(Pos.CENTER);
+		setTextAlignment(TextAlignment.CENTER);
+		prefWidthProperty().bind(parent.widthProperty());
+		setMaxHeight(Double.MAX_VALUE);
+		VBox.setVgrow(this, Priority.ALWAYS);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/view/ExceptionButton.java b/PlayWall/src/de/tobias/playpad/view/ExceptionButton.java
new file mode 100644
index 0000000000000000000000000000000000000000..c663458ceaeb0ae65caa3ce8d93ab7d6c7394b9f
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/view/ExceptionButton.java
@@ -0,0 +1,54 @@
+package de.tobias.playpad.view;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.Button;
+import javafx.stage.FileChooser;
+import javafx.stage.Window;
+
+public class ExceptionButton<T> {
+
+	public static ExceptionButton<Path> FILE_NOT_FOUND_EXCEPTION = new ExceptionButton<>(Localization.getString(Strings.Error_Fix_NewFile),
+			new Handler<Path>() {
+
+				@Override
+				public Path handle(Pad pad, Window owner) {
+					FileChooser chooser = new FileChooser();
+
+					Object lastFolder = ApplicationUtils.getApplication().getUserDefaults().getData("openFolder");
+					if (lastFolder != null) {
+						Path path = Paths.get(lastFolder.toString());
+						chooser.setInitialDirectory(path.toFile());
+					}
+					File file = chooser.showOpenDialog(owner);
+					return file != null ? file.toPath() : null;
+				}
+			});
+
+	public static interface Handler<T> {
+
+		public T handle(Pad pad, Window owner);
+	}
+
+	private String title;
+	private Handler<T> handler;
+
+	public ExceptionButton(String title, Handler<T> handler) {
+		this.title = title;
+		this.handler = handler;
+	}
+
+	public Button getButton() {
+		return new Button(title);
+	}
+
+	public Handler<T> getHandler() {
+		return handler;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/view/FileDragOptionView.java b/PlayWall/src/de/tobias/playpad/view/FileDragOptionView.java
new file mode 100644
index 0000000000000000000000000000000000000000..191a1aca1d2aeceedfa394d1989fc5f90ce717c3
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/view/FileDragOptionView.java
@@ -0,0 +1,179 @@
+package de.tobias.playpad.view;
+
+import java.util.Set;
+import java.util.function.Consumer;
+
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.pad.conntent.PadContentConnect;
+import javafx.animation.FadeTransition;
+import javafx.animation.ParallelTransition;
+import javafx.animation.ScaleTransition;
+import javafx.animation.Transition;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.control.Label;
+import javafx.scene.layout.Background;
+import javafx.scene.layout.BackgroundFill;
+import javafx.scene.layout.CornerRadii;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Priority;
+import javafx.scene.paint.Color;
+import javafx.scene.text.TextAlignment;
+
+public class FileDragOptionView {
+
+	private HBox optionPane;
+	private Pane parent;
+
+	private Transition inTransition;
+	private Transition outTransition;
+
+	public FileDragOptionView(Pane pane) {
+		parent = pane;
+
+		optionPane = new HBox();
+		optionPane.prefWidthProperty().bind(parent.widthProperty());
+		optionPane.prefHeightProperty().bind(parent.heightProperty());
+		optionPane.setBackground(new Background(new BackgroundFill(new Color(0.2, 0.2, 0.2, 0.8), new CornerRadii(10), new Insets(0))));
+		optionPane.setAlignment(Pos.CENTER);
+		optionPane.setPadding(new Insets(5));
+		optionPane.setSpacing(5);
+
+		inTransition = createTransition(true);
+		outTransition = createTransition(false);
+
+	}
+
+	public Transition getInTransition() {
+		return inTransition;
+	}
+
+	public void setInTransition(Transition inTransition) {
+		this.inTransition = inTransition;
+	}
+
+	public Transition getOutTransition() {
+		return outTransition;
+	}
+
+	public void setOutTransition(Transition outTransition) {
+		this.outTransition = outTransition;
+	}
+
+	private Transition createTransition(boolean in) {
+		FadeTransition fadeTransition = new FadeTransition();
+		fadeTransition.setNode(optionPane);
+
+		ScaleTransition scaleTransition = new ScaleTransition();
+		scaleTransition.setNode(optionPane);
+
+		if (in) {
+			fadeTransition.setFromValue(0);
+			fadeTransition.setToValue(1);
+
+			scaleTransition.setFromX(1.3);
+			scaleTransition.setFromY(1.3);
+			scaleTransition.setToX(1);
+			scaleTransition.setToY(1);
+		} else {
+			fadeTransition.setFromValue(1);
+			fadeTransition.setToValue(0);
+
+			scaleTransition.setFromX(1);
+			scaleTransition.setFromY(1);
+			scaleTransition.setToX(1.3);
+			scaleTransition.setToY(1.3);
+		}
+
+		ParallelTransition parallelTransition = new ParallelTransition(fadeTransition, scaleTransition);
+
+		parallelTransition.setOnFinished((e) ->
+		{
+			if (!in)
+				parent.getChildren().remove(optionPane);
+		});
+		return parallelTransition;
+	}
+
+	private PadContentConnect selectedConnect;
+
+	public void showDropOptions(Set<PadContentConnect> options) {
+		if (!parent.getChildren().contains(optionPane)) {
+			selectedConnect = null;
+
+			parent.getChildren().add(optionPane);
+			optionPane.getChildren().clear();
+
+			for (PadContentConnect connect : options.stream().sorted().toArray(value -> new PadContentConnect[value])) {
+				Label label = new Label();
+				label.getStyleClass().add("dnd-file-option");
+				label.textProperty().bind(connect.displayProperty());
+				Node graphics = connect.getGraphics();
+				if (graphics != null) {
+					graphics.setStyle("-fx-text-fill: white;");
+					label.setGraphic(graphics);
+				}
+				label.setWrapText(true);
+
+				label.setOnDragOver(e ->
+				{
+					label.pseudoClassStateChanged(PseudoClasses.HOVER_CLASS, true);
+					selectedConnect = connect;
+				});
+				label.setOnDragExited(e ->
+				{
+					label.pseudoClassStateChanged(PseudoClasses.HOVER_CLASS, false);
+					selectedConnect = null;
+				});
+
+				label.setUserData(connect);
+
+				label.setAlignment(Pos.CENTER);
+				label.setTextAlignment(TextAlignment.CENTER);
+				label.setContentDisplay(ContentDisplay.TOP);
+
+				label.maxWidthProperty().bind(optionPane.widthProperty().divide(options.size()).subtract(12.5));
+				label.setMaxHeight(Double.MAX_VALUE);
+				HBox.setHgrow(label, Priority.ALWAYS);
+
+				optionPane.getChildren().add(label);
+			}
+
+			inTransition.play();
+		}
+
+	}
+
+	public void showDropOptions(Set<PadContentConnect> options, Consumer<PadContentConnect> onFinish) {
+		showDropOptions(options);
+
+		for (Node node : optionPane.getChildren()) {
+			if (node instanceof Label) {
+				Label label = (Label) node;
+				label.setOnMouseClicked(ev ->
+				{
+					onFinish.accept((PadContentConnect) label.getUserData());
+				});
+				label.setOnMouseEntered(e ->
+				{
+					label.pseudoClassStateChanged(PseudoClasses.HOVER_CLASS, true);
+				});
+				label.setOnMouseExited(e ->
+				{
+					label.pseudoClassStateChanged(PseudoClasses.HOVER_CLASS, false);
+				});
+			}
+		}
+	}
+
+	public PadContentConnect getSelectedConnect() {
+		return selectedConnect;
+	}
+
+	public void hide() {
+		outTransition.play();
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/view/MapperOverviewViewController.java b/PlayWall/src/de/tobias/playpad/view/MapperOverviewViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..5174571a9eb60fc7c40d33f6428c9317d6c79a7e
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/view/MapperOverviewViewController.java
@@ -0,0 +1,161 @@
+package de.tobias.playpad.view;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.mapper.Mapper;
+import de.tobias.playpad.action.mapper.MapperRegistry;
+import de.tobias.playpad.action.mapper.MapperViewController;
+import de.tobias.playpad.viewcontroller.IMapperOverviewViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import javafx.scene.Parent;
+import javafx.scene.control.Button;
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+
+public class MapperOverviewViewController implements IMapperOverviewViewController {
+
+	private VBox root;
+	private VBox mappingView;
+	private HBox addMappingBox;
+
+	private Action action;
+	private List<MapperViewController> controllers;
+
+	private List<MapperAddListener> addListeners;
+
+	private Pane parent;
+	private ScrollPane scrollPane;
+
+	public MapperOverviewViewController() {
+		controllers = new ArrayList<>();
+		addListeners = new ArrayList<>();
+
+		init();
+	}
+
+	public void init() {
+		root = new VBox(14);
+
+		mappingView = new VBox();
+		mappingView.setSpacing(14);
+
+		addMappingBox = new HBox(14);
+
+		Label headline = new Label(PlayPadMain.getUiResourceBundle().getString("action.mapper.headline"));
+		headline.setUnderline(true);
+		root.getChildren().addAll(headline, mappingView, addMappingBox);
+
+		Set<String> types = MapperRegistry.getTypes();
+		types.stream().sorted().forEach(item ->
+		{
+			Button button = new Button(MapperRegistry.getMapperConnect(item).toString(), new FontIcon(FontAwesomeType.PLUS_CIRCLE));
+			button.setContentDisplay(ContentDisplay.TOP);
+			button.setPrefWidth(150);
+
+			button.setOnAction(e ->
+			{
+				// Adds a mapper to the action
+				MapperViewController controller = onAddMapper(item);
+				controller.showInputMapperUI();
+
+			});
+			addMappingBox.getChildren().add(button);
+		});
+	}
+
+	private MapperViewController onAddMapper(String type) {
+		Mapper mapper = MapperRegistry.getMapperConnect(type).createNewMapper();
+		action.addMapper(mapper);
+		return addMapperView(type, mapper);
+	}
+
+	private MapperViewController addMapperView(String type, Mapper mapper) {
+		MapperViewController controller = (MapperViewController) mapper.getSettingsViewController();
+		if (controller != null) {
+			Button deleteButton = new Button("", new FontIcon(FontAwesomeType.TRASH));
+
+			HBox hbox = new HBox(controller.getParent(), deleteButton);
+			hbox.setSpacing(14);
+
+			mappingView.getChildren().addAll(hbox);
+
+			deleteButton.setOnAction((e) ->
+			{
+				action.removeMapper(mapper);
+				mappingView.getChildren().removeAll(hbox);
+			});
+		}
+		controllers.add(controller);
+		addListeners.forEach(i -> i.onAdd(mapper, controller));
+		return controller;
+	}
+
+	@Override
+	public List<MapperViewController> getControllers() {
+		return controllers;
+	}
+
+	@Override
+	public Parent getParent() {
+		return root;
+	}
+
+	@Override
+	public void addMapperAddListener(MapperAddListener addListener) {
+		addListeners.add(addListener);
+	}
+
+	private void createSubViews(Action action) {
+		controllers.clear();
+		mappingView.getChildren().clear();
+
+		List<Mapper> mapperSorted = action.getMapperSorted();
+		for (int i = 0; i < mapperSorted.size(); i++) {
+			Mapper mapper = mapperSorted.get(i);
+			addMapperView(mapper.getType(), mapper);
+		}
+	}
+
+	@Override
+	public void showAction(Action action, Pane parent) {
+		this.action = action;
+
+		createSubViews(action);
+
+		if (this.parent != null) {
+			this.parent.getChildren().remove(getParent()); // Rmeove from old Parent
+		}
+		if (this.scrollPane != null) {
+			this.scrollPane.setContent(null);
+		}
+
+		this.parent = parent;
+		this.parent.getChildren().add(getParent()); // Add to new Parent
+	}
+
+	@Override
+	public void showAction(Action action, ScrollPane parent) {
+		this.action = action;
+
+		createSubViews(action);
+
+		if (this.parent != null) {
+			this.parent.getChildren().remove(getParent()); // Rmeove from old Parent
+		}
+		if (this.scrollPane != null) {
+			this.scrollPane.setContent(null);
+		}
+
+		this.scrollPane = parent;
+		this.scrollPane.setContent(getParent()); // Add to new Parent
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/view/MapperQuickSettingsView.java b/PlayWall/src/de/tobias/playpad/view/MapperQuickSettingsView.java
new file mode 100644
index 0000000000000000000000000000000000000000..095e711a9c10d6f16951a7946f87b22b3fd5c390
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/view/MapperQuickSettingsView.java
@@ -0,0 +1,58 @@
+package de.tobias.playpad.view;
+
+import java.util.List;
+
+import de.tobias.playpad.action.mapper.Mapper;
+import de.tobias.playpad.action.mapper.MapperRegistry;
+import de.tobias.playpad.action.mapper.MapperViewController;
+import de.tobias.playpad.pad.conntent.PadContentConnect;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.layout.Background;
+import javafx.scene.layout.BackgroundFill;
+import javafx.scene.layout.CornerRadii;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+
+public class MapperQuickSettingsView {
+
+	private VBox optionPane;
+	private Pane root;
+
+	public MapperQuickSettingsView(Pane pane) {
+		root = pane;
+
+		optionPane = new VBox();
+		optionPane.prefWidthProperty().bind(root.widthProperty());
+		optionPane.prefHeightProperty().bind(root.heightProperty());
+		optionPane.setBackground(new Background(new BackgroundFill(new Color(0.2, 0.2, 0.2, 0.8), new CornerRadii(10), new Insets(0))));
+		optionPane.setAlignment(Pos.CENTER);
+		optionPane.setPadding(new Insets(5));
+		optionPane.setSpacing(5);
+	}
+
+	private PadContentConnect selectedConnect;
+
+	public void showDropOptions(List<Mapper> mappers) {
+		if (!root.getChildren().contains(optionPane)) {
+			selectedConnect = null;
+
+			root.getChildren().add(optionPane);
+			optionPane.getChildren().clear();
+
+			for (Mapper mapper : mappers) {
+				MapperViewController controller = MapperRegistry.getMapperConnect(mapper.getType()).getQuickSettingsViewController(mapper);
+				optionPane.getChildren().add(controller.getParent());
+			}
+		}
+	}
+
+	public PadContentConnect getSelectedConnect() {
+		return selectedConnect;
+	}
+
+	public void hide() {
+		root.getChildren().remove(optionPane);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/view/PadDragOptionView.java b/PlayWall/src/de/tobias/playpad/view/PadDragOptionView.java
new file mode 100644
index 0000000000000000000000000000000000000000..16a64687ce031eac36fb3ccd1d14adc61cf7488e
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/view/PadDragOptionView.java
@@ -0,0 +1,155 @@
+package de.tobias.playpad.view;
+
+import java.util.Collection;
+
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.pad.drag.PadDragMode;
+import javafx.animation.FadeTransition;
+import javafx.animation.ParallelTransition;
+import javafx.animation.ScaleTransition;
+import javafx.animation.Transition;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.control.Label;
+import javafx.scene.layout.Background;
+import javafx.scene.layout.BackgroundFill;
+import javafx.scene.layout.CornerRadii;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Priority;
+import javafx.scene.paint.Color;
+import javafx.scene.text.TextAlignment;
+
+public class PadDragOptionView {
+
+	private HBox optionPane;
+	private Pane parent;
+
+	private Transition inTransition;
+	private Transition outTransition;
+
+	public PadDragOptionView(Pane pane) {
+		parent = pane;
+
+		optionPane = new HBox();
+		optionPane.prefWidthProperty().bind(parent.widthProperty());
+		optionPane.prefHeightProperty().bind(parent.heightProperty());
+		optionPane.setBackground(new Background(new BackgroundFill(new Color(0.2, 0.2, 0.2, 0.8), new CornerRadii(10), new Insets(0))));
+		optionPane.setAlignment(Pos.CENTER);
+		optionPane.setPadding(new Insets(5));
+		optionPane.setSpacing(5);
+
+		inTransition = createTransition(true);
+		outTransition = createTransition(false);
+
+	}
+
+	public Transition getInTransition() {
+		return inTransition;
+	}
+
+	public void setInTransition(Transition inTransition) {
+		this.inTransition = inTransition;
+	}
+
+	public Transition getOutTransition() {
+		return outTransition;
+	}
+
+	public void setOutTransition(Transition outTransition) {
+		this.outTransition = outTransition;
+	}
+
+	private Transition createTransition(boolean in) {
+		FadeTransition fadeTransition = new FadeTransition();
+		fadeTransition.setNode(optionPane);
+
+		ScaleTransition scaleTransition = new ScaleTransition();
+		scaleTransition.setNode(optionPane);
+
+		if (in) {
+			fadeTransition.setFromValue(0);
+			fadeTransition.setToValue(1);
+
+			scaleTransition.setFromX(1.3);
+			scaleTransition.setFromY(1.3);
+			scaleTransition.setToX(1);
+			scaleTransition.setToY(1);
+		} else {
+			fadeTransition.setFromValue(1);
+			fadeTransition.setToValue(0);
+
+			scaleTransition.setFromX(1);
+			scaleTransition.setFromY(1);
+			scaleTransition.setToX(1.3);
+			scaleTransition.setToY(1.3);
+		}
+
+		ParallelTransition parallelTransition = new ParallelTransition(fadeTransition, scaleTransition);
+
+		parallelTransition.setOnFinished((e) ->
+		{
+			if (!in)
+				parent.getChildren().remove(optionPane);
+		});
+		return parallelTransition;
+	}
+
+	private PadDragMode selectedConnect;
+
+	public void showDropOptions(Collection<PadDragMode> options) {
+		if (!parent.getChildren().contains(optionPane)) {
+			selectedConnect = null;
+
+			parent.getChildren().add(optionPane);
+			optionPane.getChildren().clear();
+
+			for (PadDragMode connect : options.stream().sorted().toArray(value -> new PadDragMode[value])) {
+				Label label = new Label();
+				label.getStyleClass().add("dnd-file-option");
+				label.textProperty().bind(connect.displayProperty());
+				Node graphics = connect.getGraphics();
+				if (graphics != null) {
+					graphics.setStyle("-fx-text-fill: white;");
+					label.setGraphic(graphics);
+				}
+				label.setWrapText(true);
+
+				label.setOnDragOver(e ->
+				{
+					label.pseudoClassStateChanged(PseudoClasses.HOVER_CLASS, true);
+					selectedConnect = connect;
+				});
+				label.setOnDragExited(e ->
+				{
+					label.pseudoClassStateChanged(PseudoClasses.HOVER_CLASS, false);
+					selectedConnect = null;
+				});
+
+				label.setUserData(connect);
+
+				label.setAlignment(Pos.CENTER);
+				label.setTextAlignment(TextAlignment.CENTER);
+				label.setContentDisplay(ContentDisplay.TOP);
+
+				label.maxWidthProperty().bind(optionPane.widthProperty().divide(options.size()).subtract(12.5));
+				label.setMaxHeight(Double.MAX_VALUE);
+				HBox.setHgrow(label, Priority.ALWAYS);
+
+				optionPane.getChildren().add(label);
+			}
+
+			inTransition.play();
+		}
+	}
+
+	public PadDragMode getSelectedPadDragMode() {
+		return selectedConnect;
+	}
+
+	public void hide() {
+		outTransition.play();
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/view/PadView.java b/PlayWall/src/de/tobias/playpad/view/PadView.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab24ea66cd1532538280e52f8823829f86954686
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/view/PadView.java
@@ -0,0 +1,364 @@
+package de.tobias.playpad.view;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
+import de.tobias.playpad.pad.conntent.Pauseable;
+import de.tobias.playpad.pad.conntent.UnkownPadContentException;
+import de.tobias.playpad.pad.view.IPadContentView;
+import de.tobias.playpad.pad.view.IPadViewController;
+import de.tobias.playpad.viewcontroller.IPadView;
+import de.tobias.playpad.viewcontroller.pad.PadViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.ui.scene.BusyView;
+import javafx.css.PseudoClass;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ProgressBar;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+
+public class PadView extends StackPane implements IPadView {
+
+	private Label indexLabel;
+	private Label loopLabel;
+	private Label triggerLabel;
+	private Label messageLabel;
+
+	private HBox infoBox;
+	private Label timeLabel;
+
+	private HBox preview;
+	private IPadContentView previewContent;
+
+	private ProgressBar playBar;
+	private Button playButton;
+	private Button pauseButton;
+	private Button stopButton;
+	private Button newButton;
+	private Button settingsButton;
+	private HBox buttonBox;
+
+	private VBox root;
+	private BusyView busyView;
+
+	private transient PadViewController controller; // Reference to its controller
+
+	public PadView(PadViewController controller) {
+		this.controller = controller;
+
+		root = new VBox();
+		busyView = new BusyView(this);
+
+		indexLabel = new Label();
+
+		loopLabel = new Label(); // Active über Visible
+		loopLabel.setGraphic(new FontIcon(FontAwesomeType.REPEAT));
+
+		triggerLabel = new Label();
+		triggerLabel.setGraphic(new FontIcon(FontAwesomeType.EXTERNAL_LINK));
+
+		messageLabel = new Label();
+		messageLabel.setGraphic(new FontIcon(FontAwesomeType.WARNING));
+
+		timeLabel = new Label();
+
+		infoBox = new HBox(); // childern in addDefaultButton()
+		infoBox.setSpacing(5);
+
+		preview = new HBox();
+		HBox.setHgrow(preview, Priority.ALWAYS);
+		VBox.setVgrow(preview, Priority.ALWAYS);
+
+		HBox.setHgrow(timeLabel, Priority.ALWAYS);
+		timeLabel.setMaxWidth(Double.MAX_VALUE);
+		timeLabel.setAlignment(Pos.CENTER_RIGHT);
+
+		playBar = new ProgressBar(0);
+		playBar.prefWidthProperty().bind(root.widthProperty());
+
+		// Buttons
+		playButton = new Button("", new FontIcon(FontAwesomeType.PLAY));
+		playButton.setFocusTraversable(false);
+		playButton.setOnAction(controller);
+		pauseButton = new Button("", new FontIcon(FontAwesomeType.PAUSE));
+		pauseButton.setFocusTraversable(false);
+		pauseButton.setOnAction(controller);
+		stopButton = new Button("", new FontIcon(FontAwesomeType.STOP));
+		stopButton.setFocusTraversable(false);
+		stopButton.setOnAction(controller);
+		newButton = new Button("", new FontIcon(FontAwesomeType.FOLDER_OPEN));
+		newButton.setFocusTraversable(false);
+		newButton.setOnAction(controller);
+		settingsButton = new Button("", new FontIcon(FontAwesomeType.GEAR));
+		settingsButton.setFocusTraversable(false);
+		settingsButton.setOnAction(controller);
+
+		// Button HBOX
+		buttonBox = new HBox(); // childern in addDefaultButton()
+
+		root.getChildren().addAll(infoBox, preview, playBar, buttonBox);
+		getChildren().addAll(root);
+	}
+
+	// wird über den Status listener gesteuert
+	public void setErrorLabelActive(boolean active) {
+		messageLabel.setVisible(active);
+	}
+
+	public void setTriggerLabelActive(boolean active) {
+		triggerLabel.setVisible(active);
+	}
+
+	public Label getIndexLabel() {
+		return indexLabel;
+	}
+
+	public Label getTimeLabel() {
+		return timeLabel;
+	}
+
+	public ProgressBar getPlayBar() {
+		return playBar;
+	}
+
+	public Button getPlayButton() {
+		return playButton;
+	}
+
+	public Button getPauseButton() {
+		return pauseButton;
+	}
+
+	public Button getStopButton() {
+		return stopButton;
+	}
+
+	public Button getNewButton() {
+		return newButton;
+	}
+
+	public Button getSettingsButton() {
+		return settingsButton;
+	}
+
+	public HBox getButtonBox() {
+		return buttonBox;
+	}
+
+	public HBox getInfoBox() {
+		return infoBox;
+	}
+
+	public IPadViewController getController() {
+		return controller;
+	}
+
+	public Label getLoopLabel() {
+		return loopLabel;
+	}
+
+	public Label getErrorLabel() {
+		return messageLabel;
+	}
+
+	public VBox getRoot() {
+		return root;
+	}
+
+	public void setPreviewContent(Pad pad) {
+		if (previewContent != null) {
+			previewContent.unconnect();
+		}
+
+		if (pad != null) {
+			PadContent content = pad.getContent();
+			if (content != null) {
+				try {
+					previewContent = PadContentRegistry.getPadContentConnect(content.getType()).getPadContentPreview(pad, preview);
+					Node node = previewContent.getNode();
+
+					node.getStyleClass().addAll("pad-title", "pad" + pad.getIndex() + "-title");
+					preview.getChildren().setAll(node);
+					return;
+				} catch (UnkownPadContentException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		EmptyPadView view = new EmptyPadView(preview);
+		if (pad != null) {
+			view.getStyleClass().addAll("pad-title", "pad" + pad.getIndex() + "-title");
+		} else {
+			view.getStyleClass().addAll("pad-title");
+		}
+		preview.getChildren().setAll(view);
+	}
+
+	public void clearPreviewContent() {
+		if (previewContent != null) {
+			previewContent.unconnect();
+		}
+		setPreviewContent(null);
+	}
+
+	public void addDefaultButton(Pad pad) {
+		if (pad != null) {
+			if (pad.getContent() != null) {
+				if (pad.getContent() instanceof Pauseable) {
+					buttonBox.getChildren().setAll(playButton, pauseButton, stopButton, newButton, settingsButton);
+				} else {
+					buttonBox.getChildren().setAll(playButton, stopButton, newButton, settingsButton);
+				}
+			} else {
+				buttonBox.getChildren().setAll(newButton, settingsButton);
+			}
+		}
+		infoBox.getChildren().setAll(indexLabel, loopLabel, triggerLabel, messageLabel, timeLabel);
+
+		// Buttons unten Full Width
+		buttonBox.prefWidthProperty().bind(widthProperty());
+		for (Node child : buttonBox.getChildren()) {
+			if (child instanceof Region) {
+				HBox.setHgrow(child, Priority.ALWAYS);
+				((Region) child).setMaxWidth(Double.MAX_VALUE);
+			}
+		}
+
+		// alle Labels in der InfoBox sollen die gleiche Höhe haben, damit die Icons auf gleicher höhe sind
+		for (Node child : infoBox.getChildren()) {
+			if (child instanceof Label) {
+				((Label) child).setMaxHeight(Double.MAX_VALUE);
+			}
+		}
+	}
+
+	public void setBusy(boolean busy) {
+		busyView.showProgress(busy);
+	}
+
+	public void pseudoClassState(PseudoClass pseudoClass, boolean active) {
+		pseudoClassStateChanged(pseudoClass, active);
+		indexLabel.pseudoClassStateChanged(pseudoClass, active);
+		timeLabel.pseudoClassStateChanged(pseudoClass, active);
+		loopLabel.getGraphic().pseudoClassStateChanged(pseudoClass, active);
+		triggerLabel.getGraphic().pseudoClassStateChanged(pseudoClass, active);
+		messageLabel.getGraphic().pseudoClassStateChanged(pseudoClass, active);
+
+		if (preview != null) {
+			preview.getChildren().forEach(i -> i.pseudoClassStateChanged(pseudoClass, active));
+		}
+
+		playBar.pseudoClassStateChanged(pseudoClass, active);
+
+		playButton.getGraphic().pseudoClassStateChanged(pseudoClass, active);
+		pauseButton.getGraphic().pseudoClassStateChanged(pseudoClass, active);
+		stopButton.getGraphic().pseudoClassStateChanged(pseudoClass, active);
+		newButton.getGraphic().pseudoClassStateChanged(pseudoClass, active);
+		settingsButton.getGraphic().pseudoClassStateChanged(pseudoClass, active);
+	}
+
+	public void addStyleClasses(Pad pad) {
+		getStyleClass().addAll("pad", "pad" + pad.getIndex());
+
+		indexLabel.getStyleClass().addAll("pad-index", "pad" + pad.getIndex() + "-index", "pad-info", "pad" + pad.getIndex() + "-info");
+		timeLabel.getStyleClass().addAll("pad-time", "pad" + pad.getIndex() + "-time", "pad-info", "pad" + pad.getIndex() + "-info");
+		loopLabel.getGraphic().getStyleClass().addAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon",
+				"pad" + pad.getIndex() + "-icon");
+		triggerLabel.getGraphic().getStyleClass().addAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon",
+				"pad" + pad.getIndex() + "-icon");
+		messageLabel.getGraphic().getStyleClass().addAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon",
+				"pad" + pad.getIndex() + "-icon");
+
+		preview.getChildren().forEach(i -> i.getStyleClass().addAll("pad-title", "pad" + pad.getIndex() + "-title"));
+
+		playBar.getStyleClass().addAll("pad-playbar", "pad" + pad.getIndex() + "-playbar");
+
+		playButton.getStyleClass().addAll("pad-button", "pad-playbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-playbutton");
+		pauseButton.getStyleClass().addAll("pad-button", "pad-pausebutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-pausebutton");
+		stopButton.getStyleClass().addAll("pad-button", "pad-stopbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-stopbutton");
+		newButton.getStyleClass().addAll("pad-button", "pad-newbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-newbutton");
+		settingsButton.getStyleClass().addAll("pad-button", "pad-settingsbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-settingsbutton");
+
+		playButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-playbutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-playbutton-icon");
+		pauseButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-pausebutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-pausebutton-icon");
+		stopButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-stopbutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-stopbutton-icon");
+		newButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-newbutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-newbutton-icon");
+		settingsButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-deletebutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-settingsbutton-icon");
+
+		getButtonBox().getStyleClass().add("pad-button-box");
+		getRoot().getStyleClass().add("pad-root");
+	}
+
+	public void removeStyleClasses(Pad pad) {
+		getStyleClass().removeAll("pad", "pad" + pad.getIndex());
+
+		indexLabel.getStyleClass().removeAll("pad-index", "pad" + pad.getIndex() + "-index", "pad-info", "pad" + pad.getIndex() + "-info");
+		timeLabel.getStyleClass().removeAll("pad-time", "pad" + pad.getIndex() + "-time", "pad-info", "pad" + pad.getIndex() + "-info");
+		loopLabel.getGraphic().getStyleClass().removeAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon",
+				"pad" + pad.getIndex() + "-icon");
+		triggerLabel.getGraphic().getStyleClass().removeAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon",
+				"pad" + pad.getIndex() + "-icon");
+		messageLabel.getGraphic().getStyleClass().removeAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon",
+				"pad" + pad.getIndex() + "-icon");
+
+		preview.getChildren().forEach(i -> i.getStyleClass().removeAll("pad-title", "pad" + pad.getIndex() + "-title"));
+
+		playBar.getStyleClass().removeAll("pad-playbar", "pad" + pad.getIndex() + "-playbar");
+
+		playButton.getStyleClass().removeAll("pad-button", "pad-playbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-playbutton");
+		pauseButton.getStyleClass().removeAll("pad-button", "pad-pausebutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-pausebutton");
+		stopButton.getStyleClass().removeAll("pad-button", "pad-stopbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-stopbutton");
+		newButton.getStyleClass().removeAll("pad-button", "pad-newbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-newbutton");
+		settingsButton.getStyleClass().removeAll("pad-button", "pad-settingsbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-settingsbutton");
+
+		playButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-playbutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-playbutton-icon");
+		pauseButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-pausebutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-pausebutton-icon");
+		stopButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-stopbutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-stopbutton-icon");
+		newButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-newbutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-newbutton-icon");
+		settingsButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-deletebutton-icon", "pad" + pad.getIndex() + "-icon",
+				"pad" + pad.getIndex() + "-settingsbutton-icon");
+
+		getButtonBox().getStyleClass().add("pad-button-box");
+		getRoot().getStyleClass().add("pad-root");
+	}
+
+	public void showPlaybar(boolean b) {
+		if (b) {
+			if (!root.getChildren().contains(playBar))
+				root.getChildren().add(2, playBar);
+		} else {
+			root.getChildren().remove(playBar);
+		}
+	}
+
+	@Override
+	public IPadContentView getPadContentView() {
+		return previewContent;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ce4507fbd74551a1bf6eebab8660fe64b88b5c5
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java
@@ -0,0 +1,229 @@
+package de.tobias.playpad.viewcontroller;
+
+import java.io.File;
+import java.nio.file.Path;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.project.ProfileChooseable;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.ProjectImporter;
+import de.tobias.playpad.project.ProjectNotFoundException;
+import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileNotFoundException;
+import de.tobias.playpad.viewcontroller.cell.ProjectCell;
+import de.tobias.playpad.viewcontroller.dialog.ImportDialog;
+import de.tobias.playpad.viewcontroller.dialog.NewProjectDialog;
+import de.tobias.playpad.viewcontroller.dialog.ProfileChooseDialog;
+import de.tobias.utils.application.App;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.Worker;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListView;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseButton;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+
+public class LaunchDialog extends ViewController implements ProfileChooseable {
+
+	private static final String IMAGE = "icon.png";
+
+	@FXML private Label infoLabel;
+	@FXML private ImageView imageView;
+
+	@FXML private ListView<ProjectReference> projectListView;
+
+	@FXML private Button newProfileButton;
+	@FXML private Button importProfileButton;
+	@FXML private Button openButton;
+	@FXML private Button deleteButton;
+
+	public LaunchDialog(Stage stage) {
+		super("launchDialog", "de/tobias/playpad/assets/dialog/", stage, null, PlayPadMain.getUiResourceBundle());
+		projectListView.getItems().addAll(ProjectReference.getProjectsSorted());
+	}
+
+	@Override
+	public void init() {
+		App app = ApplicationUtils.getApplication();
+		infoLabel.setText(Localization.getString(Strings.UI_Dialog_Launch_Info, app.getInfo().getName(), app.getInfo().getVersion()));
+		try {
+			imageView.setImage(new Image(IMAGE));
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		openButton.setDisable(true);
+		deleteButton.setDisable(true);
+
+		projectListView.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_Project)));
+		projectListView.setId("list");
+		projectListView.setCellFactory(list -> new ProjectCell());
+
+		projectListView.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			openButton.setDisable(c == null);
+			deleteButton.setDisable(c == null);
+		});
+
+		// Mouse Double Click on list
+		projectListView.setOnMouseClicked(mouseEvent ->
+		{
+			if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
+				if (mouseEvent.getClickCount() == 2) {
+					if (!projectListView.getSelectionModel().isEmpty()) {
+						ProjectReference ref = projectListView.getSelectionModel().getSelectedItem();
+						launchProject(ref);
+					}
+				}
+			}
+		});
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		setCSS("style.css", "de/tobias/playpad/assets/");
+		setCSS("launchDialog_style.css", "de/tobias/playpad/assets/style/");
+
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_Launch_Title));
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setOnCloseRequest(e ->
+		{
+			Worker.shutdown();
+		});
+
+		stage.setResizable(false);
+		stage.setWidth(650);
+		stage.show();
+	}
+
+	@FXML
+	private void newProfileButtonHandler(ActionEvent event) {
+		NewProjectDialog dialog = new NewProjectDialog(getStage());
+		dialog.getStage().showAndWait();
+
+		Project project = dialog.getProject();
+		if (project != null) {
+			PlayPadMain.launchProject(project);
+			getStage().close();
+		}
+	}
+
+	@FXML
+	private void importProfileButtonHandler(ActionEvent event) {
+		FileChooser chooser = new FileChooser();
+		chooser.getExtensionFilters()
+				.add(new ExtensionFilter(Localization.getString(Strings.File_Filter_ZIP), PlayPadMain.projectCompressedType));
+		File file = chooser.showOpenDialog(getStage());
+		if (file != null) {
+			Path zipFile = file.toPath();
+			try {
+				ProjectReference ref = ProjectImporter.importProject(zipFile, ImportDialog.getInstance(getStage()),
+						ImportDialog.getInstance(getStage()));
+				if (ref != null) {
+					launchProject(ref);
+				}
+			} catch (Exception e) {
+				showErrorMessage(Localization.getString(Strings.Error_Project_Open, e.getLocalizedMessage()));
+				e.printStackTrace();
+			}
+		}
+	}
+
+	@FXML
+	private void openButtonHandler(ActionEvent event) {
+		ProjectReference ref = projectListView.getSelectionModel().getSelectedItem();
+		try {
+			if (ref != null) {
+				Project project = Project.load(ref, true, this);
+				PlayPadMain.launchProject(project);
+				getStage().close();
+			}
+		} catch (ProfileNotFoundException e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Profile_NotFound, ref.getProfileReference(), e.getLocalizedMessage()));
+
+			// Neues Profile wählen
+			Profile profile = getUnkownProfile();
+			ref.setProfileReference(profile.getRef());
+		} catch (ProjectNotFoundException e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Project_NotFound, ref, e.getLocalizedMessage()));
+		} catch (Exception e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Project_Open, ref, e.getLocalizedMessage()));
+		}
+	}
+
+	@FXML
+	private void deleteButtonHandler(ActionEvent event) {
+		if (projectListView.getSelectionModel().getSelectedItem() != null) {
+			ProjectReference ref = projectListView.getSelectionModel().getSelectedItem();
+
+			Alert alert = new Alert(AlertType.CONFIRMATION);
+			alert.setContentText(Localization.getString(Strings.UI_Dialog_ProjectManager_Delete_Content, ref));
+
+			Stage dialog = (Stage) alert.getDialogPane().getScene().getWindow();
+			PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add);
+			alert.initOwner(getStage());
+			alert.initModality(Modality.WINDOW_MODAL);
+
+			alert.showAndWait().filter(item -> item == ButtonType.OK).ifPresent(item ->
+			{
+				try {
+					ProjectReference.removeDocument(ref);
+					projectListView.getItems().remove(ref); // VIEW
+				} catch (Exception e) {
+					showErrorMessage(Localization.getString(Strings.Error_Project_Delete, e.getLocalizedMessage()));
+				}
+			});
+		}
+	}
+
+	private void launchProject(ProjectReference ref) {
+		try {
+			Project project = Project.load(ref, true, this);
+			PlayPadMain.launchProject(project);
+			getStage().close();
+		} catch (ProfileNotFoundException e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Profile_NotFound, ref.getProfileReference(), e.getLocalizedMessage()));
+
+			// Neues Profile wählen
+			Profile profile = getUnkownProfile();
+			ref.setProfileReference(profile.getRef());
+		} catch (ProjectNotFoundException e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Project_NotFound, ref, e.getLocalizedMessage()));
+		} catch (Exception e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Project_Open, ref, e.getLocalizedMessage()));
+		}
+	}
+
+	@Override
+	public Profile getUnkownProfile() {
+		ProfileChooseDialog dialog = new ProfileChooseDialog(getStage());
+
+		dialog.getStage().showAndWait();
+		Profile profile = dialog.getProfile();
+		if (profile != null) {
+			return profile;
+		}
+		return null;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/PadSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/PadSettingsViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..40fa82395914da4674ac45e6fe85d705a4129219
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/PadSettingsViewController.java
@@ -0,0 +1,305 @@
+package de.tobias.playpad.viewcontroller;
+
+import java.awt.Desktop;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Optional;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.mididevice.Device;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.midi.device.DisplayableDevice;
+import de.tobias.playpad.model.layout.CartLayout;
+import de.tobias.playpad.model.layout.LayoutRegistry;
+import de.tobias.playpad.pad.Fade;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.Pad.TimeMode;
+import de.tobias.playpad.pad.Warning;
+import de.tobias.playpad.pad.view.PadViewController;
+import de.tobias.playpad.plugin.PlayPadPlugin;
+import de.tobias.playpad.plugin.viewcontroller.CartLayoutViewController;
+import de.tobias.playpad.plugin.viewcontroller.IPadSettingsViewController;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.cell.TimeModeCell;
+import de.tobias.playpad.viewcontroller.settings.FadeViewController;
+import de.tobias.playpad.viewcontroller.settings.WarningFeedbackViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Slider;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyCode;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+// TODO Renew this class
+public class PadSettingsViewController extends ViewController implements IPadSettingsViewController {
+
+	@FXML private TabPane tabPane;
+
+	@FXML private TextField titleTextField;
+	@FXML private Slider volumeSlider;
+	@FXML private CheckBox repeatCheckBox;
+
+	@FXML private CheckBox customTimeDisplayCheckBox;
+	@FXML private ComboBox<TimeMode> timeDisplayComboBox;
+
+	@FXML private CheckBox customFadeCheckBox;
+	@FXML private AnchorPane fadeContainer;
+	private FadeViewController fadeViewController;
+
+	@FXML private AnchorPane layoutAnchorPane;
+	@FXML private CheckBox enableLayoutCheckBox;
+	private CartLayoutViewController layoutViewController;
+
+	@FXML private AnchorPane warningFeedbackContainer;
+	@FXML private CheckBox warningEnableCheckBox;
+
+	@FXML private Button deleteButton;
+	@FXML private Button folderButton;
+	@FXML private Button finishButton;
+
+	private Pad pad;
+	private PadViewController controller;
+
+	public PadSettingsViewController(Pad pad, PadViewController controller, Window owner) {
+		super("padSettingsView", "de/tobias/playpad/assets/settings/", null, PlayPadMain.getUiResourceBundle());
+		this.pad = pad;
+		this.controller = controller;
+
+		// Listener
+		PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onInit(this));
+
+		getStage().initOwner(owner);
+
+		titleTextField.setText(pad.getTitle());
+		volumeSlider.setValue(pad.getVolume() * 100);
+		if (pad.isCustomFade())
+			fadeViewController.setFade(pad.getFade().get());
+
+		repeatCheckBox.setSelected(pad.isLoop());
+
+		customTimeDisplayCheckBox.setSelected(pad.isCustomTimeMode());
+		if (!pad.isCustomTimeMode()) {
+			timeDisplayComboBox.setDisable(true);
+		}
+		timeDisplayComboBox.setValue(pad.getTimeMode().orElse(TimeMode.REST));
+
+		customFadeCheckBox.setSelected(pad.isCustomFade());
+		if (!pad.isCustomFade()) {
+			fadeContainer.setDisable(true);
+		}
+
+		enableLayoutCheckBox.setSelected(pad.isCustomLayout());
+		if (pad.isCustomLayout()) {
+			try {
+				String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType();
+				Optional<CartLayout> layoutOpt = pad.getLayout(layoutType);
+				if (layoutOpt.isPresent()) {
+					setLayoutController(LayoutRegistry.cartViewControllerInstance(layoutType, layoutOpt.get()));
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+				// TODO
+			}
+		}
+
+		warningEnableCheckBox.setSelected(pad.isCustomWarning());
+		warningEnableCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			if (c && !pad.isCustomWarning()) {
+				pad.setWarningFeedback(new Warning());
+				addWarningController();
+			} else if (b && pad.isCustomWarning()) {
+				pad.setWarningFeedback(null);
+				warningFeedbackContainer.getChildren().clear();
+			}
+		});
+
+		if (pad.isCustomWarning()) {
+			addWarningController();
+		}
+
+		if (!pad.isPadLoaded())
+			folderButton.setDisable(true);
+
+		getStage().getScene().setOnKeyReleased(ke ->
+		{
+			if (ke.isShortcutDown() && ke.getCode() == KeyCode.W) {
+				Platform.runLater(() -> finishButtonHandler(null));
+			}
+		});
+	}
+
+	private void addWarningController() {
+		Midi midi = Midi.getInstance();
+
+		ContentViewController controller = null;
+		if (midi.getMidiDevice().isPresent()) {
+			Device device = Midi.getInstance().getMidiDevice().get();
+			if (device instanceof DisplayableDevice) {
+				controller = ((DisplayableDevice) device).getWarnViewController(pad);
+			}
+		}
+
+		if (controller == null) {
+			controller = new WarningFeedbackViewController(pad);
+		}
+
+		if (controller != null) {
+			warningFeedbackContainer.getChildren().add(controller.getParent());
+			setAnchor(controller.getParent(), 0, 0, 0, 0);
+		}
+	}
+
+	@Override
+	public void init() {
+		// Listener
+		titleTextField.textProperty().addListener((a, b, c) -> pad.setTitle(c));
+
+		// Embed ViewController
+		fadeViewController = new FadeViewController();
+		fadeContainer.getChildren().add(fadeViewController.getParent());
+		setAnchor(fadeViewController.getParent(), 0.0, 0.0, 0.0, 0.0);
+
+		volumeSlider.valueProperty().addListener((a, b, c) -> pad.setVolume(c.doubleValue() / 100.0));
+		repeatCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			pad.setLoop(c);
+			if (controller != null)
+				controller.getView().setLoopLabelActive(c);
+		});
+
+		customTimeDisplayCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			timeDisplayComboBox.setDisable(!c);
+			if (c && !pad.isCustomTimeMode())
+				pad.setTimeMode(TimeMode.REST);
+			else if (b && pad.isCustomTimeMode())
+				pad.setTimeMode(null);
+
+		});
+		timeDisplayComboBox.getItems().addAll(TimeMode.values());
+		timeDisplayComboBox.valueProperty().addListener((a, b, c) ->
+		{
+			pad.setTimeMode(c);
+		});
+		timeDisplayComboBox.setButtonCell(new TimeModeCell());
+		timeDisplayComboBox.setCellFactory(list -> new TimeModeCell());
+
+		customFadeCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			fadeContainer.setDisable(!c);
+			if (c && !pad.isCustomFade())
+				pad.setFade(new Fade());
+			else if (!c && pad.isCustomFade())
+				pad.setFade(null);
+
+			if (c)
+				fadeViewController.setFade(pad.getFade().get());
+		});
+
+		enableLayoutCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			if (c && !pad.isCustomLayout()) {
+				try {
+					pad.setCustomLayout(true);
+					try {
+						String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType();
+						Optional<CartLayout> layoutOpt = pad.getLayout(layoutType);
+						if (layoutOpt.isPresent()) {
+							setLayoutController(LayoutRegistry.cartViewControllerInstance(layoutType, layoutOpt.get()));
+						}
+					} catch (Exception e) {
+						e.printStackTrace();
+						// TODO
+					}
+				} catch (Exception e) {
+					showErrorMessage(Localization.getString(Strings.Error_Standard_Gen, e.getLocalizedMessage()));
+					e.printStackTrace();
+				}
+			} else if (!c && pad.isCustomLayout()) {
+				pad.setCustomLayout(false);
+				setLayoutController(null);
+			}
+		});
+	}
+
+	private void setLayoutController(CartLayoutViewController cartLayoutViewController) {
+		if (layoutViewController != null)
+			layoutAnchorPane.getChildren().remove(layoutViewController.getParent());
+
+		if (cartLayoutViewController != null) {
+			layoutViewController = cartLayoutViewController;
+			layoutAnchorPane.getChildren().add(layoutViewController.getParent());
+			setAnchor(layoutViewController.getParent(), 0, 0, 0, 0);
+		}
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setMinWidth(650);
+		stage.setMinHeight(530);
+		stage.setTitle(Localization.getString(Strings.UI_Window_PadSettings_Title));
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	@FXML
+	private void deleteButtonHandler(ActionEvent event) {
+		pad.clearPad();
+		getStage().close();
+	}
+
+	@Override
+	public boolean closeRequest() {
+		if (layoutViewController != null) {
+			layoutViewController.save();
+		}
+		// Listener
+		PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onClose(this));
+		return true;
+	}
+
+	@FXML
+	private void folderButtonHandler(ActionEvent event) {
+		try {
+			Desktop.getDesktop().open(pad.getPath().toFile().getParentFile());
+		} catch (IOException | URISyntaxException e) {
+			showErrorMessage(Localization.getString(Strings.Error_Standard_Gen, e.getMessage()), PlayPadMain.stageIcon);
+			e.printStackTrace();
+		}
+	}
+
+	@FXML
+	private void finishButtonHandler(ActionEvent event) {
+		if (layoutViewController != null) {
+			layoutViewController.save();
+		}
+		// Listener
+		PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onClose(this));
+		getStage().close();
+	}
+
+	public Pad getPad() {
+		return pad;
+	}
+
+	public void addTab(String name, AnchorPane content) {
+		content.setMinSize(0, 0);
+		content.setMaxSize(AnchorPane.USE_COMPUTED_SIZE, AnchorPane.USE_COMPUTED_SIZE);
+		tabPane.getTabs().add(new Tab(name, content));
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7c5c2392c56c19f44221a126ade41210ebb54be
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java
@@ -0,0 +1,111 @@
+package de.tobias.playpad.viewcontroller;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import de.tobias.playpad.AppUserInfoStrings;
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.plugin.Plugin;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.cell.PluginCell;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.Worker;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListView;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+import net.xeoh.plugins.base.PluginManager;
+
+public class PluginViewController extends ViewController {
+
+	@FXML private ListView<Plugin> pluginListView;
+	@FXML private Button finishButton;
+
+	private PluginManager manager;
+
+	public PluginViewController(PluginManager manager, Window owner) {
+		super("pluginView", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
+		this.manager = manager;
+
+		getStage().initOwner(owner);
+		getStage().initModality(Modality.WINDOW_MODAL);
+
+		Worker.runLater(() ->
+		{
+			try {
+				List<Plugin> plugins = new ArrayList<>();
+
+				URL url = new URL(ApplicationUtils.getApplication().getInfo().getUserInfo().getString(AppUserInfoStrings.PLUGINS_URL));
+				FileConfiguration cfg = YamlConfiguration.loadConfiguration(url.openStream());
+
+				// Iterate over all plugins that are online avialable
+				for (String key : cfg.getConfigurationSection("plugins").getKeys(false)) {
+					String name = cfg.getString("plugins." + key + ".name");
+					String pluginUrl = cfg.getString("plugins." + key + ".url");
+					String fileName = cfg.getString("plugins." + key + ".filename");
+					boolean active = false;
+
+					try {
+						Path path = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, fileName);
+						if (Files.exists(path))
+							active = true;
+					} catch (Exception e) {
+						e.printStackTrace();
+						showErrorMessage(Localization.getString(Strings.Error_Plugins_Download, name), PlayPadMain.stageIcon);
+					}
+
+					Plugin plugin = new Plugin(name, fileName, pluginUrl, active);
+					plugins.add(plugin);
+				}
+
+				Collections.sort(plugins, (o1, o2) -> o1.getName().compareTo(o2.getName()));
+				pluginListView.getItems().addAll(plugins);
+			} catch (IOException e) {
+				e.printStackTrace();
+				showErrorMessage(Localization.getString(Strings.Error_Standard_Gen), PlayPadMain.stageIcon);
+			}
+		});
+	}
+
+	@Override
+	public void init() {
+		pluginListView.setCellFactory(list -> new PluginCell(manager));
+		pluginListView.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_Plugins)));
+
+		addCloseKeyShortcut(() -> getStage().close());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setMinWidth(550);
+		stage.setMaxWidth(550);
+		stage.setMinHeight(500);
+
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_Plugins_Title));
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	@FXML
+	private void finishButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+}
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/PresetsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/PresetsViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..27ce636e43cbf202d9cbb3b871b47ae8afcdfa71
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/PresetsViewController.java
@@ -0,0 +1,388 @@
+package de.tobias.playpad.viewcontroller;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.settings.MidiPreset;
+import de.tobias.playpad.settings.MidiSettings;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.cell.PresetCell;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.ui.NotificationHandler;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.ui.scene.NotificationPane;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListView;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class PresetsViewController extends ViewController implements NotificationHandler {
+
+	@FXML private AnchorPane presetsContainer;
+	@FXML private AnchorPane presetsAnchorPane;
+
+	@FXML private ListView<MidiPreset> presetsListView;
+
+	@FXML private TextField nameTextField;
+	@FXML private CheckBox partlyCheckBox;
+	@FXML private CheckBox activeCheckBox;
+	@FXML private TextField pageTextField;
+
+	@FXML private Button addButton;
+	@FXML private Button removeButton;
+	@FXML private Button importButton;
+	@FXML private Button exportButton;
+	@FXML private Button duplicateButton;
+	@FXML private Button defaultButton;
+
+	@FXML private Button finishButton;
+
+	private NotificationPane notificationPane;
+	private MidiSettings midiSettings;
+
+	public PresetsViewController(Window window) {
+		super("presetsView", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
+		getStage().initOwner(window);
+
+		presetsListView.setItems(midiSettings.getPresets());
+		for (MidiPreset preset : midiSettings.getPresets()) {
+			if (preset.isActive()) {
+				presetsListView.getSelectionModel().select(preset);
+				break;
+			}
+		}
+
+		if (midiSettings.getPresets().size() == 1) {
+			removeButton.setDisable(true);
+		}
+	}
+
+	@Override
+	public void init() {
+		notificationPane = new NotificationPane(presetsAnchorPane);
+		notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK);
+		presetsContainer.getChildren().add(notificationPane);
+		setAnchor(notificationPane, 0, 0, 0, 0);
+
+		presetsListView.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_Preset)));
+
+		// Ausgewählte in der Liste rechts zeigen und Button disablen
+		presetsListView.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			showPreset(c);
+			if (c == null) {
+				exportButton.setDisable(true);
+				if (midiSettings.getPresets().size() <= 1)
+					removeButton.setDisable(true);
+			} else {
+				removeButton.setDisable(false);
+				exportButton.setDisable(false);
+			}
+		});
+
+		// Name des Presets aktualisieren
+		nameTextField.textProperty().addListener((a, b, c) ->
+		{
+			MidiPreset item = getSelectedMidiPreset();
+			if (item != null) {
+				item.setName(c);
+			}
+		});
+
+		activeCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			MidiPreset preset = getSelectedMidiPreset();
+			if (c) {
+				disableInvalidPresets(true, getSelectedMidiPreset(), midiSettings);
+			}
+			if (preset != null) {
+				preset.setActive(c);
+			}
+		});
+
+		partlyCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			MidiPreset item = getSelectedMidiPreset();
+			if (item != null) {
+				item.setPartly(c);
+			}
+		});
+
+		pageTextField.textProperty().addListener((a, b, c) ->
+		{
+			MidiPreset preset = getSelectedMidiPreset();
+			if (preset != null) {
+				// Model Update
+				if (c.isEmpty()) {
+					preset.setPage(-1);
+				} else {
+					try {
+						int page = Integer.valueOf(c) - 1;
+						preset.setPage(page);
+						pageTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false);
+					} catch (NumberFormatException e) {
+						pageTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true);
+					}
+				}
+
+				// Kollision zeigen
+				if (preset.isActive()) {
+					disableInvalidPresets(false, getSelectedMidiPreset(), midiSettings);
+				}
+			}
+		});
+
+		presetsListView.setCellFactory(item -> new PresetCell());
+
+		getStage().getScene().getAccelerators().put(new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN),
+				() -> Platform.runLater(() -> getStage().close()));
+	}
+
+	public static List<MidiPreset> disableInvalidPresets(boolean disable, MidiPreset preset, MidiSettings midiSettings) {
+		List<MidiPreset> disabledPresets = new ArrayList<>();
+
+		// Neues Preset ist Global -> alle anderen weg
+		if (preset.getPage() == -1) {
+			for (MidiPreset item : midiSettings.getPresets()) {
+				if (item != preset) {
+					if (item.isActive()) {
+						if (disable) {
+							item.setActive(false);
+						}
+						disabledPresets.add(item);
+					}
+				}
+			}
+		} else {
+			for (MidiPreset item : midiSettings.getPresets()) {
+				if (item != preset) {
+					if (item.isActive() && item.getPage() == -1 || item.isActive() && item.getPage() == preset.getPage()) {
+						if (disable) {
+							item.setActive(false);
+						}
+						disabledPresets.add(item);
+					}
+				}
+			}
+		}
+		return disabledPresets;
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setMinWidth(600);
+		stage.setMinHeight(400);
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_Preset_Title));
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	private void showPreset(MidiPreset midiPreset) {
+		if (midiPreset != null) {
+			nameTextField.setText(midiPreset.getName());
+			activeCheckBox.setSelected(midiPreset.isActive());
+			partlyCheckBox.setSelected(midiPreset.isPartly());
+			if (midiPreset.getPage() != -1) {
+				pageTextField.setText(String.valueOf(midiPreset.getPage() + 1));
+			} else {
+				pageTextField.clear();
+			}
+			activeCheckBox.setDisable(false);
+			partlyCheckBox.setDisable(false);
+		} else {
+			nameTextField.setText(null);
+			activeCheckBox.setSelected(false);
+			partlyCheckBox.setSelected(false);
+			pageTextField.clear();
+			activeCheckBox.setDisable(true);
+			partlyCheckBox.setDisable(true);
+		}
+	}
+
+	@FXML
+	private void addButtonHandler(ActionEvent event) {
+		MidiPreset preset = new MidiPreset();
+		midiSettings.getPresets().add(preset);
+		if (midiSettings.getPresets().size() > 1) {
+			removeButton.setDisable(false);
+		}
+		presetsListView.getSelectionModel().select(preset);
+	}
+
+	@FXML
+	private void removeButtonHandler(ActionEvent event) {
+		midiSettings.getPresets().remove(presetsListView.getSelectionModel().getSelectedIndex());
+		if (midiSettings.getPresets().size() == 1) {
+			removeButton.setDisable(true);
+		}
+	}
+
+	@FXML
+	private void finishButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+
+	@FXML
+	private void importButtonHandler(ActionEvent event) {
+		FileChooser chooser = new FileChooser();
+		chooser.getExtensionFilters().add(new ExtensionFilter(Localization.getString(Strings.File_Filter_Preset), PlayPadMain.midiPresetType));
+		File file = chooser.showOpenDialog(getStage());
+		if (file != null) {
+			Path path = file.toPath();
+
+			Worker.runLater(() ->
+			{
+				try {
+					MidiPreset preset = midiSettings.importMidiPreset(path);
+					preset.setActive(false); // DEFAULT nicht Active
+					Platform.runLater(() ->
+					{
+						if (midiSettings.getPresets().size() == 1) {
+							removeButton.setDisable(true);
+						} else {
+							removeButton.setDisable(false);
+						}
+
+						notify(Localization.getString(Strings.Standard_File_Save), PlayPadMain.notificationDisplayTimeMillis);
+					});
+
+				} catch (Exception e) {
+					e.printStackTrace();
+					showErrorMessage(Localization.getString(Strings.Error_Preset_Import, e.getLocalizedMessage()));
+				}
+			});
+		}
+	}
+
+	@FXML
+	private void exportButtonHandler(ActionEvent event) {
+		MidiPreset preset = getSelectedMidiPreset();
+		if (preset != null) {
+			FileChooser chooser = new FileChooser();
+
+			ExtensionFilter filter = new ExtensionFilter(Localization.getString(Strings.File_Filter_Preset), PlayPadMain.midiPresetType);
+			chooser.getExtensionFilters().add(filter);
+
+			File file = chooser.showSaveDialog(getStage());
+			if (file != null) {
+				Path path = file.toPath();
+
+				Worker.runLater(() ->
+				{
+					try {
+						midiSettings.exportMidiPreset(path, preset);
+						notify(Localization.getString(Strings.Standard_File_Save), PlayPadMain.notificationDisplayTimeMillis);
+					} catch (IOException e) {
+						e.printStackTrace();
+						showErrorMessage(Localization.getString(Strings.Error_Preset_Export, e.getLocalizedMessage()));
+					}
+				});
+			}
+		}
+	}
+
+	private MidiPreset getSelectedMidiPreset() {
+		return presetsListView.getSelectionModel().getSelectedItem();
+	}
+
+	@FXML
+	private void duplicateButtonHandler() {
+		MidiPreset preset = getSelectedMidiPreset();
+		try {
+			MidiPreset preset2 = preset.clone();
+			preset2.setName(Localization.getString(Strings.Standard_Copy, preset2.getName()));
+			preset2.setActive(false);
+
+//			Profile.currentProfile().getMidiSetting().getPresets().add(preset2);
+			presetsListView.getSelectionModel().select(preset2);
+		} catch (CloneNotSupportedException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@FXML
+	private void defaultButtonHandler() {
+		Alert alert = new Alert(AlertType.CONFIRMATION);
+
+		Stage dialog = (Stage) alert.getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add);
+		alert.initOwner(getStage());
+		alert.initModality(Modality.WINDOW_MODAL);
+
+		alert.setContentText(Localization.getString(Strings.Info_Settings_Preset_RestoreDefaults));
+		alert.showAndWait().filter(button -> button == ButtonType.OK).ifPresent(button ->
+		{
+			try {
+				Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, Profile.currentProfile().getName(), "Midi.xml");
+				midiSettings.createDefaultSettings(path);
+			} catch (Exception e) {
+				e.printStackTrace();
+				showErrorMessage(Localization.getString(Strings.Error_Preset_RestoreDefaults, e.getLocalizedMessage()));
+			}
+		});
+	}
+
+	// UI Info
+	@Override
+	public void notify(String text, long duration) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showAndHide(text, duration);
+		} else {
+			Platform.runLater(() -> notificationPane.showAndHide(text, duration));
+		}
+	}
+
+	@Override
+	public void notify(String text, long duration, Runnable finish) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showAndHide(text, duration, finish);
+		} else {
+			Platform.runLater(() -> notificationPane.showAndHide(text, duration, finish));
+		}
+	}
+
+	@Override
+	public void showError(String message) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showError(message);
+		} else {
+			Platform.runLater(() -> notificationPane.showError(message));
+		}
+	}
+
+	@Override
+	public void hide() {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.hide();
+		} else {
+			Platform.runLater(() -> notificationPane.hide());
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/PrintDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/PrintDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..4b88bd8e0cdcbdd10d5c9f5de79ba57e85432bcf
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/PrintDialog.java
@@ -0,0 +1,142 @@
+package de.tobias.playpad.viewcontroller;
+
+import com.hp.gagawa.java.elements.Body;
+import com.hp.gagawa.java.elements.Div;
+import com.hp.gagawa.java.elements.H1;
+import com.hp.gagawa.java.elements.Html;
+import com.hp.gagawa.java.elements.Table;
+import com.hp.gagawa.java.elements.Td;
+import com.hp.gagawa.java.elements.Tr;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.print.PageLayout;
+import javafx.print.PageOrientation;
+import javafx.print.Paper;
+import javafx.print.Printer;
+import javafx.print.Printer.MarginType;
+import javafx.print.PrinterJob;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.web.WebEngine;
+import javafx.scene.web.WebView;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class PrintDialog extends ViewController {
+
+	@FXML private WebView webView;
+	@FXML private ComboBox<Integer> pageComboBox;
+	@FXML private Button printButton;
+	@FXML private Button cancelButton;
+
+	private Project project;
+
+	public PrintDialog(Project project, Window owner) {
+		super("printDialog", "de/tobias/playpad/assets/dialog/project/", null, PlayPadMain.getUiResourceBundle());
+		this.project = project;
+
+		pageComboBox.getSelectionModel().selectFirst();
+
+		getStage().initOwner(owner);
+	}
+
+	@Override
+	public void init() {
+		int pages = Profile.currentProfile().getProfileSettings().getPageCount();
+		for (int i = 0; i < pages; i++) {
+			pageComboBox.getItems().add(i + 1);
+		}
+
+		pageComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			createPreview(c - 1);
+		});
+
+		addCloseKeyShortcut(() -> getStage().close());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setMinWidth(600);
+		stage.setMinHeight(400);
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_Print_Title));
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	private void createPreview(int page) {
+		Html html = new Html();
+		Body body = new Body();
+		body.setStyle("max-width: 1000px; font-family: sans-serif;");
+		html.appendChild(body);
+
+		H1 header = new H1();
+
+		String headerString = Localization.getString(Strings.Info_Print_Header, project.getRef().getName(), page + 1);
+		header.appendText(headerString);
+		header.setStyle("text-align: center;");
+		body.appendChild(header);
+
+		Table table = new Table();
+		table.setStyle("border:1px solid black;border-collapse:collapse;");
+		ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings();
+
+		int i = page * profilSettings.getRows() * profilSettings.getColumns();
+
+		for (int y = 0; y < profilSettings.getRows(); y++) {
+			Tr tr = new Tr();
+			table.appendChild(tr);
+			for (int x = 0; x < profilSettings.getColumns(); x++) {
+				Td td = new Td();
+				td.setStyle("border:1px solid black; width: " + 1000 / (float) profilSettings.getColumns()
+						+ "px; padding: 5px; vertical-align: center; text-align: center; min-height: 30px; min-width: 100px;");
+				Div div = new Div();
+				div.setStyle("word-break: break-all; white-space: normal;");
+				Pad pad = this.project.getPad(i);
+
+				if (pad.getContent() != null && pad.getContent().isPadLoaded())
+					div.appendText(pad.getName());
+				else
+					div.appendText("-");
+				td.appendChild(div);
+				i++;
+				tr.appendChild(td);
+			}
+		}
+		body.appendChild(table);
+		WebEngine e = webView.getEngine();
+		e.loadContent(html.write());
+	}
+
+	@FXML
+	private void cancelButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+
+	@FXML
+	private void printButtonHandler(ActionEvent event) {
+		Printer printer = Printer.getDefaultPrinter();
+		PageLayout layout = printer.createPageLayout(Paper.A4, PageOrientation.LANDSCAPE, MarginType.DEFAULT);
+		PrinterJob job = PrinterJob.createPrinterJob(printer);
+		job.getJobSettings().setPageLayout(layout);
+		job.getJobSettings().setJobName(ApplicationUtils.getApplication().getInfo().getName());
+		if (job != null && job.showPrintDialog(getStage())) {
+			webView.getEngine().print(job);
+			job.endJob();
+			getStage().close();
+		}
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..020656123627b651bbaab676ba9bb2f41cecc0c5
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionViewController.java
@@ -0,0 +1,77 @@
+package de.tobias.playpad.viewcontroller.actions;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.cartaction.CartAction;
+import de.tobias.playpad.action.cartaction.CartAction.ControlMode;
+import de.tobias.playpad.action.mapper.MapperRegistry;
+import de.tobias.playpad.action.mapper.MapperViewController;
+import de.tobias.playpad.viewcontroller.IMapperOverviewViewController;
+import de.tobias.playpad.viewcontroller.cell.EnumCell;
+import de.tobias.utils.ui.ContentViewController;
+import javafx.fxml.FXML;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+
+public class CartActionViewController extends ContentViewController {
+
+	@FXML private ComboBox<ControlMode> controlMode;
+	@FXML private CheckBox autoColorCheckbox;
+
+	@FXML private VBox rootContainer;
+	private IMapperOverviewViewController mapperOverviewViewController;
+
+	private CartAction action;
+
+	public CartActionViewController() {
+		super("cartAction", "de/tobias/playpad/assets/view/actions/", PlayPadMain.getUiResourceBundle());
+	}
+
+	@Override
+	public void init() {
+		controlMode.getItems().setAll(ControlMode.values());
+		controlMode.setCellFactory(list -> new EnumCell<>(Strings.CartAction_Mode_BaseName));
+		controlMode.setButtonCell(new EnumCell<>(Strings.CartAction_Mode_BaseName));
+		controlMode.valueProperty().addListener((a, b, c) ->
+		{
+			action.setMode(c);
+		});
+
+		autoColorCheckbox.selectedProperty().addListener((a, b, c) ->
+		{
+			action.setAutoFeedbackColors(c);
+			// Disable Feedback Controls bei Automatischen Feedback für VORHANDENE MAPPER
+			if (mapperOverviewViewController != null) {
+				mapperOverviewViewController.getControllers().forEach(controller ->
+				{
+					toggleFeedbackVisablity(action, controller);
+				});
+			}
+		});
+		VBox.setVgrow(rootContainer, Priority.ALWAYS);
+
+		mapperOverviewViewController = MapperRegistry.getOverviewViewControllerInstance();
+		mapperOverviewViewController.addMapperAddListener((mapper, controller) ->
+		{
+			// Disable Feedback Controls bei Automatischen Feedback für NEUE MAPPER die erstellt werden
+			toggleFeedbackVisablity(action, controller);
+		});
+	}
+
+	public void setCartAction(CartAction action) {
+		this.action = action;
+
+		controlMode.setValue(action.getMode());
+		autoColorCheckbox.setSelected(action.isAutoFeedbackColors());
+	}
+
+	private void toggleFeedbackVisablity(CartAction action, MapperViewController controller) {
+		if (action.isAutoFeedbackColors()) {
+			controller.hideFeedback();
+		} else {
+			controller.showFeedback();
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionsViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b559d479ee894aca9cf5b6c7a4b9455c264b1f6
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionsViewController.java
@@ -0,0 +1,136 @@
+package de.tobias.playpad.viewcontroller.actions;
+
+import java.util.List;
+
+import org.controlsfx.control.SegmentedButton;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Mapping;
+import de.tobias.playpad.action.cartaction.CartAction;
+import de.tobias.playpad.action.connect.CartActionConnect;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.playpad.viewcontroller.IMappingTabViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+import javafx.fxml.FXML;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.control.ToggleGroup;
+import javafx.scene.layout.ColumnConstraints;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.RowConstraints;
+import javafx.scene.layout.VBox;
+
+/**
+ * Diese View ist die Basis für die Einstellunge für eine CartAction. Dabei enthällt diese View ein Grid aus Buttons (Carts), eine
+ * seitenauswahl (Carts ändern sich) und eine Scrollview für die Einstellungen. Die Einstellungen werden von der Class
+ * CartActionViewController hier eingebettet. Dabei wird nicht jedes mal eine neue Instance erstellt, sondern die in CartAction vorhandene
+ * Instance verwendet. Das geht, solange die View nur einmal verwendet wird.
+ * 
+ * @author tobias
+ *
+ */
+public class CartActionsViewController extends ContentViewController {
+
+	@FXML private VBox buttonVbox;
+	@FXML private HBox pageHbox;
+
+	private ToggleGroup cartsToggle;
+	@FXML private GridPane gridPane;
+
+	@FXML private VBox cartActionContainer;
+
+	private Mapping mapping;
+	private IMappingTabViewController parentController;
+
+	public CartActionsViewController(Mapping mapping, IMappingTabViewController parentController) {
+		super("cartActions", "de/tobias/playpad/assets/view/actions/", PlayPadMain.getUiResourceBundle());
+		this.mapping = mapping;
+		this.parentController = parentController;
+
+		ProfileSettings settings = Profile.currentProfile().getProfileSettings();
+
+		showCartButtons(settings, 0);
+		VBox.setVgrow(gridPane, Priority.ALWAYS);
+
+		SegmentedButton segmentedButton = new SegmentedButton();
+		for (int i = 0; i < settings.getPageCount(); i++) {
+			ToggleButton button = new ToggleButton(Localization.getString(Strings.UI_Window_Main_PageButton, i + 1));
+			button.setOnAction(e ->
+			{
+				int page = Integer.valueOf(((ToggleButton) e.getSource()).getUserData().toString());
+				showCartButtons(Profile.currentProfile().getProfileSettings(), page);
+			});
+			button.setUserData(i);
+			segmentedButton.getButtons().add(button);
+		}
+		segmentedButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK);
+		pageHbox.getChildren().add(segmentedButton);
+		segmentedButton.getButtons().get(0).setSelected(true); // Select First Toggle
+	}
+
+	@Override
+	public void init() {
+		buttonVbox.minHeightProperty().bind(buttonVbox.heightProperty());
+	}
+
+	private void showCartButtons(ProfileSettings settings, int page) {
+		gridPane.getChildren().clear();
+
+		gridPane.getColumnConstraints().clear();
+		double xPercentage = 1.0 / (double) settings.getColumns();
+		for (int i = 0; i < settings.getColumns(); i++) {
+			ColumnConstraints c = new ColumnConstraints();
+			c.setPercentWidth(xPercentage * 100);
+			gridPane.getColumnConstraints().add(c);
+		}
+
+		gridPane.getRowConstraints().clear();
+		double yPercentage = 1.0 / (double) settings.getRows();
+		for (int i = 0; i < settings.getRows(); i++) {
+			RowConstraints c = new RowConstraints();
+			c.setPercentHeight(yPercentage * 100);
+			gridPane.getRowConstraints().add(c);
+		}
+
+		cartsToggle = new ToggleGroup();
+
+		int startValue = (page * settings.getColumns() * settings.getRows());
+
+		for (int x = 0; x < settings.getColumns(); x++) {
+			for (int y = 0; y < settings.getRows(); y++) {
+				int index = (settings.getColumns() * y + x) + startValue;
+				ToggleButton button = new ToggleButton(String.valueOf(index + 1));
+				button.setMaxWidth(Double.MAX_VALUE);
+				button.setUserData(index);
+				button.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK);
+
+				// Show the right cart settings
+				button.selectedProperty().addListener((a, b, c) ->
+				{
+					if (c) {
+						int id = Integer.valueOf(button.getUserData().toString());
+
+						List<CartAction> cartActions = mapping.getActions(CartActionConnect.TYPE);
+						for (CartAction action : cartActions) {
+							if (action.getCart() == id) {
+								ContentViewController actionViewController = action.getSettingsViewController();
+								cartActionContainer.getChildren().setAll(actionViewController.getParent());
+								cartActionContainer.setVisible(true);
+								parentController.showMapperFor(action);
+							}
+						}
+					} else {
+						cartActionContainer.setVisible(false);
+						parentController.showMapperFor(null);
+					}
+				});
+				gridPane.add(button, x, y);
+				cartsToggle.getToggles().add(button);
+			}
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/audio/ClipSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/audio/ClipSettingsViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..624d6c557b49d8606a58b71d5af1a82d0c29d919
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/audio/ClipSettingsViewController.java
@@ -0,0 +1,140 @@
+package de.tobias.playpad.viewcontroller.audio;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer.Info;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.audio.TinyAudioHandler;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.AudioTypeViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.util.Worker;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.util.Callback;
+
+public class ClipSettingsViewController extends AudioTypeViewController implements Callback<ListView<Info>, ListCell<Info>> {
+
+	@FXML private ComboBox<Info> soundCardComboBox;
+	@FXML private Button testButton;
+
+	private boolean isChanged;
+
+	private Clip clip;
+
+	public ClipSettingsViewController() {
+		super("clipSettings", "de/tobias/playpad/assets/view/audio/", PlayPadMain.getUiResourceBundle());
+
+		// Mixer (ohne Port)
+		List<Info> infos = Arrays.stream(AudioSystem.getMixerInfo()).filter(info -> !info.getName().startsWith("Port"))
+				.collect(Collectors.toList());
+
+		testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY));
+
+		soundCardComboBox.getItems().setAll(infos);
+		soundCardComboBox.setCellFactory(this);
+		soundCardComboBox.setButtonCell(call(null));
+
+		String name = (String) Profile.currentProfile().getProfileSettings().getAudioUserInfo().get(TinyAudioHandler.SOUND_CARD);
+		for (Info info : AudioSystem.getMixerInfo()) {
+			if (info.getName().equals(name)) {
+				soundCardComboBox.getSelectionModel().select(info);
+				break;
+			}
+		}
+
+		// ersten Auswählen wenn keiner ausgewählt ist, damit keine Probleme auftreten da keiene Soundkarte ausgewäht ist
+		if (soundCardComboBox.getSelectionModel().getSelectedItem() == null) {
+			soundCardComboBox.getSelectionModel().selectFirst();
+		}
+
+		soundCardComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			if (clip != null) {
+				clip.stop();
+				clip = null;
+				testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY));
+			}
+
+			isChanged = true;
+			Profile.currentProfile().getProfileSettings().getAudioUserInfo().put(TinyAudioHandler.SOUND_CARD, c.getName());
+		});
+	}
+
+	@FXML
+	private void testButtonHandler(ActionEvent event) {
+		try {
+			AudioInputStream audioIn = AudioSystem.getAudioInputStream(
+					ClipSettingsViewController.class.getClassLoader().getResource("de/tobias/playpad/assets/files/Test-Sound.wav"));
+
+			if (clip != null) {
+				clip.stop();
+				clip = null;
+				testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY));
+			} else {
+
+				clip = AudioSystem.getClip(soundCardComboBox.getValue());
+
+				clip.open(audioIn);
+				clip.start();
+				Worker.runLater(() ->
+				{
+					while (true) {
+						if (clip != null) {
+							return;
+						}
+						if (!clip.isRunning()) {
+							clip.drain();
+							clip.close();
+							break;
+						}
+						try {
+							Thread.sleep(100);
+						} catch (Exception e) {
+							e.printStackTrace();
+						}
+					}
+				});
+				testButton.setGraphic(new FontIcon(FontAwesomeType.STOP));
+			}
+
+		} catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public ListCell<Info> call(ListView<Info> param) {
+		return new ListCell<Info>() {
+
+			@Override
+			protected void updateItem(Info item, boolean empty) {
+				super.updateItem(item, empty);
+				if (!empty) {
+					setText(item.getName());
+				} else {
+					setText("");
+				}
+			}
+		};
+	}
+
+	@Override
+	public boolean isChanged() {
+		return isChanged;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/audio/TinySoundSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/audio/TinySoundSettingsViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..4429ba72ad6c5bc5b937e314e491e1248bdb7c19
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/audio/TinySoundSettingsViewController.java
@@ -0,0 +1,140 @@
+package de.tobias.playpad.viewcontroller.audio;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer.Info;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.audio.TinyAudioHandler;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.AudioTypeViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.util.Worker;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.util.Callback;
+
+public class TinySoundSettingsViewController extends AudioTypeViewController implements Callback<ListView<Info>, ListCell<Info>> {
+
+	@FXML private ComboBox<Info> soundCardComboBox;
+	@FXML private Button testButton;
+
+	private boolean isChanged;
+
+	private Clip clip;
+
+	public TinySoundSettingsViewController() {
+		super("tinySoundSettings", "de/tobias/playpad/assets/view/audio/", PlayPadMain.getUiResourceBundle());
+
+		// Mixer (ohne Port)
+		List<Info> infos = Arrays.stream(AudioSystem.getMixerInfo()).filter(info -> !info.getName().startsWith("Port"))
+				.collect(Collectors.toList());
+
+		testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY));
+
+		soundCardComboBox.getItems().setAll(infos);
+		soundCardComboBox.setCellFactory(this);
+		soundCardComboBox.setButtonCell(call(null));
+
+		String name = (String) Profile.currentProfile().getProfileSettings().getAudioUserInfo().get(TinyAudioHandler.SOUND_CARD);
+		for (Info info : AudioSystem.getMixerInfo()) {
+			if (info.getName().equals(name)) {
+				soundCardComboBox.getSelectionModel().select(info);
+				break;
+			}
+		}
+
+		// ersten Auswählen wenn keiner ausgewählt ist, damit keine Probleme auftreten da keiene Soundkarte ausgewäht ist
+		if (soundCardComboBox.getSelectionModel().getSelectedItem() == null) {
+			soundCardComboBox.getSelectionModel().selectFirst();
+		}
+
+		soundCardComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			if (clip != null) {
+				clip.stop();
+				clip = null;
+				testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY));
+			}
+
+			isChanged = true;
+			Profile.currentProfile().getProfileSettings().getAudioUserInfo().put(TinyAudioHandler.SOUND_CARD, c.getName());
+		});
+	}
+
+	@FXML
+	private void testButtonHandler(ActionEvent event) {
+		try {
+			AudioInputStream audioIn = AudioSystem.getAudioInputStream(
+					TinySoundSettingsViewController.class.getClassLoader().getResource("de/tobias/playpad/assets/files/Test-Sound.wav"));
+
+			if (clip != null) {
+				clip.stop();
+				clip = null;
+				testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY));
+			} else {
+
+				clip = AudioSystem.getClip(soundCardComboBox.getValue());
+
+				clip.open(audioIn);
+				clip.start();
+				Worker.runLater(() ->
+				{
+					while (true) {
+						if (clip != null) {
+							return;
+						}
+						if (!clip.isRunning()) {
+							clip.drain();
+							clip.close();
+							break;
+						}
+						try {
+							Thread.sleep(100);
+						} catch (Exception e) {
+							e.printStackTrace();
+						}
+					}
+				});
+				testButton.setGraphic(new FontIcon(FontAwesomeType.STOP));
+			}
+
+		} catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public ListCell<Info> call(ListView<Info> param) {
+		return new ListCell<Info>() {
+
+			@Override
+			protected void updateItem(Info item, boolean empty) {
+				super.updateItem(item, empty);
+				if (!empty) {
+					setText(item.getName());
+				} else {
+					setText("");
+				}
+			}
+		};
+	}
+
+	@Override
+	public boolean isChanged() {
+		return isChanged;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/DisplayableCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/DisplayableCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..69045785485c04dd624aebf5866d4391a2d707a6
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/DisplayableCell.java
@@ -0,0 +1,30 @@
+package de.tobias.playpad.viewcontroller.cell;
+
+import de.tobias.playpad.Displayable;
+import javafx.scene.Node;
+import javafx.scene.control.ListCell;
+
+public class DisplayableCell<T extends Displayable> extends ListCell<T> {
+
+	private Displayable action;
+
+	@Override
+	protected void updateItem(T action, boolean empty) {
+		super.updateItem(action, empty);
+		if (!empty) {
+			if (this.action == null || this.action != action) {
+				Node graphics = action.getGraphics();
+				setGraphic(graphics);
+
+				textProperty().bind(action.displayProperty());
+				this.action = action;
+			}
+		} else {
+			this.action = null;
+			textProperty().unbind();
+
+			setGraphic(null);
+			setText("");
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/DisplayableTreeCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/DisplayableTreeCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd11f91ca4ad5dc09570ac44132a96b4adb84e06
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/DisplayableTreeCell.java
@@ -0,0 +1,30 @@
+package de.tobias.playpad.viewcontroller.cell;
+
+import de.tobias.playpad.Displayable;
+import javafx.scene.Node;
+import javafx.scene.control.TreeCell;
+
+public class DisplayableTreeCell<T extends Displayable> extends TreeCell<T> {
+
+	private Displayable action;
+
+	@Override
+	protected void updateItem(T action, boolean empty) {
+		super.updateItem(action, empty);
+		if (!empty) {
+			if (this.action == null || this.action != action) {
+				Node graphics = action.getGraphics();
+				setGraphic(graphics);
+
+				textProperty().bind(action.displayProperty());
+				this.action = action;
+			}
+		} else {
+			this.action = null;
+			textProperty().unbind();
+
+			setGraphic(null);
+			setText("");
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/EnumCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/EnumCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..788b5fc9f1c1307031b1b2ee5dea0d9204e1902d
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/EnumCell.java
@@ -0,0 +1,23 @@
+package de.tobias.playpad.viewcontroller.cell;
+
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.ListCell;
+
+public class EnumCell<T extends Enum<?>> extends ListCell<T> {
+
+	private String baseName;
+
+	public EnumCell(String baseName) {
+		this.baseName = baseName;
+	}
+
+	@Override
+	protected void updateItem(T item, boolean empty) {
+		super.updateItem(item, empty);
+		if (!empty) {
+			setText(Localization.getString(baseName + item.name()));
+		} else {
+			setText("");
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1ea5a801ab150ac7a2ceef4194d96c8f5a871e4
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java
@@ -0,0 +1,73 @@
+package de.tobias.playpad.viewcontroller.cell;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.plugin.Plugin;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Pos;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ListCell;
+import javafx.scene.layout.HBox;
+import net.xeoh.plugins.base.PluginManager;
+
+public class PluginCell extends ListCell<Plugin> implements ChangeListener<Boolean> {
+
+	private Plugin plugin;
+	private HBox buttons;
+	private CheckBox checkBox;
+
+	private PluginManager manager;
+
+	public PluginCell(PluginManager manager) {
+		this.manager = manager;
+
+		checkBox = new CheckBox();
+		checkBox.selectedProperty().addListener(this);
+
+		buttons = new HBox(checkBox);
+		buttons.setSpacing(14);
+		buttons.setAlignment(Pos.CENTER_LEFT);
+	}
+
+	@Override
+	protected void updateItem(Plugin item, boolean empty) {
+		super.updateItem(item, empty);
+		if (!empty) {
+			this.plugin = item;
+			if (item.isActive()) {
+				checkBox.setSelected(true);
+			} else {
+				checkBox.setSelected(false);
+			}
+			setGraphic(buttons);
+			checkBox.setText(item.getName());
+		} else {
+			setGraphic(null);
+		}
+	}
+
+	@Override
+	public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+		Path path = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, plugin.getFileName());
+		if (newValue) { // Wurde Aktiviert
+			if (Files.notExists(path)) {
+				try {
+					Files.createDirectories(path.getParent());
+					Files.copy(new URL(plugin.getUrl()).openStream(), path);
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+			manager.addPluginsFrom(path.toUri());
+		} else {
+			PlayPadMain.addDeletedPlugin(path);
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ee0a1ee42ca3a96948d1f22d28c7694e7c18d15
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java
@@ -0,0 +1,44 @@
+package de.tobias.playpad.viewcontroller.cell;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import de.tobias.playpad.Displayable;
+import de.tobias.playpad.project.ProjectReference;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.control.ListCell;
+import javafx.scene.paint.Color;
+
+public class ProjectCell extends ListCell<ProjectReference> {
+
+	private Displayable action;
+
+	@Override
+	protected void updateItem(ProjectReference action, boolean empty) {
+		super.updateItem(action, empty);
+		if (!empty) {
+			if (this.action == null || this.action != action) {
+				Path path = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, action.getFileName());
+				if (Files.notExists(path)) {
+					FontIcon graphics = new FontIcon(FontAwesomeType.WARNING);
+					graphics.setColor(Color.RED);
+					setGraphic(graphics);
+				}
+				setContentDisplay(ContentDisplay.RIGHT);
+
+				textProperty().bind(action.displayProperty());
+				this.action = action;
+			}
+		} else {
+			this.action = null;
+			textProperty().unbind();
+
+			setGraphic(null);
+			setText("");
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ThemeCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ThemeCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..64cdd06b4cd2fc28efc3f790c720ea428bad01b6
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ThemeCell.java
@@ -0,0 +1,19 @@
+package de.tobias.playpad.viewcontroller.cell;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.layout.classic.Theme;
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.ListCell;
+
+public class ThemeCell extends ListCell<Theme> {
+
+	@Override
+	protected void updateItem(Theme item, boolean empty) {
+		super.updateItem(item, empty);
+		if (!empty) {
+			setText(Localization.getString(Strings.UI_Layout_Classic_Theme_BaseName + item.name()));
+		} else {
+			setText("");
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..48d27b4b90eba7e5e6e99885433f76cb0fd6494e
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java
@@ -0,0 +1,19 @@
+package de.tobias.playpad.viewcontroller.cell;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.Updatable;
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.ListCell;
+
+public class UpdateCell extends ListCell<Updatable> {
+
+	@Override
+	protected void updateItem(Updatable item, boolean empty) {
+		super.updateItem(item, empty);
+		if (!empty) {
+			setText(Localization.getString(Strings.UI_Dialog_Update_Cell, item.name(), item.getCurrentVersion(), item.getNewVersion()));
+		} else {
+			setText("");
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..601212b6d9566e905d331b046322e06bdac4e26d
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java
@@ -0,0 +1,20 @@
+package de.tobias.playpad.viewcontroller.cell.errordialog;
+
+import de.tobias.playpad.pad.PadException;
+import javafx.scene.control.Control;
+import javafx.scene.control.TableCell;
+import javafx.scene.text.Text;
+
+
+public class ErrorCell extends TableCell<PadException, String> {
+
+	
+	public ErrorCell() {
+		Text text = new Text();
+		text.getStyleClass().add("label");
+		setGraphic(text);
+		setPrefHeight(Control.USE_COMPUTED_SIZE);
+		text.wrappingWidthProperty().bind(widthProperty());
+		text.textProperty().bind(itemProperty());
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..4dd2458946d4ff8295964d8f282105bccd916efe
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java
@@ -0,0 +1,92 @@
+package de.tobias.playpad.viewcontroller.cell.errordialog;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadException;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
+import de.tobias.playpad.pad.conntent.UnkownPadContentException;
+import de.tobias.playpad.view.ExceptionButton;
+import de.tobias.utils.util.FileUtils;
+import javafx.scene.control.Button;
+import javafx.scene.control.TableCell;
+import javafx.stage.Stage;
+
+public class FixCell extends TableCell<PadException, PadException> {
+
+	private Stage stage;
+
+	public FixCell(Stage stage) {
+		this.stage = stage;
+	}
+
+	@Override
+	protected void updateItem(PadException item, boolean empty) {
+		super.updateItem(item, empty);
+		if (!empty) {
+			switch (item.getType()) {
+			case FILE_NOT_FOUND:
+				ExceptionButton<Path> notExistsExButton = ExceptionButton.FILE_NOT_FOUND_EXCEPTION;
+				Button notExistsButton = notExistsExButton.getButton();
+				notExistsButton.setOnAction(a ->
+				{
+					Path path = notExistsExButton.getHandler().handle(item.getPad(), stage);
+					if (path != null) {
+
+						Pad pad = item.getPad();
+						PadContent content = item.getPad().getContent();
+						try {
+							PadContentConnect padContentConnect = PadContentRegistry.getPadContentConnect(content.getType());
+
+							if (Files.exists(path) && PadContentConnect.isFileSupported(path, padContentConnect)) {
+								content.handlePath(path);
+								pad.setName(FileUtils.getFilenameWithoutExtention(path.getFileName()));
+								pad.removeException(item);
+							}
+						} catch (UnkownPadContentException e) {
+							e.printStackTrace();
+						}
+					}
+				});
+				setGraphic(notExistsButton);
+				break;
+
+			case FILE_FORMAT_NOT_SUPPORTED:
+			case CONVERT_NOT_SUPPORTED:
+				ExceptionButton<Path> supportExButton = ExceptionButton.FILE_NOT_FOUND_EXCEPTION;
+				Button supportButton = supportExButton.getButton();
+				supportButton.setOnAction(a ->
+				{
+					Path path = supportExButton.getHandler().handle(item.getPad(), stage);
+					if (path != null) {
+
+						Pad pad = item.getPad();
+						PadContent content = item.getPad().getContent();
+						try {
+							PadContentConnect padContentConnect = PadContentRegistry.getPadContentConnect(content.getType());
+
+							if (Files.exists(path) && PadContentConnect.isFileSupported(path, padContentConnect)) {
+								content.handlePath(path);
+								pad.setName(FileUtils.getFilenameWithoutExtention(path.getFileName()));
+								pad.removeException(item);
+							}
+						} catch (UnkownPadContentException e) {
+							e.printStackTrace();
+						}
+					}
+				});
+				setGraphic(supportButton);
+				break;
+
+			default:
+				break;
+			}
+		} else {
+			setGraphic(null);
+		}
+		setText("");
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ChangelogDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ChangelogDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..742c07fd81d1ea48256bce922099c0a4502ece2a
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ChangelogDialog.java
@@ -0,0 +1,66 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import de.tobias.playpad.AppUserInfoStrings;
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.concurrent.Worker.State;
+import javafx.fxml.FXML;
+import javafx.scene.web.WebView;
+import javafx.stage.Stage;
+import netscape.javascript.JSObject;
+
+public class ChangelogDialog extends ViewController {
+
+	@FXML private WebView contentView;
+	private JSBridge bridge;
+
+	public ChangelogDialog() {
+		super("changelogDialog", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
+
+		if (ApplicationUtils.getApplication().isUpdated()) {
+			bridge = new JSBridge();
+
+			contentView.getEngine().getLoadWorker().stateProperty().addListener((ov, oldState, newState) ->
+			{
+				if (newState == State.SUCCEEDED) {
+					JSObject window = (JSObject) contentView.getEngine().executeScript("window");
+					window.setMember("app", bridge);
+					getStage().show();
+				}
+			});
+
+			String url = ApplicationUtils.getApplication().getInfo().getUserInfo().getString(AppUserInfoStrings.CHANGELOG_URL) + "&version="
+					+ ApplicationUtils.getApplication().getOldVersionNumber();
+			contentView.getEngine().load(url);
+			getStage().show();
+		}
+	}
+
+	@Override
+	public void init() {
+		addCloseKeyShortcut(() -> getStage().close());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setWidth(500);
+		stage.setMinWidth(500);
+		stage.setMaxWidth(500);
+
+		stage.setMinHeight(700);
+		stage.setTitle(Localization.getString(Strings.UI_Window_Changelog_Title));
+		stage.setAlwaysOnTop(true);
+	}
+
+	public class JSBridge {
+
+		public void close() {
+			getStage().close();
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DragAndDropDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DragAndDropDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..76304d7e8af88fdd4e580be3d389bb8530333958
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DragAndDropDialog.java
@@ -0,0 +1,48 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.ButtonBar.ButtonData;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.Label;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.VBox;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class DragAndDropDialog extends Dialog<Void> {
+
+	private CheckBox displayOnceCheckBox;
+
+	public DragAndDropDialog(Window owner) {
+		setHeaderText(Localization.getString(Strings.UI_Dialog_DragAndDrop_Header));
+		setGraphic(new ImageView("org/controlsfx/dialog/dialog-information.png"));
+
+		Label textLabel = new Label(Localization.getString(Strings.UI_Dialog_DragAndDrop_Content));
+		textLabel.setWrapText(true);
+		textLabel.setMaxWidth(450);
+		ImageView view = new ImageView("de/tobias/playpad/assets/files/dialogDnD.png");
+
+		displayOnceCheckBox = new CheckBox(Localization.getString(Strings.UI_Standard_DoNotShow));
+
+		VBox box = new VBox(textLabel, view, displayOnceCheckBox);
+		box.setSpacing(10);
+		getDialogPane().setContent(box);
+
+		ButtonType buttonTypeOk = new ButtonType(Localization.getString(Strings.UI_Dialog_DragAndDrop_Button), ButtonData.OK_DONE);
+		getDialogPane().getButtonTypes().add(buttonTypeOk);
+
+		initOwner(owner);
+		initModality(Modality.WINDOW_MODAL);
+		Stage dialogStage = (Stage) getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(dialogStage.getIcons()::add);
+	}
+
+	public boolean isPermanentSelected() {
+		return displayOnceCheckBox.isSelected();
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProfileDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProfileDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..8556d72177365c43b1a3e563c2e2f976ffd8e2ee
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProfileDialog.java
@@ -0,0 +1,63 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import java.util.Optional;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.TextInputDialog;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+
+public class DuplicateProfileDialog extends TextInputDialog {
+
+	private ProfileReference newRef;
+
+	public DuplicateProfileDialog(ViewController controller, ProfileReference cloneableProfile) {
+		initOwner(controller.getStage());
+		initModality(Modality.WINDOW_MODAL);
+		Stage dialog = (Stage) getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add);
+
+		Button button = (Button) getDialogPane().lookupButton(ButtonType.OK);
+		getEditor().textProperty().addListener((a, b, c) ->
+		{
+			if (ProfileReference.getProfiles().contains(c) || !c.matches(Profile.profileNameEx)) {
+				button.setDisable(true);
+			} else {
+				button.setDisable(false);
+			}
+		});
+
+		setContentText(Localization.getString(Strings.UI_Dialog_NewProfile_Content));
+		showAndWait().filter(name -> !name.isEmpty()).ifPresent(name ->
+		{
+			try {
+				if (ProfileReference.getProfiles().contains(name)) {
+					controller.showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, name));
+					return;
+				}
+
+				newRef = new ProfileReference(name);
+				ProfileReference.duplicate(cloneableProfile, newRef);
+
+			} catch (Exception e) {
+				e.printStackTrace();
+				controller.showErrorMessage(Localization.getString(Strings.Error_Profile_Save, e.getMessage()));
+			}
+		});
+	}
+
+	public Optional<ProfileReference> getName() {
+		if (newRef != null) {
+			return Optional.of(newRef);
+		} else {
+			return Optional.empty();
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4bbfd864346d13b9efde1988e29e3e8604edf6f
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java
@@ -0,0 +1,74 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import java.util.Optional;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonBar.ButtonData;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.TextInputDialog;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+
+public class DuplicateProjectDialog extends TextInputDialog {
+
+	private ProjectReference ref;
+
+	public DuplicateProjectDialog(ViewController controller, ProjectReference cloneableProject) {
+		initOwner(controller.getStage());
+		initModality(Modality.WINDOW_MODAL);
+		Stage dialog = (Stage) getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add);
+
+		setResultConverter(button ->
+		{
+			String param = getEditor().getText();
+			if (!param.endsWith(PlayPadMain.projectType[0].substring(1))) {
+				param += PlayPadMain.projectType[0].substring(1);
+			}
+
+			ButtonData data = button == null ? null : button.getButtonData();
+			return data == ButtonData.OK_DONE ? param : null;
+		});
+
+		Button button = (Button) getDialogPane().lookupButton(ButtonType.OK);
+		getEditor().textProperty().addListener((a, b, c) ->
+		{
+			if (ProjectReference.getProjects().contains(c) || !c.matches(Project.projectNameEx)) {
+				button.setDisable(true);
+			} else {
+				button.setDisable(false);
+			}
+		});
+
+		setContentText(Localization.getString(Strings.UI_Dialog_NewProject_Content));
+		showAndWait().filter(name -> !name.isEmpty()).ifPresent(name ->
+		{
+			try {
+				if (ProfileReference.getProfiles().contains(name)) {
+					controller.showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, name));
+					return;
+				}
+
+				ref = ProjectReference.duplicate(cloneableProject, name);
+			} catch (Exception e) {
+				e.printStackTrace();
+				controller.showErrorMessage(Localization.getString(Strings.Error_Project_Save, name, e.getMessage()));
+			}
+		});
+	}
+
+	public Optional<ProjectReference> getName() {
+		if (ref != null) {
+			return Optional.of(ref);
+		} else {
+			return Optional.empty();
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..d8f79dd00d3b4a2034c3973a59195b8f88e5ea2a
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java
@@ -0,0 +1,134 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.PadException;
+import de.tobias.playpad.pad.PadException.PadExceptionType;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.cell.errordialog.ErrorCell;
+import de.tobias.playpad.viewcontroller.cell.errordialog.FixCell;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.application.Platform;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.ListChangeListener;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class ErrorSummaryDialog extends ViewController {
+
+	private static ErrorSummaryDialog instance;
+
+	@FXML private TableView<PadException> errorTable;
+
+	@FXML private TableColumn<PadException, String> padColumn;
+	@FXML private TableColumn<PadException, String> errorColumn;
+	@FXML private TableColumn<PadException, PadException> fixColumn;
+
+	@FXML private Button closeButton;
+
+	public ErrorSummaryDialog(Window owner) {
+		super("errorSummaryDialog", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
+		instance = this;
+
+		getStage().initOwner(owner);
+		getStage().initModality(Modality.WINDOW_MODAL);
+	}
+
+	@Override
+	public void init() {
+		errorTable.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_ErrorSummary)));
+		// Disable das etwas ausgewählt werden kann
+		errorTable.setSelectionModel(null);
+
+		padColumn.setCellValueFactory(param ->
+		{
+			StringProperty value = new SimpleStringProperty(param.getValue().getPad().toString());
+			return value;
+		});
+
+		errorColumn.setCellFactory(param -> new ErrorCell());
+		errorColumn.setCellValueFactory(param ->
+
+		{
+			PadException padException = param.getValue();
+			String string = "";
+			try {
+				if (padException.getType() == PadExceptionType.UNKOWN_CONTENT_TYPE)
+					string = Localization.getString(Strings.Error_Pad_BaseName + padException.getType().name(),
+							padException.getPad().getIndexReadable());
+				else
+					string = Localization.getString(Strings.Error_Pad_BaseName + padException.getType().name(), padException.getPath());
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			StringProperty value = new SimpleStringProperty(string);
+			return value;
+		});
+
+		fixColumn.setCellFactory(param -> new FixCell(getStage()));
+		fixColumn.setCellValueFactory(param ->
+
+		{
+			ObjectProperty<PadException> type = new SimpleObjectProperty<>(param.getValue());
+			return type;
+		});
+
+		// Close CMD+W
+		getStage().getScene().getAccelerators().put(new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN),
+				() -> Platform.runLater(() -> getStage().close()));
+	}
+
+	public void setProject(Project project) {
+		errorTable.setItems(project.getExceptions());
+		errorTable.getItems().addListener(new ListChangeListener<PadException>() {
+
+			@Override
+			public void onChanged(javafx.collections.ListChangeListener.Change<? extends PadException> c) {
+				if (!errorTable.getItems().isEmpty()) {
+					getStage().show();
+				} else {
+					getStage().close();
+				}
+			}
+		});
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		stage.setMinWidth(900);
+		stage.setMinHeight(300);
+
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_ErrorSummary_Title));
+		stage.setWidth(900);
+		stage.setHeight(300);
+
+		if (Profile.currentProfile() != null)
+			Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	@FXML
+	private void closeButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+
+	public static ErrorSummaryDialog getInstance() {
+		return instance;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ExportDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ExportDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..eebd0d8ba87e3fe640b0ad3beec4eb82b9065093
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ExportDialog.java
@@ -0,0 +1,101 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import java.io.File;
+import java.io.IOException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.project.ProjectExporter;
+import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.utils.ui.NotificationHandler;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.ui.scene.BusyView;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class ExportDialog extends ViewController {
+
+	@FXML private CheckBox profileCheckBox;
+	@FXML private CheckBox mediaCheckBox;
+
+	@FXML private Button cancelButton;
+	@FXML private Button saveButton;
+
+	private BusyView busyView;
+
+	private ProjectReference projectRef;
+	private NotificationHandler notificationHandler;
+
+	public ExportDialog(ProjectReference projectRef, Window owner, NotificationHandler notificationHandler) {
+		super("exportDialog", "de/tobias/playpad/assets/dialog/project/", null, PlayPadMain.getUiResourceBundle());
+		this.projectRef = projectRef;
+		this.notificationHandler = notificationHandler;
+
+		getStage().initOwner(owner);
+		getStage().initModality(Modality.WINDOW_MODAL);
+
+		busyView = new BusyView(this);
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_ProjectExport_Title));
+		stage.setWidth(320);
+		stage.setHeight(180);
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	@FXML
+	private void cancelButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+
+	@FXML
+	private void saveButtonHandler(ActionEvent event) {
+		FileChooser chooser = new FileChooser();
+		chooser.getExtensionFilters()
+				.add(new ExtensionFilter(Localization.getString(Strings.File_Filter_ZIP), PlayPadMain.projectCompressedType));
+		File file = chooser.showSaveDialog(getStage());
+		if (file != null) {
+			cancelButton.setDisable(true);
+			busyView.showProgress(true);
+
+			Worker.runLater(() ->
+			{
+				try {
+					ProjectExporter.exportProject(projectRef, file.toPath(), profileCheckBox.isSelected(), mediaCheckBox.isSelected());
+
+					Platform.runLater(() ->
+					{
+						busyView.showProgress(false);
+						getStage().close();
+						notificationHandler.notify(Localization.getString(Strings.Standard_File_Save),
+								PlayPadMain.notificationDisplayTimeMillis);
+					});
+				} catch (IOException e) {
+					e.printStackTrace();
+					Platform.runLater(() ->
+					{
+						busyView.showProgress(false);
+						showErrorMessage(Localization.getString(Strings.Error_Project_Export, projectRef.getName(), e.getMessage()),
+								PlayPadMain.stageIcon);
+					});
+				}
+			});
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ImportDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ImportDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..a1e8fbf6ef6d4655147014a4d0a77693a430999e
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ImportDialog.java
@@ -0,0 +1,131 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Optional;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.project.Importable;
+import de.tobias.playpad.project.ProfileChooseable;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.TextInputDialog;
+import javafx.stage.DirectoryChooser;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+
+public class ImportDialog implements Importable, ProfileChooseable {
+
+	private static ImportDialog instance;
+	private static Stage owner;
+
+	static {
+		instance = new ImportDialog();
+	}
+
+	public static ImportDialog getInstance(Stage stage) {
+		ImportDialog.owner = stage;
+		return instance;
+	}
+
+	private Stage getStage() {
+		return owner;
+	}
+
+	@Override
+	public String replaceProfile(String name) {
+		Alert replaceAlert = new Alert(AlertType.CONFIRMATION);
+		replaceAlert.initOwner(getStage());
+		replaceAlert.initModality(Modality.WINDOW_MODAL);
+		replaceAlert.setContentText(Localization.getString(Strings.UI_Dialog_Import_ReplaceProfile_Content, name));
+
+		ButtonType skipButton = new ButtonType(Localization.getString(Strings.UI_Dialog_Import_ReplaceProfile_Skip));
+		ButtonType renameButton = new ButtonType(Localization.getString(Strings.UI_Dialog_Import_ReplaceProfile_Rename));
+		replaceAlert.getButtonTypes().setAll(skipButton, renameButton);
+
+		Stage replaceStage = (Stage) replaceAlert.getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(replaceStage.getIcons()::add);
+
+		Optional<ButtonType> resultButton = replaceAlert.showAndWait();
+		if (resultButton.isPresent()) {
+			if (resultButton.get() == renameButton) {
+				TextInputDialog alert = new TextInputDialog(name);
+				alert.initOwner(getStage());
+				alert.initModality(Modality.WINDOW_MODAL);
+				alert.setContentText(Localization.getString(Strings.UI_Dialog_Import_ReplaceProfile_ReplaceContent, name));
+
+				Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
+				PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+				if (alert.showAndWait().filter(item -> item != null).isPresent()) {
+					return alert.getResult();
+				}
+			} else {
+				return null;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public String replaceProject(String name) {
+		TextInputDialog alert = new TextInputDialog(name.replace(PlayPadMain.projectType[0].substring(1), ""));
+		alert.initOwner(getStage());
+		alert.initModality(Modality.WINDOW_MODAL);
+		alert.setContentText(Localization.getString(Strings.UI_Dialog_Import_ReplaceProject_ReplaceContent, name));
+
+		Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		if (alert.showAndWait().filter(item -> item != null).isPresent()) {
+			return alert.getResult();
+		}
+
+		return null;
+	}
+
+	@Override
+	public Path mediaFolder() {
+		Alert copyMediaAlert = new Alert(AlertType.CONFIRMATION);
+		copyMediaAlert.initOwner(getStage());
+		copyMediaAlert.initModality(Modality.WINDOW_MODAL);
+		copyMediaAlert.setContentText(Localization.getString(Strings.UI_Dialog_Import_ReplaceMedia_Content));
+
+		ButtonType copyButton = new ButtonType(Localization.getString(Strings.UI_Dialog_Import_ReplaceMedia_Copy));
+		ButtonType skipButton = new ButtonType(Localization.getString(Strings.UI_Dialog_Import_ReplaceMedia_Skip));
+
+		copyMediaAlert.getButtonTypes().setAll(copyButton, skipButton);
+
+		Stage replaceStage = (Stage) copyMediaAlert.getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(replaceStage.getIcons()::add);
+
+		Optional<ButtonType> resultButton = copyMediaAlert.showAndWait();
+		if (resultButton.isPresent()) {
+			if (resultButton.get() == copyButton) {
+				DirectoryChooser chooser = new DirectoryChooser();
+				File file = chooser.showDialog(owner);
+				if (file != null) {
+					return file.toPath();
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public Profile getUnkownProfile() {
+		ProfileChooseDialog dialog = new ProfileChooseDialog(getStage());
+
+		dialog.getStage().showAndWait();
+		Profile profile = dialog.getProfile();
+		if (profile != null) {
+			return profile;
+		}
+		return null;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..e82fd677771bb7798c9881b7895e710c859abb9c
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java
@@ -0,0 +1,225 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Mapping;
+import de.tobias.playpad.action.MappingList;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.cell.DisplayableCell;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class MappingListViewController extends ViewController {
+
+	@FXML private ComboBox<Mapping> presetsListView;
+
+	@FXML private TextField nameTextField;
+
+	@FXML private Button addButton;
+	@FXML private Button removeButton;
+	@FXML private Button importButton;
+	@FXML private Button exportButton;
+	@FXML private Button duplicateButton;
+
+	@FXML private Button finishButton;
+
+	private MappingList mappingList;
+
+	public MappingListViewController(MappingList mappingList, Window window) {
+		super("mappingView", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
+		this.mappingList = mappingList;
+
+		getStage().initOwner(window);
+
+		presetsListView.getItems().addAll(mappingList);
+		presetsListView.getSelectionModel().selectFirst();
+
+		if (mappingList.size() == 1) {
+			removeButton.setDisable(true);
+		}
+	}
+
+	@Override
+	public void init() {
+		presetsListView.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_Preset)));
+
+		// Ausgewählte in der Liste rechts zeigen und Button disablen
+		presetsListView.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			showPreset(c);
+			if (c == null) {
+				exportButton.setDisable(true);
+				if (mappingList.size() <= 1)
+					removeButton.setDisable(true);
+			} else {
+				removeButton.setDisable(false);
+				exportButton.setDisable(false);
+			}
+		});
+
+		// Name des Presets aktualisieren
+		nameTextField.textProperty().addListener((a, b, c) ->
+		{
+			Mapping item = getSelectedMidiPreset();
+			if (item != null) {
+				item.setName(c);
+			}
+		});
+
+		presetsListView.setCellFactory(item -> new DisplayableCell<>());
+		presetsListView.setButtonCell(new DisplayableCell<>());
+
+		addCloseKeyShortcut(() -> getStage().close());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		stage.initModality(Modality.WINDOW_MODAL);
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setMinWidth(500);
+		stage.setMinHeight(200);
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_Preset_Title));
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	private void showPreset(Mapping midiPreset) {
+		if (midiPreset != null) {
+			nameTextField.setText(midiPreset.getName());
+		} else {
+			nameTextField.setText(null);
+		}
+	}
+
+	@FXML
+	private void addButtonHandler(ActionEvent event) {
+		Mapping preset = new Mapping(true, Profile.currentProfile());
+
+		mappingList.add(preset);
+		presetsListView.getItems().add(preset);
+		presetsListView.getSelectionModel().select(preset);
+
+		if (mappingList.size() > 1) {
+			removeButton.setDisable(false);
+		}
+	}
+
+	@FXML
+	private void duplicateButtonHandler() {
+		Mapping preset = getSelectedMidiPreset();
+		try {
+			Mapping clonedMapping = preset.clone();
+			clonedMapping.setName(Localization.getString(Strings.Standard_Copy, clonedMapping.getName()));
+
+			// Model
+			mappingList.add(clonedMapping);
+			// UI
+			presetsListView.getItems().add(preset);
+			presetsListView.getSelectionModel().select(clonedMapping);
+		} catch (CloneNotSupportedException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@FXML
+	private void removeButtonHandler(ActionEvent event) {
+		int preset = presetsListView.getSelectionModel().getSelectedIndex();
+
+		mappingList.remove(preset);
+		presetsListView.getItems().remove(preset);
+
+		if (mappingList.size() == 1) {
+			removeButton.setDisable(true);
+		}
+	}
+
+	@FXML
+	private void finishButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+
+	@FXML
+	private void importButtonHandler(ActionEvent event) {
+		FileChooser chooser = new FileChooser();
+		chooser.getExtensionFilters().add(new ExtensionFilter(Localization.getString(Strings.File_Filter_Preset), PlayPadMain.midiPresetType));
+		File file = chooser.showOpenDialog(getStage());
+		if (file != null) {
+			Path path = file.toPath();
+
+			Worker.runLater(() ->
+			{
+				try {
+					Mapping preset = MappingList.importMappingPreset(path, Profile.currentProfile());
+					mappingList.add(preset);
+					Platform.runLater(() ->
+					{
+						presetsListView.getItems().add(preset);
+						presetsListView.getSelectionModel().select(preset);
+
+						if (mappingList.size() == 1) {
+							removeButton.setDisable(true);
+						} else {
+							removeButton.setDisable(false);
+						}
+
+						showInfoMessage(Localization.getString(Strings.Standard_File_Save));
+					});
+
+				} catch (Exception e) {
+					e.printStackTrace();
+					showErrorMessage(Localization.getString(Strings.Error_Preset_Import, e.getLocalizedMessage()));
+				}
+			});
+		}
+	}
+
+	@FXML
+	private void exportButtonHandler(ActionEvent event) {
+		Mapping preset = getSelectedMidiPreset();
+		if (preset != null) {
+			FileChooser chooser = new FileChooser();
+
+			ExtensionFilter filter = new ExtensionFilter(Localization.getString(Strings.File_Filter_Preset), PlayPadMain.midiPresetType);
+			chooser.getExtensionFilters().add(filter);
+
+			File file = chooser.showSaveDialog(getStage());
+			if (file != null) {
+				Path path = file.toPath();
+
+				Worker.runLater(() ->
+				{
+					try {
+						MappingList.exportMidiPreset(path, preset);
+						showInfoMessage(Localization.getString(Strings.Standard_File_Save));
+					} catch (IOException e) {
+						e.printStackTrace();
+						showErrorMessage(Localization.getString(Strings.Error_Preset_Export, e.getLocalizedMessage()));
+					}
+				});
+			}
+		}
+	}
+
+	private Mapping getSelectedMidiPreset() {
+		return presetsListView.getSelectionModel().getSelectedItem();
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProfileDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProfileDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..294c7f99b43d034d9eeba22752ee2f7200d82654
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProfileDialog.java
@@ -0,0 +1,154 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import javax.sound.midi.MidiDevice.Info;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Accordion;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.VBox;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class NewProfileDialog extends ViewController {
+
+	@FXML private TextField nameTextField;
+	@FXML private CheckBox activeCheckBox;
+	@FXML private ComboBox<String> midiDeviceComboBox;
+
+	@FXML private Button finishButton;
+	@FXML private Button cancelButton;
+
+	@FXML private VBox accordionParent;
+	@FXML private Accordion accordion;
+
+	private Profile profile;
+
+	public NewProfileDialog(Window owner) {
+		super("newProfileDialog", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
+
+		getStage().initOwner(owner);
+		getStage().initModality(Modality.WINDOW_MODAL);
+
+		midiDeviceComboBox.setDisable(!activeCheckBox.isSelected());
+
+		// In Worker, da Midi.getMidiDevices etwas dauert und FX-Thread sonst blockiert
+		Worker.runLater(() ->
+		{
+			Info[] data = Midi.getMidiDevices();
+
+			// Gerät anzeigen - Doppelte weg
+			Platform.runLater(() ->
+			{
+				for (Info item : data) {
+					if (!midiDeviceComboBox.getItems().contains(item.getName())) {
+						midiDeviceComboBox.getItems().add(item.getName());
+					}
+				}
+			});
+		});
+		getStage().sizeToScene();
+	}
+
+	private boolean expand = false;
+
+	@Override
+	public void init() {
+		accordion.heightProperty().addListener((obs, oldHeight, newHeight) ->
+		{
+			if (newHeight.doubleValue() > oldHeight.doubleValue()) {
+				if (accordionParent.getHeight() <= newHeight.doubleValue()) {
+					getStage().setHeight(getStage().getHeight() + newHeight.doubleValue());
+					expand = true;
+				}
+			} else {
+				if (expand)
+					getStage().setHeight(getStage().getHeight() - oldHeight.doubleValue());
+				expand = false;
+			}
+		});
+
+		nameTextField.textProperty().addListener((a, b, c) ->
+		{
+			if (c.isEmpty()) {
+				finishButton.setDisable(true);
+			} else {
+				if (ProfileReference.getProfiles().contains(c) || !c.matches(Profile.profileNameEx)) {
+					finishButton.setDisable(true);
+					return;
+				}
+				finishButton.setDisable(false);
+			}
+		});
+		finishButton.setDisable(true);
+
+		addCloseKeyShortcut(() -> getStage().close());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_NewProile_Title));
+		stage.setWidth(400);
+		stage.setHeight(200);
+
+		stage.setMinWidth(500);
+		stage.setMinHeight(200);
+
+		stage.setMaxWidth(500);
+
+		if (Profile.currentProfile() != null) {
+			Profile.currentProfile().currentLayout().applyCss(getStage());
+		}
+	}
+
+	@FXML
+	private void activeCheckBoxHandler(ActionEvent actionEvent) {
+		midiDeviceComboBox.setDisable(!activeCheckBox.isSelected());
+	}
+
+	@FXML
+	private void finishButtonHandler(ActionEvent event) {
+		String name = nameTextField.getText();
+		try {
+			if (ProfileReference.getProfiles().contains(name) || !name.matches(Profile.profileNameEx)) {
+				showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, name));
+				return;
+			}
+
+			profile = ProfileReference.newProfile(name);
+
+			profile.getProfileSettings().setMidiActive(activeCheckBox.isSelected());
+			profile.getProfileSettings().setMidiDeviceName(midiDeviceComboBox.getSelectionModel().getSelectedItem());
+
+			profile.save();
+			getStage().close();
+		} catch (Exception e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Profile_Create, e.getMessage()));
+		}
+	}
+
+	@FXML
+	private void cancelButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+
+	public Profile getProfile() {
+		return profile;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..973a5a43db38b233c796e259acca9db58d28e58c
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java
@@ -0,0 +1,135 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import org.dom4j.DocumentException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileNotFoundException;
+import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.TextField;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+/**
+ * Create an new project and adds it to the project reference list
+ * 
+ * @author tobias
+ *
+ */
+public class NewProjectDialog extends ViewController {
+
+	@FXML private TextField nameTextField;
+	@FXML private ComboBox<ProfileReference> profileComboBox;
+	@FXML private Button newProfileButton;
+
+	@FXML private Button finishButton;
+	@FXML private Button cancelButton;
+
+	private Project project;
+
+	public NewProjectDialog(Window owner) {
+		super("newProjectDialog", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
+
+		getStage().initOwner(owner);
+		getStage().initModality(Modality.WINDOW_MODAL);
+
+		profileComboBox.getItems().addAll(ProfileReference.getProfiles());
+		profileComboBox.getSelectionModel().selectFirst();
+	}
+
+	@Override
+	public void init() {
+		nameTextField.textProperty().addListener((a, b, c) ->
+		{
+			if (c.isEmpty()) {
+				finishButton.setDisable(true);
+			} else {
+				if (ProjectReference.getProjects().contains(c) || !c.matches(Project.projectNameEx)) {
+					finishButton.setDisable(true);
+					return;
+				}
+				finishButton.setDisable(false);
+			}
+		});
+		finishButton.setDisable(true);
+
+		addCloseKeyShortcut(() -> getStage().close());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_NewProject_Title));
+		stage.setWidth(560);
+		stage.setHeight(250);
+
+		stage.setMinWidth(560);
+		stage.setMinHeight(250);
+
+		stage.setMaxWidth(560);
+
+		if (Profile.currentProfile() != null) {
+			Profile.currentProfile().currentLayout().applyCss(getStage());
+		}
+	}
+
+	@FXML
+	private void finishButtonHandler(ActionEvent evenet) {
+		try {
+			Profile profile = Profile.load(profileComboBox.getSelectionModel().getSelectedItem());
+
+			String name = nameTextField.getText();
+			UUID uuid = UUID.randomUUID();
+
+			ProjectReference projectReference = new ProjectReference(uuid, name, profile.getRef());
+
+			project = new Project(projectReference);
+			project.save();
+
+			ProjectReference.addProject(projectReference);
+
+			getStage().close();
+		} catch (IOException | DocumentException | ProfileNotFoundException e) {
+			showErrorMessage(Localization.getString(Strings.Error_Project_Create, e.getLocalizedMessage()));
+			e.printStackTrace();
+		}
+	}
+
+	@FXML
+	private void cancelButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+
+	@FXML
+	private void newProfileButtonHandler(ActionEvent event) {
+		NewProfileDialog dialog = new NewProfileDialog(getStage());
+		dialog.getStage().showAndWait();
+
+		Profile profile = dialog.getProfile();
+
+		// In GUI hinzufügen (am Ende) und auswählen
+		if (profile != null) {
+			profileComboBox.getItems().add(profile.getRef());
+			profileComboBox.getSelectionModel().selectLast();
+		}
+	}
+
+	public Project getProject() {
+		return project;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileChooseDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileChooseDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..16362ff2cae9c234455fbbab6f86d343eafeafaa
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileChooseDialog.java
@@ -0,0 +1,93 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import java.io.IOException;
+
+import org.dom4j.DocumentException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileNotFoundException;
+import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class ProfileChooseDialog extends ViewController {
+
+	@FXML private ComboBox<ProfileReference> profileComboBox;
+	@FXML private Button newProfileButton;
+
+	@FXML private Button finishButton;
+	@FXML private Button cancelButton;
+
+	private Profile profile;
+
+	public ProfileChooseDialog(Window owner) {
+		super("profileChooseDialog", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
+
+		getStage().initOwner(owner);
+		getStage().initModality(Modality.WINDOW_MODAL);
+
+		profileComboBox.getItems().addAll(ProfileReference.getProfiles());
+		profileComboBox.getSelectionModel().selectFirst();
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_ChooseProfile_Title));
+		stage.setWidth(560);
+		stage.setHeight(180);
+		stage.setMinWidth(560);
+		stage.setMinHeight(180);
+		stage.setMaxWidth(560);
+
+		if (Profile.currentProfile() != null) {
+			Profile.currentProfile().currentLayout().applyCss(getStage());
+		}
+	}
+
+	@FXML
+	private void finishButtonHandler(ActionEvent evenet) {
+		try {
+			profile = Profile.load(profileComboBox.getSelectionModel().getSelectedItem());
+
+			getStage().close();
+		} catch (IOException | DocumentException | ProfileNotFoundException e) {
+			showErrorMessage(Localization.getString(Strings.Error_Profile_Save, e.getLocalizedMessage()));
+			e.printStackTrace();
+		}
+	}
+
+	@FXML
+	private void cancelButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+
+	@FXML
+	private void newProfileButtonHandler(ActionEvent event) {
+		NewProfileDialog dialog = new NewProfileDialog(getStage());
+		dialog.getStage().showAndWait();
+
+		Profile profile = dialog.getProfile();
+
+		// In GUI hinzufügen (am Ende) und auswählen
+		if (profile != null) {
+			profileComboBox.getItems().add(profile.getRef());
+			profileComboBox.getSelectionModel().selectLast();
+		}
+	}
+
+	public Profile getProfile() {
+		return profile;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..afd7641c48aaffa3b3709727e00337758fe041ce
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileViewController.java
@@ -0,0 +1,200 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import java.io.IOException;
+
+import org.dom4j.DocumentException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileNotFoundException;
+import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.playpad.viewcontroller.cell.DisplayableCell;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.ListView;
+import javafx.scene.control.TextField;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class ProfileViewController extends ViewController implements ChangeListener<ProfileReference> {
+
+	@FXML private ListView<ProfileReference> profileList;
+	@FXML private TextField nameTextField;
+
+	@FXML private Button newButton;
+	@FXML private Button duplicateButton;
+	@FXML private Button deleteButton;
+	@FXML private Button renameButton;
+
+	@FXML private Button chooseButton;
+
+	private Project project;
+
+	public ProfileViewController(Window owner, Project project) {
+		super("profileSettingsView", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
+		profileList.getSelectionModel().select(Profile.currentProfile().getRef());
+		this.project = project;
+
+		getStage().initOwner(owner);
+		getStage().initModality(Modality.WINDOW_MODAL);
+
+		if (ProfileReference.getProfiles().size() == 1
+				|| profileList.getSelectionModel().getSelectedItem().equals(Profile.currentProfile().getRef())) {
+			deleteButton.setDisable(true);
+		}
+	}
+
+	@Override
+	public void init() {
+		profileList.getItems().setAll(ProfileReference.getProfiles());
+		profileList.setCellFactory(list -> new DisplayableCell<>());
+
+		nameTextField.textProperty().addListener((a, b, c) ->
+		{
+			if (c != null) {
+				try {
+					if ((ProfileReference.getProfiles().contains(c) && !profileList.getSelectionModel().getSelectedItem().equals(c))
+							&& !c.equals(profileList.getSelectionModel().getSelectedItem().getName())) {
+						nameTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true);
+					} else {
+						nameTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false);
+					}
+				} catch (Exception e) {
+					nameTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true);
+				}
+			} else {
+				nameTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true);
+			}
+		});
+
+		profileList.getSelectionModel().selectedItemProperty().addListener(this);
+
+		addCloseKeyShortcut(() -> getStage().close());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_Profile_Title));
+		stage.setMinWidth(375);
+		stage.setMinHeight(500);
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	@FXML
+	private void chooseButtonHandler(ActionEvent event) {
+		ProfileReference ref = profileList.getSelectionModel().getSelectedItem();
+		project.getRef().setProfileReference(ref);
+
+		try {
+			Profile.load(ref);
+		} catch (ProfileNotFoundException | DocumentException | IOException e) {
+			e.printStackTrace();
+		}
+		getStage().close();
+	}
+
+	@FXML
+	private void newButtonHandler(ActionEvent event) {
+		NewProfileDialog dialog = new NewProfileDialog(getStage());
+		dialog.getStage().showAndWait();
+
+		Profile profile = dialog.getProfile();
+
+		if (profile != null) {
+			ProfileReference ref = profile.getRef();
+			profileList.getItems().add(ref);
+			selectProfile(ref);
+		}
+	}
+
+	@FXML
+	private void duplicateButtonHandler(ActionEvent event) {
+		if (profileList.getSelectionModel().getSelectedItem() != null) {
+			DuplicateProfileDialog dialog = new DuplicateProfileDialog(this, profileList.getSelectionModel().getSelectedItem());
+
+			dialog.getName().ifPresent(newRef ->
+			{
+				profileList.getItems().add(newRef);
+				selectProfile(newRef);
+			});
+		}
+	}
+
+	@FXML
+	private void deleteButtonHandler() {
+		Alert alert = new Alert(AlertType.CONFIRMATION);
+
+		alert.initOwner(getStage());
+		alert.initModality(Modality.WINDOW_MODAL);
+		Stage dialog = (Stage) alert.getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add);
+
+		ProfileReference ref = profileList.getSelectionModel().getSelectedItem();
+
+		alert.setContentText(Localization.getString(Strings.UI_Dialog_Profile_Delete_Content, ref));
+		alert.showAndWait().filter(button -> button == ButtonType.OK).ifPresent(button ->
+		{
+			try {
+				ProfileReference.removeProfile(ref);
+				profileList.getItems().remove(ref);
+			} catch (Exception e) {
+				e.printStackTrace();
+				showErrorMessage(Localization.getString(Strings.Error_Profile_Delete, e.getMessage()));
+			}
+		});
+	}
+
+	@FXML
+	private void renameButtonHandler(ActionEvent event) {
+		ProfileReference ref = profileList.getSelectionModel().getSelectedItem();
+		try {
+			String newProfileName = nameTextField.getText();
+			if (ProfileReference.getProfiles().contains(newProfileName) || !newProfileName.matches(Profile.profileNameEx)) {
+				showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, newProfileName));
+				return;
+			}
+			ref.setName(newProfileName);
+		} catch (Exception e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Standard_Gen, ref.getName(), e.getMessage()));
+		}
+	}
+
+	private void selectProfile(ProfileReference ref) {
+		profileList.getSelectionModel().select(ref);
+	}
+
+	@Override
+	public void changed(ObservableValue<? extends ProfileReference> observable, ProfileReference oldValue, ProfileReference newValue) {
+		if (newValue != null) {
+			nameTextField.setText(newValue.getName());
+		} else {
+			nameTextField.clear();
+		}
+		renameButton.setDisable(newValue == null);
+		chooseButton.setDisable(newValue == null);
+		duplicateButton.setDisable(newValue == null);
+
+		if (ProfileReference.getProfiles().size() == 1 || profileList.getSelectionModel().getSelectedItem() == null
+				|| profileList.getSelectionModel().getSelectedItem().equals(Profile.currentProfile().getRef())) {
+			deleteButton.setDisable(true);
+		} else {
+			deleteButton.setDisable(false);
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..33bf43df585597d188dc49079d8c63e3e504a8bc
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java
@@ -0,0 +1,326 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+
+import org.dom4j.DocumentException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.ProjectImporter;
+import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.cell.ProjectCell;
+import de.tobias.utils.ui.NotificationHandler;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.ui.scene.NotificationPane;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.NumberUtils;
+import de.tobias.utils.util.TimeUtils;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListView;
+import javafx.scene.control.TextField;
+import javafx.scene.input.MouseButton;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class ProjectManagerDialog extends ViewController implements NotificationHandler {
+
+	@FXML private ListView<ProjectReference> projectList;
+
+	@FXML private Button openButton;
+	@FXML private Button cancelButton;
+
+	@FXML private TextField nameTextField;
+	@FXML private Button renameButton;
+
+	@FXML private Button newButton;
+	@FXML private Button duplicateButton;
+	@FXML private Button deleteButton;
+
+	@FXML private Button importButton;
+	@FXML private Button exportButton;
+
+	@FXML private Label dateLabel;
+	@FXML private Label sizeLabel;
+
+	private Project currentProject;
+
+	private NotificationPane notificationPane;
+	@FXML private AnchorPane rootNode;
+
+	private boolean cancel = false;
+
+	public ProjectManagerDialog(Window owner, Project currentProject) {
+		super("openDialog", "de/tobias/playpad/assets/dialog/project/", null, PlayPadMain.getUiResourceBundle());
+		this.currentProject = currentProject;
+
+		projectList.getItems().setAll(ProjectReference.getProjectsSorted());
+
+		getStage().initOwner(owner);
+		getStage().initModality(Modality.WINDOW_MODAL);
+	}
+
+	@Override
+	public void init() {
+		// Notification Handler
+		notificationPane = new NotificationPane(rootNode);
+		notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK);
+
+		setAnchor(notificationPane, 0, 0, 0, 0);
+		((AnchorPane) getParent()).getChildren().add(notificationPane);
+
+		projectList.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_Project)));
+		projectList.setCellFactory(list -> new ProjectCell());
+
+		projectList.setOnMouseClicked(mouseEvent ->
+		{
+			if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
+				if (mouseEvent.getClickCount() == 2) {
+					if (!projectList.getSelectionModel().isEmpty()) {
+						getStage().close();
+					}
+				}
+			}
+		});
+		projectList.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			if (c != null) {
+				ProjectReference ref = getSelectedProject();
+
+				openButton.setDisable(false);
+				duplicateButton.setDisable(false);
+				exportButton.setDisable(false);
+				renameButton.setDisable(false);
+
+				nameTextField.setText(c.toString());
+				try {
+					sizeLabel.setText(NumberUtils.numberToString(ref.getSize()));
+					dateLabel.setText(TimeUtils.getDfmLong().format(ref.getLastMofied()));
+				} catch (Exception e) {
+					sizeLabel.setText("-");
+					dateLabel.setText("-");
+					e.printStackTrace();
+				}
+
+				if (currentProject.getRef().equals(c)) {
+					deleteButton.setDisable(true);
+				} else {
+					deleteButton.setDisable(false);
+				}
+			} else {
+				openButton.setDisable(true);
+				deleteButton.setDisable(true);
+				duplicateButton.setDisable(true);
+				exportButton.setDisable(true);
+				renameButton.setDisable(true);
+
+				nameTextField.setText(null);
+				sizeLabel.setText("-");
+				dateLabel.setText("-");
+			}
+		});
+
+		openButton.setDisable(true);
+		deleteButton.setDisable(true);
+		duplicateButton.setDisable(true);
+		exportButton.setDisable(true);
+		renameButton.setDisable(true);
+
+		sizeLabel.setText("-");
+		dateLabel.setText("-");
+
+		addCloseKeyShortcut(() -> getStage().close());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setMinWidth(600);
+		stage.setMinHeight(400);
+		stage.setWidth(600);
+		stage.setHeight(400);
+		stage.setTitle(Localization.getString(Strings.UI_Dialog_ProjectManager_Title));
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	@FXML
+	private void deleteButtonHandler(ActionEvent event) {
+		ProjectReference ref = getSelectedProject();
+
+		Alert alert = new Alert(AlertType.CONFIRMATION);
+		alert.setContentText(Localization.getString(Strings.UI_Dialog_ProjectManager_Delete_Content, ref));
+
+		Stage dialog = (Stage) alert.getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add);
+		alert.initOwner(getStage());
+		alert.initModality(Modality.WINDOW_MODAL);
+
+		alert.showAndWait().filter(item -> item == ButtonType.OK).ifPresent(item ->
+		{
+			try {
+				ProjectReference.removeDocument(ref);
+				projectList.getItems().remove(ref); // VIEW
+			} catch (Exception e) {
+				showErrorMessage(Localization.getString(Strings.Error_Project_Delete, e.getLocalizedMessage()));
+			}
+		});
+	}
+
+	@FXML
+	private void cancelButtonHandler(ActionEvent event) {
+		cancel = true;
+		getStage().close();
+	}
+
+	@FXML
+	private void openButtonHandler(ActionEvent event) {
+		getStage().close();
+	}
+
+	@FXML
+	private void renameButtonHandler(ActionEvent event) {
+		ProjectReference projectReference = getSelectedProject();
+		String oldName = projectReference.toString();
+
+		try {
+			String newProjectName = (String) nameTextField.getTextFormatter().getValue(); // Name + XML
+			if (ProjectReference.getProjects().contains(newProjectName) || !nameTextField.getText().matches(Project.projectNameEx)) {
+				showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, nameTextField.getText()));
+				return;
+			}
+
+			projectReference.setName(newProjectName);
+			projectList.getItems().setAll(ProjectReference.getProjectsSorted());
+
+			selectProject(projectReference);
+		} catch (Exception e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Project_Rename, oldName, e.getMessage()));
+		}
+	}
+
+	@FXML
+	private void newButtonHandler(ActionEvent event) {
+		NewProjectDialog dialog = new NewProjectDialog(getStage());
+		dialog.getStage().showAndWait();
+
+		Project project = dialog.getProject();
+		projectList.getItems().add(project.getRef());
+	}
+
+	@FXML
+	private void duplicateButtonHandler(ActionEvent event) {
+		if (getSelecteItem() != null) {
+			DuplicateProjectDialog dialog = new DuplicateProjectDialog(this, getSelectedProject());
+
+			dialog.getName().ifPresent(ref ->
+			{
+				projectList.getItems().add(ref);
+				selectProject(ref);
+			});
+		}
+	}
+
+	@FXML
+	private void importButtonHandler(ActionEvent event) {
+		FileChooser chooser = new FileChooser();
+		chooser.getExtensionFilters()
+				.add(new ExtensionFilter(Localization.getString(Strings.File_Filter_ZIP), PlayPadMain.projectCompressedType));
+		File file = chooser.showOpenDialog(getStage());
+		if (file != null) {
+			Path zipFile = file.toPath();
+			try {
+				ProjectReference ref = ProjectImporter.importProject(zipFile, ImportDialog.getInstance(getStage()),
+						ImportDialog.getInstance(getStage()));
+				projectList.getItems().add(ref);
+				selectProject(ref);
+			} catch (IOException | DocumentException e) {
+				showErrorMessage(Localization.getString(Strings.Error_Project_Open, e.getLocalizedMessage()));
+				e.printStackTrace();
+			}
+		}
+	}
+
+	@FXML
+	private void exportButtonHandler(ActionEvent event) {
+		ExportDialog dialog = new ExportDialog(getSelectedProject(), getStage(), this);
+		dialog.getStage().show();
+	}
+
+	public Optional<ProjectReference> showAndWait() {
+		getStage().showAndWait();
+		if (!cancel) {
+			if (getSelecteItem() != null) {
+				if (currentProject.getRef() != getSelecteItem()) {
+					return Optional.of(getSelecteItem());
+				}
+			}
+		}
+		return Optional.empty();
+	}
+
+	private ProjectReference getSelecteItem() {
+		return projectList.getSelectionModel().getSelectedItem();
+	}
+
+	private ProjectReference getSelectedProject() {
+		return getSelecteItem();
+	}
+
+	private void selectProject(ProjectReference ref) {
+		projectList.getSelectionModel().select(ref);
+	}
+
+	@Override
+	public void notify(String text, long duration) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showAndHide(text, duration);
+		} else {
+			Platform.runLater(() -> notificationPane.showAndHide(text, duration));
+		}
+	}
+
+	@Override
+	public void notify(String text, long duration, Runnable finish) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showAndHide(text, duration, finish);
+		} else {
+			Platform.runLater(() -> notificationPane.showAndHide(text, duration, finish));
+		}
+	}
+
+	@Override
+	public void showError(String message) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showError(message);
+		} else {
+			Platform.runLater(() -> notificationPane.showError(message));
+		}
+	}
+
+	@Override
+	public void hide() {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.hide();
+		} else {
+			Platform.runLater(() -> notificationPane.hide());
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/UpdaterDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/UpdaterDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..6143bc834cdf0810172eef642d3453118feb3e44
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/UpdaterDialog.java
@@ -0,0 +1,30 @@
+package de.tobias.playpad.viewcontroller.dialog;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.Label;
+import javafx.scene.image.ImageView;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class UpdaterDialog extends Dialog<Void> {
+
+	public UpdaterDialog(Window owner) {
+		setHeaderText(Localization.getString(Strings.UI_Dialog_DragAndDrop_Header));
+		setGraphic(new ImageView("org/controlsfx/dialog/dialog-information.png"));
+
+		Label textLabel = new Label(
+				"Die Aktualisierung wird vorbereitet. Bitte schließen Sie nicht das Programm. \nDieser Vorgang kann wenige Minuten dauern.");
+		textLabel.setWrapText(true);
+		textLabel.setMaxWidth(450);
+		getDialogPane().setContent(textLabel);
+
+		initOwner(owner);
+		initModality(Modality.WINDOW_MODAL);
+		Stage dialogStage = (Stage) getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(dialogStage.getIcons()::add);
+	}
+}
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ClassicLayoutCartViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ClassicLayoutCartViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..197ff4d30e76056f5c313d784f68b031c080747e
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ClassicLayoutCartViewController.java
@@ -0,0 +1,95 @@
+package de.tobias.playpad.viewcontroller.layout;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.classic.ClassicCartLayout;
+import de.tobias.playpad.viewcontroller.CartLayoutViewController;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.paint.Color;
+
+public class ClassicLayoutCartViewController extends CartLayoutViewController {
+
+	private ClassicCartLayout layout;
+
+	@FXML private ColorPicker playgroundColorPicker;
+	@FXML private ColorPicker backgroundColorPicker;
+	@FXML private ColorPicker warnColorPicker;
+	@FXML private ColorPicker fadeColorPicker;
+
+	@FXML private ColorPicker infoLabelColorPicker;
+	@FXML private ColorPicker titleLabelColorPicker;
+
+	@FXML private Button resetButton;
+
+	public ClassicLayoutCartViewController(CartLayout layout) {
+		super("classicLayoutCart", "de/tobias/playpad/assets/view/option/layout/", PlayPadMain.getUiResourceBundle(), layout);
+		setLayout((ClassicCartLayout) layout);
+	}
+
+	@Override
+	public void init() {
+		backgroundColorPicker.valueProperty().addListener((a, b, c) ->
+		{
+			if (c.getOpacity() > 0.5) {
+				backgroundColorPicker.setValue(new Color(c.getRed(), c.getGreen(), c.getBlue(), 0.5));
+				return;
+			}
+			layout.setBackgroundColor(c);
+		});
+		playgroundColorPicker.valueProperty().addListener((a, b, c) ->
+		{
+			if (c.getOpacity() > 0.75) {
+				playgroundColorPicker.setValue(new Color(c.getRed(), c.getGreen(), c.getBlue(), 0.75));
+				return;
+			}
+			layout.setPlaybackColor(c);
+		});
+
+		warnColorPicker.valueProperty().addListener((a, b, c) ->
+		{
+			if (c.getOpacity() > 0.75) {
+				warnColorPicker.setValue(new Color(c.getRed(), c.getGreen(), c.getBlue(), 0.75));
+				return;
+			}
+			layout.setWarnColor(c);
+		});
+
+		fadeColorPicker.valueProperty().addListener((a, b, c) ->
+		{
+			if (c.getOpacity() > 0.75) {
+				fadeColorPicker.setValue(new Color(c.getRed(), c.getGreen(), c.getBlue(), 0.75));
+				return;
+			}
+			layout.setFadeColor(c);
+		});
+
+		infoLabelColorPicker.valueProperty().addListener((a, b, c) -> layout.setInfoLabelColor(c));
+		titleLabelColorPicker.valueProperty().addListener((a, b, c) -> layout.setTitleLabelColor(c));
+	}
+
+	public void setLayout(ClassicCartLayout defaultLayout) {
+		this.layout = defaultLayout;
+
+		backgroundColorPicker.setValue(layout.getBackgroundColor());
+		playgroundColorPicker.setValue(layout.getPlaybackColor());
+		warnColorPicker.setValue(layout.getWarnColor());
+		fadeColorPicker.setValue(layout.getFadeColor());
+
+		infoLabelColorPicker.setValue(layout.getInfoLabelColor());
+		titleLabelColorPicker.setValue(layout.getTitleLabelColor());
+	}
+
+	@FXML
+	private void resetButtonHandler(ActionEvent event) {
+		layout.reset();
+		setLayout(layout);
+	}
+
+	@Override
+	public void updateData() {
+		backgroundColorPicker.setValue(layout.getBackgroundColor());
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ClassicLayoutGlobalViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ClassicLayoutGlobalViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..780435cc39b4974383dd0ecde0539ecd961610ec
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ClassicLayoutGlobalViewController.java
@@ -0,0 +1,169 @@
+package de.tobias.playpad.viewcontroller.layout;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.layout.GlobalLayout;
+import de.tobias.playpad.layout.LayoutConnect;
+import de.tobias.playpad.layout.classic.ClassicGlobalLayout;
+import de.tobias.playpad.layout.classic.Theme;
+import de.tobias.playpad.viewcontroller.GlobalLayoutViewController;
+import de.tobias.playpad.viewcontroller.cell.ThemeCell;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.control.ComboBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.util.converter.IntegerStringConverter;
+
+public class ClassicLayoutGlobalViewController extends GlobalLayoutViewController {
+
+	private ClassicGlobalLayout layout;
+
+	@FXML private ComboBox<LayoutConnect> layoutTypeComboBox;
+
+	@FXML private ComboBox<Theme> programLayoutComboBox;
+	@FXML private ColorPicker accentColorChooser;
+	@FXML private CheckBox customLayoutCheckBox;
+
+	@FXML private VBox customizeView;
+
+	@FXML private ColorPicker playgroundColorPicker;
+	@FXML private ColorPicker backgroundColorPicker;
+	@FXML private ColorPicker warnColorPicker;
+	@FXML private ColorPicker fadeColorPicker;
+
+	@FXML private ColorPicker infoLabelColorPicker;
+	@FXML private ComboBox<Integer> infoLabelFontSizeComboBox;
+
+	@FXML private ColorPicker titleLabelColorPicker;
+	@FXML private ComboBox<Integer> titleLabelFontSizeComboBox;
+
+	@FXML private Button resetButton;
+
+	public ClassicLayoutGlobalViewController(GlobalLayout layout) {
+		super("classicLayoutGlobal", "de/tobias/playpad/assets/view/option/layout/", PlayPadMain.getUiResourceBundle(), layout);
+		setLayout((ClassicGlobalLayout) layout);
+
+		ClassicGlobalLayout cl = (ClassicGlobalLayout) layout;
+		programLayoutComboBox.valueProperty().bindBidirectional(cl.themeProperty());
+		accentColorChooser.setValue(cl.getAccentColor());
+		customLayoutCheckBox.setSelected(cl.isCustomLayout());
+
+		customizeView.setDisable(!cl.isCustomLayout());
+	}
+
+	@Override
+	public void init() {
+		backgroundColorPicker.valueProperty().addListener((a, b, c) ->
+		{
+			if (c.getOpacity() > 0.5) {
+				backgroundColorPicker.setValue(new Color(c.getRed(), c.getGreen(), c.getBlue(), 0.5));
+				return;
+			}
+			layout.setBackgroundColor(c);
+		});
+		playgroundColorPicker.valueProperty().addListener((a, b, c) ->
+		{
+			if (c.getOpacity() > 0.75) {
+				playgroundColorPicker.setValue(new Color(c.getRed(), c.getGreen(), c.getBlue(), 0.75));
+				return;
+			}
+			layout.setPlaybackColor(c);
+		});
+
+		warnColorPicker.valueProperty().addListener((a, b, c) ->
+		{
+			if (c.getOpacity() > 0.75) {
+				warnColorPicker.setValue(new Color(c.getRed(), c.getGreen(), c.getBlue(), 0.75));
+				return;
+			}
+			layout.setWarnColor(c);
+		});
+
+		fadeColorPicker.valueProperty().addListener((a, b, c) ->
+		{
+			if (c.getOpacity() > 0.75) {
+				fadeColorPicker.setValue(new Color(c.getRed(), c.getGreen(), c.getBlue(), 0.75));
+				return;
+			}
+			layout.setFadeColor(c);
+		});
+
+		infoLabelColorPicker.valueProperty().addListener((a, b, c) -> layout.setInfoLabelColor(c));
+		infoLabelFontSizeComboBox.getItems().addAll(9, 10, 12, 13, 14, 16, 18, 20, 24, 28);
+		infoLabelFontSizeComboBox.valueProperty().addListener((a, b, c) ->
+		{
+			try {
+				layout.setInfoLabelFontSize(c);
+				infoLabelFontSizeComboBox.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false);
+			} catch (NumberFormatException e) {
+				infoLabelFontSizeComboBox.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true);
+			}
+		});
+		infoLabelFontSizeComboBox.setConverter(new IntegerStringConverter());
+
+		titleLabelColorPicker.valueProperty().addListener((a, b, c) -> layout.setTitleLabelColor(c));
+		titleLabelFontSizeComboBox.getItems().addAll(9, 10, 12, 13, 14, 16, 18, 20, 24, 28);
+		titleLabelFontSizeComboBox.valueProperty().addListener((a, b, c) ->
+		{
+			try {
+				layout.setTitleLabelFontSize(c);
+				titleLabelFontSizeComboBox.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false);
+			} catch (NumberFormatException e) {
+				titleLabelFontSizeComboBox.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true);
+			}
+		});
+		titleLabelFontSizeComboBox.setConverter(new IntegerStringConverter());
+
+		programLayoutComboBox.getItems().addAll(Theme.values());
+		programLayoutComboBox.setButtonCell(new ThemeCell());
+		programLayoutComboBox.setCellFactory(list -> new ThemeCell());
+		programLayoutComboBox.valueProperty().addListener((a, b, c) ->
+		{
+			if (b != null) {
+				layout.setBackgroundColor(c.getBackground());
+				layout.setAccentColor(c.getGridColor());
+				backgroundColorPicker.setValue(c.getBackground());
+				accentColorChooser.setValue(c.getGridColor());
+			}
+		});
+		accentColorChooser.valueProperty().addListener((a, b, c) ->
+		{
+			layout.setAccentColor(c);
+		});
+		customLayoutCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			layout.setCustomLayout(c);
+			customizeView.setDisable(!c);
+		});
+	}
+
+	public void setLayout(ClassicGlobalLayout defaultLayout) {
+		this.layout = defaultLayout;
+
+		backgroundColorPicker.setValue(layout.getBackgroundColor());
+		playgroundColorPicker.setValue(layout.getPlaybackColor());
+		warnColorPicker.setValue(layout.getWarnColor());
+		fadeColorPicker.setValue(layout.getFadeColor());
+
+		infoLabelColorPicker.setValue(layout.getInfoLabelColor());
+		infoLabelFontSizeComboBox.setValue(layout.getInfoLabelFontSize());
+
+		titleLabelColorPicker.setValue(layout.getTitleLabelColor());
+		titleLabelFontSizeComboBox.setValue(layout.getTitleLabelFontSize());
+	}
+
+	@FXML
+	private void resetButtonHandler(ActionEvent event) {
+		layout.reset();
+		setLayout(layout);
+	}
+
+	@Override
+	public void updateData() {
+		backgroundColorPicker.setValue(layout.getBackgroundColor());
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutCartViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutCartViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd3e7bd2cfe6f21f8ab1fbe39d609185c2cb9930
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutCartViewController.java
@@ -0,0 +1,99 @@
+package de.tobias.playpad.viewcontroller.layout;
+
+import java.util.function.Consumer;
+
+import org.controlsfx.control.PopOver;
+import org.controlsfx.control.PopOver.ArrowLocation;
+
+import de.tobias.playpad.DisplayableColor;
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.modern.ModernColor;
+import de.tobias.playpad.layout.modern.ModernLayoutCart;
+import de.tobias.playpad.view.ColorView;
+import de.tobias.playpad.viewcontroller.CartLayoutViewController;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+
+public class ModernLayoutCartViewController extends CartLayoutViewController {
+
+	@FXML private Button backgroundColorButton;
+	@FXML private Button playColorButton;
+	@FXML private CheckBox warnAnimationCheckBox;
+
+	@FXML private Button resetButton;
+
+	private ModernLayoutCart cartLayout;
+
+	private PopOver colorChooser;
+
+	public ModernLayoutCartViewController(CartLayout layout) {
+		super("modernLayoutCart", "de/tobias/playpad/assets/view/option/layout/", PlayPadMain.getUiResourceBundle(), layout);
+
+		if (layout instanceof CartLayout) {
+			this.cartLayout = (ModernLayoutCart) layout;
+
+			setLayout();
+		}
+	}
+
+	private void setLayout() {
+		backgroundColorButton.setStyle(getLinearGradientCss(cartLayout.getBackgroundColor()));
+		playColorButton.setStyle(getLinearGradientCss(cartLayout.getPlayColor()));
+
+		warnAnimationCheckBox.setSelected(cartLayout.isWarnAnimation());
+	}
+
+	@Override
+	public void init() {
+		warnAnimationCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			cartLayout.setWarnAnimation(c);
+		});
+	}
+
+	@FXML
+	private void resetButtonHandler(ActionEvent event) {
+		cartLayout.reset();
+		setLayout();
+	}
+
+	@FXML
+	private void backgroundColorButtonHandler(ActionEvent event) {
+		colorChooser(backgroundColorButton, cartLayout.getBackgroundColor(), (color) -> cartLayout.setBackgroundColor(color));
+	}
+
+	@FXML
+	private void playColorButtonHandler(ActionEvent event) {
+		colorChooser(playColorButton, cartLayout.getPlayColor(), (color) -> cartLayout.setPlayColor(color));
+	}
+
+	private void colorChooser(Button anchorNode, ModernColor startColor, Consumer<ModernColor> onFinish) {
+		ColorView view = new ColorView(startColor, ModernColor.values(), (DisplayableColor t) ->
+		{
+			colorChooser.hide();
+
+			if (t instanceof ModernColor) {
+				ModernColor color = (ModernColor) t;
+				onFinish.accept(color);
+				anchorNode.setStyle(getLinearGradientCss(color));
+			}
+		});
+		colorChooser = new PopOver();
+		colorChooser.setContentNode(view);
+		colorChooser.setDetachable(false);
+		colorChooser.setOnHiding(e -> colorChooser = null);
+		colorChooser.setCornerRadius(5);
+		colorChooser.setArrowLocation(ArrowLocation.LEFT_CENTER);
+		colorChooser.show(anchorNode);
+	}
+
+	private String getLinearGradientCss(ModernColor color) {
+		String css = "-fx-background-color: " + color.linearGradient() + ";";
+		css += "-fx-border-color: rgb(20, 20, 20);-fx-border-width: 1.5px;-fx-border-radius: 3px;";
+		return css;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutGlobalViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutGlobalViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..bbda3b0d30dddff4c980f601cd70b1bb8876fc15
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutGlobalViewController.java
@@ -0,0 +1,122 @@
+package de.tobias.playpad.viewcontroller.layout;
+
+import java.util.function.Consumer;
+
+import org.controlsfx.control.PopOver;
+import org.controlsfx.control.PopOver.ArrowLocation;
+
+import de.tobias.playpad.DisplayableColor;
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.layout.GlobalLayout;
+import de.tobias.playpad.layout.modern.ModernColor;
+import de.tobias.playpad.layout.modern.ModernLayoutGlobal;
+import de.tobias.playpad.view.ColorView;
+import de.tobias.playpad.viewcontroller.GlobalLayoutViewController;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.util.converter.IntegerStringConverter;
+
+public class ModernLayoutGlobalViewController extends GlobalLayoutViewController {
+
+	@FXML private Button backgroundColorButton;
+	@FXML private Button playColorButton;
+
+	@FXML private CheckBox warnAnimationCheckBox;
+
+	@FXML private ComboBox<Integer> infoLabelFontSizeComboBox;
+	@FXML private ComboBox<Integer> titleLabelFontSizeComboBox;
+
+	@FXML private Button resetButton;
+
+	private ModernLayoutGlobal globalLayout;
+
+	private PopOver colorChooser;
+
+	public ModernLayoutGlobalViewController(GlobalLayout layout) {
+		super("modernLayoutGlobal", "de/tobias/playpad/assets/view/option/layout/", PlayPadMain.getUiResourceBundle(), layout);
+
+		if (layout instanceof GlobalLayout) {
+			this.globalLayout = (ModernLayoutGlobal) layout;
+
+			setLayout();
+		}
+	}
+
+	private void setLayout() {
+		backgroundColorButton.setStyle(getLinearGradientCss(globalLayout.getBackgroundColor()));
+		playColorButton.setStyle(getLinearGradientCss(globalLayout.getPlayColor()));
+
+		warnAnimationCheckBox.setSelected(globalLayout.isWarnAnimation());
+
+		infoLabelFontSizeComboBox.setValue(globalLayout.getInfoFontSize());
+		titleLabelFontSizeComboBox.setValue(globalLayout.getTitleFontSize());
+	}
+
+	@Override
+	public void init() {
+		warnAnimationCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			globalLayout.setWarnAnimation(c);
+		});
+
+		infoLabelFontSizeComboBox.getItems().addAll(9, 10, 12, 13, 14, 16, 18, 20, 24, 28);
+		infoLabelFontSizeComboBox.valueProperty().addListener((a, b, c) ->
+		{
+			globalLayout.setInfoFontSize(c);
+		});
+		infoLabelFontSizeComboBox.setConverter(new IntegerStringConverter());
+
+		titleLabelFontSizeComboBox.getItems().addAll(9, 10, 12, 13, 14, 16, 18, 20, 24, 28);
+		titleLabelFontSizeComboBox.valueProperty().addListener((a, b, c) ->
+		{
+			globalLayout.setTitleFontSize(c);
+		});
+		titleLabelFontSizeComboBox.setConverter(new IntegerStringConverter());
+	}
+
+	@FXML
+	private void resetButtonHandler(ActionEvent event) {
+		globalLayout.reset();
+		setLayout();
+	}
+
+	@FXML
+	private void backgroundColorButtonHandler(ActionEvent event) {
+		colorChooser(backgroundColorButton, globalLayout.getBackgroundColor(), (color) -> globalLayout.setBackgroundColor(color));
+	}
+
+	@FXML
+	private void playColorButtonHandler(ActionEvent event) {
+		colorChooser(playColorButton, globalLayout.getPlayColor(), (color) -> globalLayout.setPlayColor(color));
+	}
+
+	private void colorChooser(Button anchorNode, ModernColor startColor, Consumer<ModernColor> onFinish) {
+		ColorView view = new ColorView(startColor, ModernColor.values(), (DisplayableColor t) ->
+		{
+			colorChooser.hide();
+
+			if (t instanceof ModernColor) {
+				ModernColor color = (ModernColor) t;
+				onFinish.accept(color);
+				anchorNode.setStyle(getLinearGradientCss(color));
+			}
+		});
+		colorChooser = new PopOver();
+		colorChooser.setContentNode(view);
+		colorChooser.setDetachable(false);
+		colorChooser.setOnHiding(e -> colorChooser = null);
+		colorChooser.setCornerRadius(5);
+		colorChooser.setArrowLocation(ArrowLocation.LEFT_CENTER);
+		colorChooser.show(anchorNode);
+	}
+
+	private String getLinearGradientCss(ModernColor color) {
+		String css = "-fx-background-color: " + color.linearGradient() + ";";
+		css += "-fx-border-color: rgb(20, 20, 20);-fx-border-width: 1.5px;-fx-border-radius: 3px;";
+		return css;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java
new file mode 100644
index 0000000000000000000000000000000000000000..e905a558857e8aa68ed3260bf968260addc08539
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java
@@ -0,0 +1,361 @@
+package de.tobias.playpad.viewcontroller.main;
+
+import java.awt.Desktop;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Optional;
+import java.util.ResourceBundle;
+
+import de.tobias.playpad.AppUserInfoStrings;
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.cartaction.CartAction;
+import de.tobias.playpad.action.connect.CartActionConnect;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.pad.view.IPadViewController;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.ProjectNotFoundException;
+import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileNotFoundException;
+import de.tobias.playpad.viewcontroller.PluginViewController;
+import de.tobias.playpad.viewcontroller.PrintDialog;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.viewcontroller.dialog.ErrorSummaryDialog;
+import de.tobias.playpad.viewcontroller.dialog.ImportDialog;
+import de.tobias.playpad.viewcontroller.dialog.NewProjectDialog;
+import de.tobias.playpad.viewcontroller.dialog.ProfileViewController;
+import de.tobias.playpad.viewcontroller.dialog.ProjectManagerDialog;
+import de.tobias.playpad.viewcontroller.option.SettingsViewController;
+import de.tobias.playpad.viewcontroller.pad.PadDragListener;
+import de.tobias.utils.application.ApplicationInfo;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.OS;
+import de.tobias.utils.util.OS.OSType;
+import de.tobias.utils.util.Worker;
+import de.tobias.utils.util.net.FileUpload;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.CheckMenuItem;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuBar;
+import javafx.scene.control.MenuItem;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import net.xeoh.plugins.base.PluginManager;
+
+public class MainMenuBarController implements EventHandler<ActionEvent>, Initializable {
+
+	@FXML private MenuBar menuBar;
+	@FXML CheckMenuItem dndModeMenuItem;
+	@FXML CheckMenuItem alwaysOnTopItem;
+	@FXML CheckMenuItem fullScreenMenuItem;
+	@FXML Menu recentOpenMenu;
+	@FXML MenuItem profileMenu;
+
+	@FXML CheckMenuItem quickEditMenuItem;
+	@FXML MenuItem settingsMenuItem;
+
+	@FXML Menu extensionMenu;
+
+	// Open Windows
+	private SettingsViewController settingsViewController;
+	private PluginManager manager;
+	private MainViewController mvc;
+
+	@Override
+	public void initialize(URL location, ResourceBundle resources) {
+		menuBar.setUseSystemMenuBar(true);
+
+		if (OS.getType() == OSType.MacOSX) {
+			menuBar.setMaxHeight(0);
+		}
+	}
+
+	// Event
+	@FXML
+	private void newDocumentHandler(ActionEvent event) {
+		doAction(() ->
+		{
+			NewProjectDialog dialog = new NewProjectDialog(mvc.getStage());
+			dialog.getStage().showAndWait();
+
+			Project project = dialog.getProject();
+			if (project != null) {
+				mvc.setProject(project);
+				mvc.showPage(0);
+			}
+		});
+	}
+
+	@FXML
+	private void openDocumentHandler(ActionEvent event) {
+		doAction(() ->
+		{
+			ProjectManagerDialog view = new ProjectManagerDialog(mvc.getStage(), mvc.getProject());
+			Optional<ProjectReference> result = view.showAndWait();
+			if (result.isPresent()) {
+				ProjectReference ref = result.get();
+				try {
+					Project project = Project.load(result.get(), true, ImportDialog.getInstance(mvc.getStage()));
+					mvc.setProject(project);
+
+					mvc.showPage(0);
+					createRecentDocumentMenuItems();
+				} catch (ProfileNotFoundException e) {
+					e.printStackTrace();
+					mvc.showErrorMessage(
+							Localization.getString(Strings.Error_Profile_NotFound, ref.getProfileReference(), e.getLocalizedMessage()));
+
+					// Neues Profile wählen
+					Profile profile = ImportDialog.getInstance(mvc.getStage()).getUnkownProfile();
+					ref.setProfileReference(profile.getRef());
+				} catch (ProjectNotFoundException e) {
+					e.printStackTrace();
+					mvc.showErrorMessage(Localization.getString(Strings.Error_Project_NotFound, ref, e.getLocalizedMessage()));
+				} catch (Exception e) {
+					e.printStackTrace();
+					mvc.showErrorMessage(Localization.getString(Strings.Error_Project_Open, ref, e.getLocalizedMessage()));
+				}
+			}
+		});
+	}
+
+	@FXML
+	private void saveMenuHandler(ActionEvent event) {
+		try {
+			mvc.getProject().save();
+			mvc.notify(Localization.getString(Strings.Standard_File_Save), PlayPadMain.notificationDisplayTimeMillis);
+		} catch (IOException e) {
+			mvc.showError(Localization.getString(Strings.Error_Project_Save));
+			e.printStackTrace();
+		}
+	}
+
+	// Einstellungsmenu
+	@FXML
+	private void profileMenuHandler(ActionEvent event) {
+		doAction(() ->
+		{
+			ProfileViewController controller = new ProfileViewController(mvc.getStage(), mvc.getProject());
+			controller.getStage().showAndWait();
+		});
+	}
+
+	@FXML
+	private void quickEditMenuHandler(ActionEvent event) {
+		try {
+			for (Action action : Profile.currentProfile().getMappings().getActiveMapping().getActionsOfType(CartActionConnect.TYPE)) {
+				CartAction cartAction = (CartAction) action;
+				if (cartAction.getCart() < mvc.padViewList.size()) {
+					cartAction.getPad().getController().getParent().setBusy(quickEditMenuItem.isSelected());
+					// IPadViewController controller = mvc.padViewList.get(cartAction.getCart());
+					// MapperQuickSettingsView view = new MapperQuickSettingsView((Pane) controller.getParent().getParent());
+					// view.showDropOptions(action.getMappers());
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	@FXML
+	private void settingsHandler(ActionEvent event) {
+		Midi midi = Midi.getInstance();
+
+		if (settingsViewController == null) {
+			settingsViewController = new SettingsViewController(midi, mvc.getScreen(), mvc.getStage(), mvc.getProject()) {
+
+				@Override
+				public void updateData() {
+					midi.setListener(mvc.getMidiHandler());
+
+					boolean change = false;
+					for (SettingsTabViewController controller : tabs) {
+						if (controller.needReload()) {
+							change = true;
+							controller.reload(Profile.currentProfile(), mvc.getProject(), mvc);
+						}
+					}
+
+					if (change) {
+						PlayPadPlugin.getImplementation().getSettingsListener().forEach(l -> l.onChange(Profile.currentProfile()));
+					}
+
+					settingsViewController = null;
+					mvc.getStage().toFront();
+				}
+			};
+
+			settingsViewController.getStage().show();
+		} else if (settingsViewController.getStage().isShowing()) {
+			settingsViewController.getStage().toFront();
+		}
+	}
+
+	@FXML
+	private void printMenuHandler(ActionEvent event) {
+		PrintDialog dialog = new PrintDialog(mvc.getProject(), mvc.getStage());
+		dialog.getStage().show();
+	}
+
+	@FXML
+	private void alwaysOnTopItemHandler(ActionEvent event) {
+		mvc.getStage().setAlwaysOnTop(alwaysOnTopItem.isSelected());
+		Profile.currentProfile().getProfileSettings().setWindowAlwaysOnTop(alwaysOnTopItem.isSelected());
+	}
+
+	@FXML
+	private void fullScreenMenuItemHandler(ActionEvent event) {
+		mvc.getStage().setFullScreen(fullScreenMenuItem.isSelected());
+	}
+
+	@FXML
+	private void dndModeHandler(ActionEvent event) {
+		if (dndModeMenuItem.isSelected()) {
+			doAction(() ->
+			{
+				PadDragListener.setDndMode(true);
+				for (IPadViewController view : mvc.padViewList) {
+					view.showDnDLayout(true);
+				}
+			});
+		} else {
+			PadDragListener.setDndMode(false);
+			for (IPadViewController view : mvc.padViewList) {
+				view.showDnDLayout(false);
+			}
+		}
+	}
+
+	@FXML
+	private void errorMenuHandler(ActionEvent event) {
+		ErrorSummaryDialog.getInstance().getStage().show();
+	}
+
+	@FXML
+	private void aboutMenuHandler(ActionEvent event) {
+		ApplicationInfo info = ApplicationUtils.getApplication().getInfo();
+		String message = Localization.getString(Strings.UI_Dialog_Info_Content, info.getVersion(), info.getBuild(), info.getAuthor());
+		mvc.showInfoMessage(message, Localization.getString(Strings.UI_Dialog_Info_Header, info.getName()), PlayPadMain.stageIcon.orElse(null));
+	}
+
+	@FXML
+	private void visiteWebsiteMenuHandler(ActionEvent event) {
+		String website = ApplicationUtils.getApplication().getInfo().getUserInfo().getString(AppUserInfoStrings.WEBSITE);
+		try {
+			Desktop.getDesktop().browse(new URI(website));
+		} catch (IOException | URISyntaxException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@FXML
+	private void sendErrorMenuItem(ActionEvent event) {
+		Alert alert = new Alert(AlertType.INFORMATION);
+		alert.initOwner(mvc.getStage());
+		alert.initModality(Modality.WINDOW_MODAL);
+		Stage dialog = (Stage) alert.getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add);
+		alert.setContentText(Localization.getString(Strings.UI_Dialog_Feedback_Content));
+		alert.show();
+
+		Worker.runLater(() ->
+		{
+			try {
+				String response = FileUpload.fileUpload(
+						ApplicationUtils.getApplication().getInfo().getUserInfo().getString(AppUserInfoStrings.ERROR_URL),
+						ApplicationUtils.getApplication().getPath(PathType.LOG, "err.log").toFile());
+				Platform.runLater(() -> alert.setContentText(response));
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		});
+	}
+
+	@FXML
+	private void pluginMenuItemHandler(ActionEvent e) {
+		doAction(() ->
+		{
+			PluginViewController controller = new PluginViewController(manager, mvc.getStage());
+			controller.getStage().showAndWait();
+			mvc.showPage(mvc.getPage());
+		});
+	}
+
+	@Override
+	public void handle(ActionEvent event) {
+		if (event.getSource() instanceof MenuItem) {
+			// Zuletzt verwendete Projects
+			doAction(() ->
+			{
+				MenuItem item = (MenuItem) event.getSource();
+				ProjectReference ref = (ProjectReference) item.getUserData();
+				try {
+					// Speichern das alte Project in mvc.setProject(Project)
+					Project project = Project.load(ref, true, ImportDialog.getInstance(mvc.getStage()));
+					mvc.setProject(project);
+					mvc.showPage(0);
+				} catch (ProfileNotFoundException e) {
+					e.printStackTrace();
+					mvc.showErrorMessage(
+							Localization.getString(Strings.Error_Profile_NotFound, ref.getProfileReference(), e.getLocalizedMessage()));
+
+					// Neues Profile wählen
+					Profile profile = ImportDialog.getInstance(mvc.getStage()).getUnkownProfile();
+					ref.setProfileReference(profile.getRef());
+				} catch (ProjectNotFoundException e) {
+					e.printStackTrace();
+					mvc.showErrorMessage(Localization.getString(Strings.Error_Project_NotFound, ref, e.getLocalizedMessage()));
+				} catch (Exception e) {
+					e.printStackTrace();
+					mvc.showErrorMessage(Localization.getString(Strings.Error_Project_Open, ref, e.getLocalizedMessage()));
+				}
+			});
+		}
+	}
+
+	private void doAction(Runnable run) {
+		if (mvc.getProject().getPlayedPlayers() > 0 && Profile.currentProfile().getProfileSettings().isLiveMode()) {
+			mvc.showLiveInfo();
+		} else {
+			run.run();
+		}
+	}
+
+	private final int LAST_DOCUMENT_LIMIT = 3;
+
+	public void createRecentDocumentMenuItems() {
+		recentOpenMenu.getItems().clear();
+
+		String project = mvc.getProject().getRef().getName();
+
+		ProjectReference.getProjectsSorted().stream().filter(item -> !item.getName().equals(project)).limit(LAST_DOCUMENT_LIMIT).forEach(item ->
+		{
+			MenuItem menuItem = new MenuItem(item.toString());
+			menuItem.setUserData(item);
+			menuItem.setOnAction(this);
+			recentOpenMenu.getItems().add(menuItem);
+		});
+	}
+
+	public void setPluginManager(PluginManager manager) {
+		this.manager = manager;
+	}
+
+	public void setMainViewController(MainViewController mvc) {
+		this.mvc = mvc;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainToolbarController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainToolbarController.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b582c60879890a4c9184769cdb0d7f3eba2f68a
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainToolbarController.java
@@ -0,0 +1,88 @@
+package de.tobias.playpad.viewcontroller.main;
+
+import java.net.URL;
+import java.util.ResourceBundle;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.main.IMainToolbarViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.Slider;
+import javafx.scene.control.ToolBar;
+import javafx.scene.layout.HBox;
+
+public class MainToolbarController implements IMainToolbarViewController, Initializable, EventHandler<ActionEvent> {
+
+	@FXML private ToolBar toolbar;
+	@FXML private HBox toolbarHBox;
+	@FXML private HBox pageHBox;
+
+	@FXML private Label volumeDownLabel;
+	@FXML private Slider volumeSlider;
+	@FXML private Label volumeUpLabel;
+
+	private MainViewController mainViewController;
+
+	@Override
+	public void initialize(URL location, ResourceBundle resources) {
+
+		// HBox Child wird Max Width, subtract weil sonst zu groß für Toolbar
+		toolbarHBox.prefWidthProperty().bind(toolbar.widthProperty().subtract(25));
+		toolbarHBox.prefHeightProperty().bind(toolbar.minHeightProperty());
+
+		// Icons Volume
+		volumeDownLabel.setGraphic(new FontIcon("volume-item", FontAwesomeType.VOLUME_DOWN));
+		volumeUpLabel.setGraphic(new FontIcon("volume-item", FontAwesomeType.VOLUME_UP));
+
+		volumeSlider.setOnScroll(ev ->
+		{
+			volumeSlider.setValue(volumeSlider.getValue() - ev.getDeltaY() * 0.001);
+			volumeSlider.setValue(volumeSlider.getValue() + ev.getDeltaX() * 0.001);
+		});
+	}
+
+	public void createPageButtons() {
+		pageHBox.getChildren().clear();
+		for (int i = 0; i < Profile.currentProfile().getProfileSettings().getPageCount(); i++) {
+			Button item = new Button(Localization.getString(Strings.UI_Window_Main_PageButton, (i + 1)));
+			item.setUserData(i);
+			item.setFocusTraversable(false);
+			item.setOnAction(this);
+			pageHBox.getChildren().add(item);
+		}
+	}
+
+	public HBox getPageHBox() {
+		return pageHBox;
+	}
+
+	public HBox getToolbarHBox() {
+		return toolbarHBox;
+	}
+
+	public Slider getVolumeSlider() {
+		return volumeSlider;
+	}
+
+	public void setMainViewController(MainViewController mainViewController) {
+		this.mainViewController = mainViewController;
+	}
+
+	@Override
+	public void handle(ActionEvent event) {
+		if (event.getSource() instanceof Button) {
+			// Page Buttons
+			Button item = (Button) event.getSource();
+			int number = (int) item.getUserData();
+			mainViewController.showPage(number);
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..a1811badf7ce2fcbf7173269c3502048bc7b70f7
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java
@@ -0,0 +1,645 @@
+package de.tobias.playpad.viewcontroller.main;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import javax.sound.midi.MidiUnavailableException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.cartaction.CartAction;
+import de.tobias.playpad.action.connect.CartActionConnect;
+import de.tobias.playpad.action.feedback.ColorAssociator;
+import de.tobias.playpad.action.feedback.DisplayableFeedbackColor;
+import de.tobias.playpad.action.feedback.FeedbackMessage;
+import de.tobias.playpad.action.mapper.Mapper;
+import de.tobias.playpad.action.mapper.MapperFeedbackable;
+import de.tobias.playpad.action.mapper.listener.KeyboardHandler;
+import de.tobias.playpad.action.mapper.listener.MidiHandler;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.GlobalLayout;
+import de.tobias.playpad.layout.LayoutColorAssociator;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.view.IPadViewController;
+import de.tobias.playpad.plugin.WindowListener;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileListener;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.playpad.view.PadView;
+import de.tobias.playpad.viewcontroller.IPadView;
+import de.tobias.playpad.viewcontroller.dialog.ErrorSummaryDialog;
+import de.tobias.playpad.viewcontroller.pad.PadDragListener;
+import de.tobias.playpad.viewcontroller.pad.PadViewController;
+import de.tobias.utils.ui.BasicControllerSettings;
+import de.tobias.utils.ui.NotificationHandler;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.ui.scene.NotificationPane;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.OS;
+import de.tobias.utils.util.OS.OSType;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
+import javafx.fxml.FXML;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Label;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.Slider;
+import javafx.scene.input.KeyCombination;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.ColumnConstraints;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.RowConstraints;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Line;
+import javafx.stage.Modality;
+import javafx.stage.Screen;
+import javafx.stage.Stage;
+import net.xeoh.plugins.base.PluginManager;
+
+public class MainViewController extends ViewController implements IMainViewController, NotificationHandler, ProfileListener {
+
+	private static final String CURRENT_PAGE_BUTTON = "current-page-button";
+
+	// UI
+	@FXML protected MainMenuBarController menuBarController;
+	@FXML protected MainToolbarController toolbarController;
+	@FXML private GridPane padGridPane;
+
+	@FXML private Label liveLabel;
+
+	@FXML private AnchorPane gridContainer;
+	private NotificationPane notificationPane;
+
+	private ErrorSummaryDialog errorSummaryDialog;
+
+	// Model
+	private Project project;
+	protected List<IPadViewController> padViewList = new ArrayList<>();
+
+	// Current View Items
+	private int pageNumber;
+
+	// Mapper
+	private Midi midi;
+	private MidiHandler midiHandler;
+	private KeyboardHandler keyboardHandler;
+
+	// Style
+	private Color gridColor;
+
+	public MainViewController(Project project, List<WindowListener<IMainViewController>> listener, PluginManager manager) {
+		super("mainView", "de/tobias/playpad/assets/view/main/", null, PlayPadMain.getUiResourceBundle());
+
+		// Include FXML Setup
+		toolbarController.setMainViewController(this);
+		menuBarController.setMainViewController(this);
+		menuBarController.setPluginManager(manager);
+
+		padGridPane.setGridLinesVisible(true);
+
+		// Settings Setup
+		Profile.registerListener(this);
+
+		/*
+		 * Gridline Color
+		 */
+		try {
+			Field field = padGridPane.getClass().getDeclaredField("gridLines");
+			field.setAccessible(true);
+			Group group = (Group) field.get(padGridPane);
+			if (group != null) {
+				group.getChildren().addListener((javafx.collections.ListChangeListener.Change<? extends Node> c) ->
+				{
+					for (Node node : group.getChildren()) {
+						if (node instanceof Line) {
+							((Line) node).setStroke(gridColor);
+						}
+					}
+				});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		/*
+		 * Mapper Setup & Listener
+		 */
+		this.midi = Midi.getInstance();
+		this.midiHandler = new MidiHandler(midi, this, project);
+		this.midi.setListener(midiHandler);
+		this.keyboardHandler = new KeyboardHandler(project, this);
+
+		// Setup
+		errorSummaryDialog = new ErrorSummaryDialog(getStage());
+		getStage().toFront();
+
+		// setup project
+		setProject(project);
+
+		// Setup Settings
+		reloadSettings(null, Profile.currentProfile());
+
+		listener.forEach(l -> l.onInit(this));
+	}
+
+	@Override
+	public void init() {
+		padGridPane.getStyleClass().add("pad-grid");
+
+		menuBarController.extensionMenu.setVisible(false);
+
+		liveLabel.setVisible(false);
+		liveLabel.getStyleClass().add("live-label");
+
+		notificationPane = new NotificationPane(padGridPane);
+		notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK);
+
+		gridContainer.getChildren().add(notificationPane);
+		setAnchor(notificationPane, 0, 0, 0, 0);
+
+		getStage().fullScreenProperty().addListener((a, b, c) ->
+		{
+			menuBarController.fullScreenMenuItem.setSelected(c);
+		});
+
+		// Lautstärke Veränderung
+		toolbarController.getVolumeSlider().valueProperty().addListener((a, b, c) ->
+		{
+			setPadVolume(c.doubleValue());
+		});
+	}
+
+	private void setPadVolume(double volume) {
+		for (Pad pad : project.getPads().values()) {
+			pad.setMasterVolume(volume);
+		}
+	}
+
+	private void setTitle() {
+		if (project != null && Profile.currentProfile() != null) {
+			getStage().setTitle(Localization.getString(Strings.UI_Window_Main_Title, project.getRef().getName(),
+					Profile.currentProfile().getRef().getName()));
+		} else {
+			getStage().setTitle(Localization.getString(Strings.UI_Window_Main_Title));
+		}
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+		stage.setFullScreenExitKeyCombination(KeyCombination.keyCombination(KeyCombination.SHIFT_DOWN + "+Esc"));
+		stage.setTitle(Localization.getString(Strings.UI_Window_Main_Title));
+		stage.show();
+	}
+
+	@Override
+	protected void loadSettings(BasicControllerSettings settings) {
+		List<Screen> screens = Screen.getScreensForRectangle(settings.getUserInfoAsDouble("x"), settings.getUserInfoAsDouble("y"),
+				settings.width, settings.height);
+		if (!screens.isEmpty()) {
+			getStage().setX(settings.getUserInfoAsDouble("x"));
+			getStage().setY(settings.getUserInfoAsDouble("y"));
+		}
+
+		getStage().setWidth(settings.width);
+		getStage().setHeight(settings.height);
+	}
+
+	@Override
+	protected void save(BasicControllerSettings settings) {
+		settings.addUserInfo("x", getStage().getX());
+		settings.addUserInfo("y", getStage().getY());
+		settings.width = getStage().getWidth();
+		settings.height = getStage().getHeight();
+	}
+
+	public void setProject(Project project) {
+		if (this.project != null) {
+			for (IPadViewController controller : padViewList) {
+				controller.unconnectPad();
+			}
+			try {
+				this.project.save();
+			} catch (IOException e) {
+				e.printStackTrace();
+				showError(Localization.getString(Strings.Error_Project_Save, e.getLocalizedMessage()));
+			}
+		}
+		this.project = project;
+
+		midiHandler.setProject(project);
+		keyboardHandler.setProject(project);
+		PadDragListener.setProject(project);
+
+		errorSummaryDialog.setProject(project);
+		menuBarController.createRecentDocumentMenuItems();
+		setTitle();
+	}
+
+	// GUI Helping Methoden
+	public void loadUserCss() {
+		Profile.currentProfile().currentLayout().applyCssMainView(this, getStage(), project);
+		applyColorsToMappers();
+	}
+
+	private void applyColorsToMappers() {
+		// Apply Layout to Mapper
+		List<CartAction> actions = Profile.currentProfile().getMappings().getActiveMapping().getActions(CartActionConnect.TYPE);
+		for (CartAction cartAction : actions) {
+			if (cartAction.isAutoFeedbackColors()) {
+				for (Mapper mapper : cartAction.getMappers()) {
+					if (mapper instanceof MapperFeedbackable) {
+						MapperFeedbackable feedbackable = (MapperFeedbackable) mapper;
+						if (feedbackable.supportFeedback() && mapper instanceof ColorAssociator) {
+							ColorAssociator colorAssociator = (ColorAssociator) mapper;
+
+							Pad pad = project.getPad(cartAction.getCart());
+							Color layoutStandardColor = null;
+							Color layoutEventColor = null;
+
+							if (pad.isCustomLayout()) {
+								CartLayout layout = pad.getLayout();
+								if (layout instanceof LayoutColorAssociator) {
+									layoutStandardColor = ((LayoutColorAssociator) layout).getAssociatedStandardColor();
+									layoutEventColor = ((LayoutColorAssociator) layout).getAssociatedEventColor();
+								}
+							} else {
+								GlobalLayout layout = Profile.currentProfile().currentLayout();
+								if (layout instanceof LayoutColorAssociator) {
+									layoutStandardColor = ((LayoutColorAssociator) layout).getAssociatedStandardColor();
+									layoutEventColor = ((LayoutColorAssociator) layout).getAssociatedEventColor();
+								}
+							}
+
+							if (layoutStandardColor != null) {
+								DisplayableFeedbackColor associator = Mapper.searchColor(colorAssociator, FeedbackMessage.STANDARD,
+										layoutStandardColor);
+								colorAssociator.setColor(FeedbackMessage.STANDARD, associator.midiVelocity());
+							}
+
+							if (layoutEventColor != null) {
+								DisplayableFeedbackColor associator = Mapper.searchColor(colorAssociator, FeedbackMessage.EVENT,
+										layoutEventColor);
+								colorAssociator.setColor(FeedbackMessage.EVENT, associator.midiVelocity());
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Erstellt Constraints von GridView, Erstellt PadViews, Lädt CSS, Set Min Size vom Fendster
+	 */
+	public void createPadViews() {
+		ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings();
+
+		// Table
+		padGridPane.getColumnConstraints().clear();
+		double xPercentage = 1.0 / (double) profileSettings.getColumns();
+		for (int i = 0; i < profileSettings.getColumns(); i++) {
+			ColumnConstraints c = new ColumnConstraints();
+			c.setPercentWidth(xPercentage * 100);
+			padGridPane.getColumnConstraints().add(c);
+		}
+
+		padGridPane.getRowConstraints().clear();
+		double yPercentage = 1.0 / (double) profileSettings.getRows();
+		for (int i = 0; i < profileSettings.getRows(); i++) {
+			RowConstraints c = new RowConstraints();
+			c.setPercentHeight(yPercentage * 100);
+			padGridPane.getRowConstraints().add(c);
+		}
+
+		// Pads - Remove Old PadViews
+		padGridPane.getChildren().removeIf(t ->
+		{
+			if (t instanceof PadView) {
+				((PadView) t).getController().unconnectPad();
+				return true;
+			} else {
+				return false;
+			}
+		});
+		padViewList.clear();
+
+		// Neue PadViews
+		for (int y = 0; y < profileSettings.getRows(); y++) {
+			for (int x = 0; x < profileSettings.getColumns(); x++) {
+				IPadViewController controller = new PadViewController();
+				IPadView node = controller.getParent();
+				if (node instanceof PadView) {
+					padGridPane.add((Node) node, x, y);
+					padViewList.add(controller);
+				}
+			}
+		}
+
+		// Min Size of window
+		getStage().setMinWidth(Profile.currentProfile().currentLayout().getMinWidth(profileSettings.getColumns()));
+		if (OS.getType() == OSType.MacOSX) {
+			getStage().setMinHeight(Profile.currentProfile().currentLayout().getMinHeight(profileSettings.getRows()) + 100);
+		} else {
+			getStage().setMinHeight(Profile.currentProfile().currentLayout().getMinHeight(profileSettings.getRows()) + 150);
+		}
+	}
+
+	/**
+	 * Setzt die Pads in die Views und Cleared die alten Views. Lädt für die neuen Pads das Layout neu.
+	 * 
+	 * @param newPage
+	 */
+	public synchronized void showPage(int newPage) {
+		ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings();
+
+		if (!(newPage >= 0 && newPage < profileSettings.getPageCount())) {
+			return;
+		}
+
+		// Button in Toolbar
+		Button oldButton = (Button) toolbarController.getPageHBox().getChildren().get(pageNumber); // Der Aktuell andersfarbende Button
+		oldButton.getStyleClass().remove(CURRENT_PAGE_BUTTON);
+
+		this.pageNumber = newPage;
+
+		// alte Pads weg
+		padViewList.forEach(i -> i.unconnectPad());
+
+		// Neue Pads anzeigen
+		int index = pageNumber * profileSettings.getRows() * profileSettings.getColumns();
+		for (int i = 0; i < profileSettings.getRows() * profileSettings.getColumns(); i++) {
+			if (padViewList.size() > i) {
+				IPadViewController view = padViewList.get(i);
+				view.setPad(project.getPad(index));
+			}
+			index++;
+		}
+
+		// Button in Toolbar anders färben
+		Button newButton = (Button) toolbarController.getPageHBox().getChildren().get(pageNumber);
+		newButton.getStyleClass().add(CURRENT_PAGE_BUTTON);
+
+		// Handle Mapper
+		if (Profile.currentProfile() != null) {
+			Profile.currentProfile().getMappings().getActiveMapping().showFeedback(project, this);
+		}
+
+		// GUI Styling
+		loadUserCss();
+	}
+
+	public Slider getVolumeSlider() {
+		return toolbarController.getVolumeSlider();
+	}
+
+	@Override
+	public boolean closeRequest() {
+		if (errorSummaryDialog != null)
+			errorSummaryDialog.getStage().close();
+
+		if (Profile.currentProfile() != null) {
+			ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings();
+
+			// Frag den Nutzer ob das Programm wirdklich geschlossen werden sol wenn ein Pad noch im Status Play ist
+			if (project.getPlayedPlayers() > 0 && profilSettings.isLiveMode()) {
+				Alert alert = new Alert(AlertType.CONFIRMATION);
+				alert.setContentText(Localization.getString(Strings.UI_Window_Main_CloseRequest));
+
+				alert.initOwner(getStage());
+				alert.initModality(Modality.WINDOW_MODAL);
+				Stage alertStage = (Stage) alert.getDialogPane().getScene().getWindow();
+				PlayPadMain.stageIcon.ifPresent(alertStage.getIcons()::add);
+
+				Optional<ButtonType> result = alert.showAndWait();
+				if (result.isPresent())
+					if (result.get() != ButtonType.OK)
+						return false;
+			}
+
+			// MIDI Shutdown
+			if (profilSettings.isMidiActive()) {
+				try {
+					midi.close();
+				} catch (MidiUnavailableException e1) {
+					e1.printStackTrace();
+				}
+			}
+		}
+
+		if (getStage().isIconified()) {
+			getStage().setIconified(false);
+		}
+
+		// Verbindung von Pad und PadView wird getrennt. Zudem wird bei PLAY oder PAUSE auf STOP gesetzt
+		padViewList.forEach(padView -> padView.unconnectPad());
+
+		Worker.shutdown();
+
+		// Mapper Clear Feedback
+		Profile.currentProfile().getMappings().getActiveMapping().clearFeedback();
+
+		saveSettings();
+
+		System.exit(0);
+		return true;
+	}
+
+	/*
+	 * MIDI
+	 */
+
+	/**
+	 * Init MIDI Device by using the Midi Class and show some feedback the user.
+	 * 
+	 * @param name
+	 *            Device Name
+	 * 
+	 * @see Midi#lookupMidiDevice(String)
+	 */
+	private void loadMidiDevice(String name) {
+		try {
+			midi.lookupMidiDevice(name);
+			notificationPane.showAndHide(Localization.getString(Strings.Info_Midi_Device_Connected, name),
+					PlayPadMain.notificationDisplayTimeMillis);
+		} catch (NullPointerException e) {
+			showError(Localization.getString(Strings.Error_Midi_Device_Unavailible, name));
+		} catch (IllegalArgumentException | MidiUnavailableException e) {
+			showError(Localization.getString(Strings.Error_Midi_Device_Busy, e.getLocalizedMessage()));
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void notify(String text, long duration) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showAndHide(text, duration);
+		} else {
+			Platform.runLater(() -> notificationPane.showAndHide(text, duration));
+		}
+	}
+
+	@Override
+	public void notify(String text, long duration, Runnable finish) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showAndHide(text, duration, finish);
+		} else {
+			Platform.runLater(() -> notificationPane.showAndHide(text, duration, finish));
+		}
+	}
+
+	@Override
+	public void showError(String message) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showError(message);
+		} else {
+			Platform.runLater(() -> notificationPane.showError(message));
+		}
+	}
+
+	@Override
+	public void hide() {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.hide();
+		} else {
+			Platform.runLater(() -> notificationPane.hide());
+		}
+	}
+
+	@Override
+	public int getPage() {
+		return pageNumber;
+	}
+
+	private boolean shown = false;
+
+	protected void showLiveInfo() {
+		if (!shown) {
+			toolbarController.getToolbarHBox().setOpacity(0.5);
+			liveLabel.setVisible(true);
+			shown = true;
+			Worker.runLater(() ->
+			{
+				try {
+					Thread.sleep(PlayPadMain.notificationDisplayTimeMillis * 2);
+				} catch (Exception e) {}
+				Platform.runLater(() ->
+				{
+					toolbarController.getToolbarHBox().setOpacity(1);
+					liveLabel.setVisible(false);
+					shown = false;
+				});
+			});
+		}
+	}
+
+	@Override
+	public void reloadSettings(Profile old, Profile currentProfile) {
+		if (old != null) {
+			// Unbind Volume Slider
+			toolbarController.getVolumeSlider().valueProperty().unbindBidirectional(old.getProfileSettings().volumeProperty());
+			// Clear Feedback on Devie (LaunchPad Light off)
+			old.getMappings().getActiveMapping().getActions().forEach(action -> action.clearFeedback());
+		}
+
+		// Pad iund Page GUI
+		createPadViews();
+		toolbarController.createPageButtons();
+
+		// Volume
+		toolbarController.getVolumeSlider().valueProperty().bindBidirectional(currentProfile.getProfileSettings().volumeProperty());
+
+		// Apply Layout
+		currentProfile.currentLayout().applyCssMainView(this, getStage(), project);
+
+		// MIDI
+		ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings();
+		if (profilSettings.isMidiActive()) {
+			// Load known MIDI Device
+			Worker.runLater(() ->
+			{
+				if (profilSettings.getMidiDevice() != null) {
+					loadMidiDevice(profilSettings.getMidiDevice());
+
+					applyColorsToMappers();
+
+					Platform.runLater(() ->
+					{
+						// Handle Mapper
+						if (Profile.currentProfile() != null) {
+							Profile.currentProfile().getMappings().getActiveMapping().initFeedback();
+							Profile.currentProfile().getMappings().getActiveMapping().showFeedback(project, this);
+						}
+					});
+				}
+			});
+		}
+
+		if (Profile.currentProfile() != null) {
+			Profile.currentProfile().getMappings().getActiveMapping().showFeedback(project, this);
+		}
+
+		// WINDOW Settings
+		menuBarController.alwaysOnTopItem.setSelected(profilSettings.isWindowAlwaysOnTop());
+		getStage().setAlwaysOnTop(profilSettings.isWindowAlwaysOnTop());
+
+		setTitle();
+		showPage(pageNumber);
+	}
+
+	@Override
+	public Project getProject() {
+		return project;
+	}
+
+	public MidiHandler getMidiHandler() {
+		return midiHandler;
+	}
+
+	public MainToolbarController getToolbarController() {
+		return toolbarController;
+	}
+
+	// Plugins
+	/**
+	 * Fügt ein MenuItem ins Menu hinzu
+	 * 
+	 * @param item
+	 * 
+	 * @since 2.0.0
+	 */
+	public void addMenuItem(MenuItem item) {
+		menuBarController.extensionMenu.getItems().add(item);
+		if (!menuBarController.extensionMenu.isVisible()) {
+			menuBarController.extensionMenu.setVisible(true);
+		}
+	}
+
+	public void setGridColor(Color gridColor) {
+		this.gridColor = gridColor;
+		try {
+			Field field = padGridPane.getClass().getDeclaredField("gridLines");
+			field.setAccessible(true);
+			Group group = (Group) field.get(padGridPane);
+			if (group != null) {
+				for (Node node : group.getChildren()) {
+					if (node instanceof Line) {
+						((Line) node).setStroke(gridColor);
+					}
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/mapper/KeyboardMapperViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/mapper/KeyboardMapperViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..580f84d0f31c897f9b92d2262839ddf9c4a57fe3
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/mapper/KeyboardMapperViewController.java
@@ -0,0 +1,86 @@
+package de.tobias.playpad.viewcontroller.mapper;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.mapper.KeyboardMapper;
+import de.tobias.playpad.action.mapper.Mapper;
+import de.tobias.playpad.action.mapper.MapperViewController;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.StringUtils;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Scene;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Label;
+import javafx.stage.Stage;
+
+public class KeyboardMapperViewController extends MapperViewController {
+
+	@FXML private Label keyLabel;
+	@FXML private Button mappingButton;
+
+	private KeyboardMapper mapper;
+
+	public KeyboardMapperViewController() {
+		super("keyboard", "de/tobias/playpad/assets/view/mapper/", PlayPadMain.getUiResourceBundle());
+	}
+
+	@Override
+	public Mapper getMapper() {
+		return mapper;
+	}
+
+	@Override
+	public void hideFeedback() {}
+
+	@Override
+	public void showFeedback() {}
+
+	private void setLabel() {
+		keyLabel.setText(mapper.getReadableName());
+	}
+
+	@FXML
+	private void mappingButtonHandler(ActionEvent event) {
+		Alert alert = new Alert(AlertType.NONE);
+		alert.setTitle(Localization.getString(Strings.Mapper_Keyboard_Name));
+		alert.setContentText(Localization.getString(Strings.Info_Mapper_PressKey));
+		Scene scene = alert.getDialogPane().getScene();
+
+		scene.setOnKeyPressed(ev ->
+		{
+			mapper.setKey(ev.getCode().getName());
+			mapper.setCode(ev.getCode());
+			setLabel();
+		});
+		scene.setOnKeyReleased(ev ->
+		{
+			// Close on Finish (alert.close() does not work)
+			((Stage) scene.getWindow()).close();
+		});
+		scene.setOnKeyTyped(ev ->
+		{
+			if (!StringUtils.isStringNotVisable(ev.getCharacter())) {
+				mapper.setKey(ev.getCharacter().toUpperCase());
+				setLabel();
+			}
+		});
+
+		alert.getButtonTypes().add(ButtonType.CANCEL);
+		alert.initOwner(getWindow());
+		alert.showAndWait();
+	}
+
+	@Override
+	public void showInputMapperUI() {
+		mappingButton.fire();
+	}
+
+	public void setMapper(KeyboardMapper keyboardMapper) {
+		this.mapper = keyboardMapper;
+		setLabel();
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/mapper/MidiMapperViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/mapper/MidiMapperViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..a24809d66ebaa5437f350ebd1dc746279eb53599
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/mapper/MidiMapperViewController.java
@@ -0,0 +1,146 @@
+package de.tobias.playpad.viewcontroller.mapper;
+
+import javax.sound.midi.MidiMessage;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.feedback.DoubleSimpleFeedback;
+import de.tobias.playpad.action.feedback.FeedbackType;
+import de.tobias.playpad.action.feedback.SingleSimpleFeedback;
+import de.tobias.playpad.action.mapper.Mapper;
+import de.tobias.playpad.action.mapper.MapperViewController;
+import de.tobias.playpad.action.mapper.MidiMapper;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.midi.MidiListener;
+import de.tobias.playpad.viewcontroller.option.feedback.DoubleFeedbackViewController;
+import de.tobias.playpad.viewcontroller.option.feedback.SingleFeedbackViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Label;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+
+public class MidiMapperViewController extends MapperViewController implements MidiListener {
+
+	@FXML private Label midiInputKeyLabel;
+	@FXML private Button midiInputRecordButton;
+
+	@FXML private VBox root;
+
+	private MidiMapper mapper;
+
+	private ContentViewController feedbackController;
+
+	public MidiMapperViewController() {
+		super("midi", "de/tobias/playpad/assets/view/mapper/", PlayPadMain.getUiResourceBundle());
+	}
+
+	@Override
+	public Mapper getMapper() {
+		return mapper;
+	}
+
+	@Override
+	public void hideFeedback() {
+		if (feedbackController != null) {
+			root.getChildren().remove(feedbackController.getParent());
+		}
+	}
+
+	@Override
+	public void showFeedback() {
+		if (feedbackController != null) {
+			if (root.getChildren().contains(feedbackController.getParent()))
+				root.getChildren().remove(feedbackController.getParent());
+			root.getChildren().add(feedbackController.getParent());
+			VBox.setVgrow(feedbackController.getParent(), Priority.ALWAYS);
+		}
+	}
+
+	/**
+	 * Midi Listener von SettingsViewController, damit dieser wiederhergestellt werden kann am Ende.
+	 */
+	private MidiListener currentListener;
+
+	/**
+	 * Current Alert for mapping.
+	 */
+	private Alert alert;
+
+	@FXML
+	private void midiInputRecordButtonHandler(ActionEvent event) {
+		currentListener = Midi.getInstance().getListener();
+		Midi.getInstance().setListener(this);
+
+		alert = new Alert(AlertType.NONE);
+		alert.setTitle(Localization.getString(Strings.Mapper_Midi_Name));
+		alert.setContentText(Localization.getString(Strings.Info_Mapper_PressKey));
+		alert.getButtonTypes().add(ButtonType.CANCEL);
+		alert.initOwner(getWindow());
+		alert.showAndWait().ifPresent(result ->
+		{
+			if (result == ButtonType.CANCEL) {
+				Midi.getInstance().setListener(currentListener);
+				currentListener = null;
+				alert = null;
+			}
+		});
+	}
+
+	/**
+	 * Record new Midi Key
+	 */
+	@Override
+	public void onMidiAction(MidiMessage message) {
+		Platform.runLater(() ->
+		{
+			if (alert != null) {
+				Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
+				stage.close();
+				alert = null;
+			}
+			mapper.setCommand(message.getMessage()[0]);
+			mapper.setKey(message.getMessage()[1]);
+
+			midiInputKeyLabel.setText(String.valueOf(mapper.getKey()));
+		});
+		Midi.getInstance().setListener(currentListener);
+		currentListener = null;
+	}
+
+	@Override
+	public void showInputMapperUI() {
+		midiInputRecordButton.fire();
+	}
+
+	public void setMapper(MidiMapper midiMapper) {
+		this.mapper = midiMapper;
+
+		midiInputKeyLabel.setText(String.valueOf(mapper.getKey()));
+
+		Midi.getInstance().getMidiDevice().ifPresent(device ->
+		{
+			if (device.supportFeedback()) {
+				// remove old Elements
+				if (feedbackController != null) {
+					root.getChildren().remove(feedbackController.getParent());
+				}
+				// add new Elements
+				if (mapper.getFeedbackType() == FeedbackType.SINGLE) {
+					feedbackController = new SingleFeedbackViewController((SingleSimpleFeedback) mapper.getFeedback(), device.getColors());
+				} else if (mapper.getFeedbackType() == FeedbackType.DOUBLE) {
+					feedbackController = new DoubleFeedbackViewController((DoubleSimpleFeedback) mapper.getFeedback(), device.getColors());
+				}
+				showFeedback();
+			}
+		});
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/AudioTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/AudioTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e0c3bd36672fa2d417d967a630e3163b1e928d5
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/AudioTabViewController.java
@@ -0,0 +1,108 @@
+package de.tobias.playpad.viewcontroller.option;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.audio.AudioRegistry;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.playpad.viewcontroller.AudioTypeViewController;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.Worker;
+import javafx.fxml.FXML;
+import javafx.scene.control.ComboBox;
+import javafx.scene.layout.AnchorPane;
+
+public class AudioTabViewController extends SettingsTabViewController {
+
+	// Audio
+	@FXML private ComboBox<String> audioTypeComboBox;
+	@FXML private AnchorPane audioUserInfoSettings;
+	private AudioTypeViewController audioViewController;
+	private boolean changeAudioSettings;
+
+	public AudioTabViewController(boolean playerActive) {
+		super("audioTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle());
+
+		if (playerActive) {
+			audioTypeComboBox.setDisable(true);
+			audioUserInfoSettings.setDisable(true);
+		}
+	}
+
+	@Override
+	public void init() {
+		ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings();
+
+		// Audio
+		audioTypeComboBox.getItems().addAll(AudioRegistry.getAudioSystems().keySet());
+		audioTypeComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			if (b != null && c != null)
+				changeAudioSettings = true;
+			showAudioSettings(c);
+		});
+		showAudioSettings(profileSettings.getAudioClass());
+	}
+
+	private void showAudioSettings(String classID) {
+		if (audioViewController != null) {
+			if (audioViewController.isChanged()) {
+				changeAudioSettings = true;
+			}
+		}
+
+		audioUserInfoSettings.getChildren().clear();
+
+		audioViewController = AudioRegistry.getAudioSystems().get(classID).getAudioViewController();
+		if (audioViewController != null) {
+			audioUserInfoSettings.getChildren().add(audioViewController.getParent());
+		}
+	}
+
+	@Override
+	public void loadSettings(Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+
+		audioTypeComboBox.getSelectionModel().select(profileSettings.getAudioClass());
+
+	}
+
+	@Override
+	public void saveSettings(Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+
+		profileSettings.setAudioClass(audioTypeComboBox.getValue());
+
+	}
+
+	@Override
+	public boolean needReload() {
+		if (audioViewController != null) {
+			if (audioViewController.isChanged()) {
+				changeAudioSettings = true;
+			}
+		}
+		return changeAudioSettings;
+	}
+
+	@Override
+	public void reload(Profile profile, Project project, IMainViewController controller) {
+		Worker.runLater(() ->
+		{
+			project.getPads().values().forEach(pad -> pad.loadContent());
+		});
+	}
+
+	@Override
+	public boolean validSettings() {
+		return true;
+	}
+
+	@Override
+	public String name() {
+		return Localization.getString(Strings.UI_Window_Settings_Audio_Title);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..016a35a9570e0492ea51810a9994142e8048a5ab
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java
@@ -0,0 +1,257 @@
+package de.tobias.playpad.viewcontroller.option;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.layout.GlobalLayout;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.NumberUtils;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.stage.DirectoryChooser;
+import javafx.stage.Screen;
+
+public class GeneralTabViewController extends SettingsTabViewController {
+
+	private static final String DIGIT_POSITIV = "^[1-9]\\d*$";
+	
+	private Screen mainWindowScreen;
+	private ViewController parentController; // Für Benachrichtungen
+
+	@FXML private TextField pageCountTextField;
+	@FXML private TextField columnTextField;
+	@FXML private TextField rowTextField;
+
+	@FXML private CheckBox liveModeCheckBox;
+
+	@FXML private TextField cacheTextField;
+	@FXML private Label cacheSizeLabel;
+
+	private boolean changeSettings;
+
+	public GeneralTabViewController(Screen screen, ViewController parentController, boolean activePlayer) {
+		super("generalTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle());
+		this.mainWindowScreen = screen;
+		this.parentController = parentController;
+
+		if (activePlayer) {
+			rowTextField.setDisable(true);
+			columnTextField.setDisable(true);
+			pageCountTextField.setDisable(true);
+		}
+		calcCacheSize();
+	}
+
+	@Override
+	public void init() {
+		pageCountTextField.textProperty().addListener((a, b, c) ->
+		{
+			if (c.matches(DIGIT_POSITIV) && !c.isEmpty()) {
+				int number = Integer.valueOf(c);
+				if (number > ProfileSettings.MAX_PAGES) {
+					pageCountTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); // Zahl zu groß
+				} else {
+					pageCountTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false); // Zahl ok
+				}
+			} else {
+				pageCountTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); // Negativ oder leer
+			}
+		});
+
+		columnTextField.textProperty().addListener((a, b, c) ->
+		{
+			if (c.matches(DIGIT_POSITIV) && !c.isEmpty()) {
+				if (screenValid()) {
+					columnTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false); // Zahl ok
+				} else {
+					columnTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); // Zahl zu groß
+				}
+			} else {
+				columnTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); // Negativ oder leer
+			}
+		});
+
+		rowTextField.textProperty().addListener((a, b, c) ->
+		{
+			if (c.matches(DIGIT_POSITIV) && !c.isEmpty()) {
+				if (screenValid()) {
+					rowTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false); // Zahl ok
+				} else {
+					rowTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); // Zahl zu groß
+				}
+			} else {
+				rowTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); // Negativ oder leer
+			}
+		});
+	}
+
+	@FXML
+	private void cacheChooseHandler(ActionEvent event) {
+		DirectoryChooser chooser = new DirectoryChooser();
+		File folder = chooser.showDialog(getStage());
+		if (folder != null) {
+			Path folderPath = folder.toPath();
+			Profile.currentProfile().getProfileSettings().setCachePath(folderPath);
+			cacheTextField.setText(folderPath.toString());
+		}
+	}
+
+	@FXML
+	private void cacheResetButtonHandler(ActionEvent event) {
+		try {
+			int deleteFiles = 0;
+			for (Path path : Files.newDirectoryStream(ApplicationUtils.getApplication().getPath(PathType.CACHE))) {
+				if (Files.isRegularFile(path)) {
+					try {
+						Files.delete(path);
+						deleteFiles++;
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+				}
+			}
+			parentController.showInfoMessage(Localization.getString(Strings.Info_Settings_CacheDelete, deleteFiles),
+					PlayPadMain.stageIcon.get());
+
+			calcCacheSize();
+		} catch (IOException e) {
+			e.printStackTrace();
+			showErrorMessage(Localization.getString(Strings.Error_Settings_CacheClear, e.getLocalizedMessage()));
+		}
+	}
+
+	@FXML
+	private void resetDialogs(ActionEvent event) {
+		ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings();
+
+		profilSettings.setDialogDragAndDrop(true);
+		parentController.showInfoMessage(Localization.getString(Strings.Info_Settings_ResetWarning));
+	}
+
+	private void calcCacheSize() {
+		try {
+			double size = 0;
+			Path path = Profile.currentProfile().getProfileSettings().getCachePath();
+			if (Files.notExists(path))
+				Files.createDirectories(path);
+
+			for (Path item : Files.newDirectoryStream(Profile.currentProfile().getProfileSettings().getCachePath())) {
+				size += Files.size(item);
+			}
+			cacheSizeLabel.setText(Localization.getString(Strings.UI_Window_Settings_Gen_CacheSize, NumberUtils.numberToString(size)));
+		} catch (IOException e) {
+			e.printStackTrace();
+			parentController.showErrorMessage(Localization.getString(Strings.Error_Settings_CacheSize, e.getMessage()), PlayPadMain.stageIcon);
+		}
+	}
+
+	private boolean screenValid() {
+		double width = mainWindowScreen.getVisualBounds().getMaxX() - mainWindowScreen.getVisualBounds().getMinX();
+		double height = mainWindowScreen.getVisualBounds().getMaxY() - mainWindowScreen.getVisualBounds().getMinY();
+
+		GlobalLayout layout = Profile.currentProfile().currentLayout();
+
+		try {
+			double neededWidth = layout.getMinWidth(Integer.valueOf(columnTextField.getText()));
+			double neededHeight = layout.getMinHeight(Integer.valueOf(rowTextField.getText())) + 100;
+
+			if (neededHeight <= height && neededWidth <= width)
+				return true;
+		} catch (NumberFormatException e) {}
+		return false;
+	}
+
+	@Override
+	public void loadSettings(Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+
+		pageCountTextField.setText(String.valueOf(profileSettings.getPageCount()));
+		columnTextField.setText(String.valueOf(profileSettings.getColumns()));
+		rowTextField.setText(String.valueOf(profileSettings.getRows()));
+
+		liveModeCheckBox.setSelected(profileSettings.isLiveMode());
+		cacheTextField.setText(profileSettings.getCachePath().toString());
+		
+		if (screenValid()) {
+			columnTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false);
+			rowTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false);
+		} else {
+			columnTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true);
+			rowTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true);
+		}
+	}
+
+	@Override
+	public void saveSettings(Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+
+		int columns = Integer.valueOf(columnTextField.getText());
+		int rows = Integer.valueOf(rowTextField.getText());
+		int pageCount = Integer.valueOf(pageCountTextField.getText());
+
+		if (profileSettings.getColumns() != columns || profileSettings.getRows() != rows || profileSettings.getPageCount() != pageCount)
+			changeSettings = true;
+		else
+			changeSettings = false;
+
+		// Copy Settings
+		profileSettings.setColumns(columns);
+		profileSettings.setRows(rows);
+		profileSettings.setPageCount(pageCount);
+
+		profileSettings.setLiveMode(liveModeCheckBox.isSelected());
+		profileSettings.setCachePath(Paths.get(cacheTextField.getText()));
+	}
+
+	@Override
+	public boolean needReload() {
+		return changeSettings;
+	}
+
+	@Override
+	public void reload(Profile profile, Project project, IMainViewController controller) {
+		controller.getToolbarController().createPageButtons();
+		controller.createPadViews();
+		controller.showPage(controller.getPage());
+	}
+
+	@Override
+	public boolean validSettings() {
+		if (screenValid()) {
+			return true;
+		} else {
+			double width = mainWindowScreen.getVisualBounds().getMaxX() - mainWindowScreen.getVisualBounds().getMinX();
+			double height = mainWindowScreen.getVisualBounds().getMaxY() - mainWindowScreen.getVisualBounds().getMinY();
+
+			GlobalLayout globalLayout = Profile.currentProfile().currentLayout();
+
+			int maxCartsX = (int) (width / globalLayout.getPadWidth());
+			int maxCartsY = (int) ((height - 100) / globalLayout.getPadHeight());
+			parentController.showErrorMessage(Localization.getString(Strings.Error_Profile_SmallScreen, maxCartsX, maxCartsY),
+					PlayPadMain.stageIcon.orElse(null));
+			return false;
+		}
+	}
+
+	@Override
+	public String name() {
+		return Localization.getString(Strings.UI_Window_Settings_Gen_Title);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/LayoutTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/LayoutTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..2077e4e715160998d32974c43b44289433442afc
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/LayoutTabViewController.java
@@ -0,0 +1,89 @@
+package de.tobias.playpad.viewcontroller.option;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.layout.GlobalLayout;
+import de.tobias.playpad.layout.LayoutConnect;
+import de.tobias.playpad.layout.LayoutRegistry;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.GlobalLayoutViewController;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.viewcontroller.cell.DisplayableCell;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.util.Localization;
+import javafx.fxml.FXML;
+import javafx.scene.control.ComboBox;
+import javafx.scene.layout.VBox;
+
+public class LayoutTabViewController extends SettingsTabViewController {
+
+	@FXML private VBox layoutContainer;
+	@FXML private ComboBox<LayoutConnect> layoutTypeComboBox;
+	private GlobalLayoutViewController globalLayoutViewController;
+
+	public LayoutTabViewController() {
+		super("layoutTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle());
+
+		String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType();
+		layoutTypeComboBox.setValue(LayoutRegistry.getLayout(layoutType));
+	}
+
+	@Override
+	public void init() {
+		// Layout
+		layoutTypeComboBox.getItems().setAll(LayoutRegistry.getValues());
+		layoutTypeComboBox.valueProperty().addListener((a, b, c) ->
+		{
+			String type = c.getType();
+
+			Profile.currentProfile().getProfileSettings().setLayoutType(type);
+			GlobalLayout layout = Profile.currentProfile().getLayout(type);
+			try {
+				setLayoutController(c.getGlobalLayoutViewController(layout));
+			} catch (Exception e) {
+				e.printStackTrace();
+				showErrorMessage(Localization.getString(Strings.Error_Layout_Load, e.getMessage()));
+			}
+		});
+
+		layoutTypeComboBox.setCellFactory((list) -> new DisplayableCell<>());
+		layoutTypeComboBox.setButtonCell(new DisplayableCell<>());
+	}
+
+	private void setLayoutController(GlobalLayoutViewController globalLayoutViewController) {
+		if (this.globalLayoutViewController != null)
+			layoutContainer.getChildren().remove(this.globalLayoutViewController.getParent());
+
+		if (globalLayoutViewController != null) {
+			this.globalLayoutViewController = globalLayoutViewController;
+			layoutContainer.getChildren().add(globalLayoutViewController.getParent());
+		}
+	}
+
+	@Override
+	public void loadSettings(Profile profile) {}
+
+	@Override
+	public void saveSettings(Profile profile) {}
+
+	@Override
+	public boolean needReload() {
+		return true;
+	}
+
+	@Override
+	public void reload(Profile profile, Project project, IMainViewController controller) {
+		controller.loadUserCss();
+	}
+
+	@Override
+	public boolean validSettings() {
+		return true;
+	}
+
+	@Override
+	public String name() {
+		return Localization.getString(Strings.UI_Window_Settings_Layout_Title);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/MappingTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/MappingTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8130b66d3f74fa123462ea0ba340cf4a5afcb9f
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/MappingTabViewController.java
@@ -0,0 +1,169 @@
+package de.tobias.playpad.viewcontroller.option;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.Action;
+import de.tobias.playpad.action.ActionConnect;
+import de.tobias.playpad.action.ActionDisplayable;
+import de.tobias.playpad.action.ActionRegistery;
+import de.tobias.playpad.action.ActionType;
+import de.tobias.playpad.action.Mapping;
+import de.tobias.playpad.action.mapper.MapperRegistry;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.IMapperOverviewViewController;
+import de.tobias.playpad.viewcontroller.IMappingTabViewController;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.viewcontroller.cell.DisplayableCell;
+import de.tobias.playpad.viewcontroller.cell.DisplayableTreeCell;
+import de.tobias.playpad.viewcontroller.dialog.MappingListViewController;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.layout.VBox;
+
+public class MappingTabViewController extends SettingsTabViewController implements IMappingTabViewController {
+
+	@FXML private ComboBox<Mapping> mappingComboBox;
+	@FXML private Button editMappingsButton;
+
+	@FXML private TreeView<ActionDisplayable> treeView;
+
+	@FXML private VBox detailView;
+	private IMapperOverviewViewController mapperOverviewViewController;
+
+	private Mapping mapping;
+
+	public MappingTabViewController() {
+		super("mapping", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle());
+	}
+
+	@Override
+	public void init() {
+		mappingComboBox.setCellFactory(list -> new DisplayableCell<>());
+		mappingComboBox.setButtonCell(new DisplayableCell<>());
+
+		mappingComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			mapping = c;
+			Profile.currentProfile().getMappings().setActiveMapping(c);
+			createTreeViewContent();
+		});
+
+		treeView.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			detailView.getChildren().clear();
+
+			if (c != null) {
+				ContentViewController controller = c.getValue().getSettingsViewController();
+				if (controller == null) {
+					controller = c.getValue().getActionSettingsViewController(mapping, this);
+				}
+				if (controller != null) {
+					detailView.getChildren().add(controller.getParent());
+				}
+				if (c.getValue() instanceof Action) {
+					showMapperFor((Action) c.getValue());
+				}
+			}
+		});
+		treeView.setCellFactory(list -> new DisplayableTreeCell<>());
+	}
+
+	private TreeItem<ActionDisplayable> createTreeView(Mapping mapping) {
+		TreeItem<ActionDisplayable> rootItem = new TreeItem<>();
+		Set<String> types = ActionRegistery.getTypes();
+		List<String> sortedTypes = types.stream().sorted().collect(Collectors.toList());
+
+		// Sort the tpyes for the treeview
+		for (ActionType actionType : ActionType.values()) {
+			createTreeViewForActionType(mapping, rootItem, sortedTypes, actionType);
+		}
+
+		return rootItem;
+	}
+
+	private void createTreeViewForActionType(Mapping mapping, TreeItem<ActionDisplayable> rootItem, List<String> sortedTypes, ActionType type) {
+		for (String tpye : sortedTypes) {
+			List<Action> actions = mapping.getActionsOfType(tpye);
+			ActionConnect actionConnect = ActionRegistery.getActionConnect(tpye);
+			if (actionConnect.geActionType() == type) {
+				TreeItem<ActionDisplayable> item = actionConnect.getTreeViewForActions(actions, mapping);
+				rootItem.getChildren().add(item);
+			}
+		}
+	}
+
+	@FXML
+	private void editMappingsHandler(ActionEvent event) {
+		MappingListViewController controller = new MappingListViewController(Profile.currentProfile().getMappings(), getWindow());
+		controller.getStage().showAndWait();
+		setMappingItemsToList();
+	}
+
+	private void createTreeViewContent() {
+		TreeItem<ActionDisplayable> rootItem = createTreeView(mapping);
+		treeView.setRoot(rootItem);
+	}
+
+	private void setMappingItemsToList() {
+		mappingComboBox.getItems().setAll(Profile.currentProfile().getMappings());
+		mappingComboBox.setValue(Profile.currentProfile().getMappings().getActiveMapping());
+
+		mapping = mappingComboBox.getValue();
+	}
+
+	@Override
+	public void showMapperFor(Action action) {
+		try {
+			if (action != null) {
+				mapperOverviewViewController = MapperRegistry.getOverviewViewControllerInstance();
+				mapperOverviewViewController.showAction(action, detailView);
+			} else {
+				detailView.getChildren().remove(mapperOverviewViewController.getParent());
+			}
+		} catch (Exception e) {}
+	}
+
+	// Tab Utils
+	@Override
+	public void loadSettings(Profile profile) {
+		setMappingItemsToList();
+		createTreeViewContent();
+	}
+
+	@Override
+	public void saveSettings(Profile profile) {}
+
+	@Override
+	public boolean needReload() {
+		return true;
+	}
+
+	@Override
+	public void reload(Profile profile, Project project, IMainViewController controller) {
+		Profile.currentProfile().getMappings().getActiveMapping().clearFeedback();
+		Profile.currentProfile().getMappings().getActiveMapping().showFeedback(project, controller);
+		Profile.currentProfile().getMappings().getActiveMapping().initFeedback();
+	}
+
+	@Override
+	public boolean validSettings() {
+		return true;
+	}
+
+	@Override
+	public String name() {
+		return Localization.getString(Strings.UI_Window_Settings_Mapping_Title);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/MidiTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/MidiTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c6e45c2e1c371685cd8d0ba349f51a78f3eaddb
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/MidiTabViewController.java
@@ -0,0 +1,124 @@
+package de.tobias.playpad.viewcontroller.option;
+
+import javax.sound.midi.MidiDevice.Info;
+import javax.sound.midi.MidiUnavailableException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.layout.AnchorPane;
+
+public class MidiTabViewController extends SettingsTabViewController {
+
+	@FXML private AnchorPane rootPane;
+
+	@FXML private CheckBox midiActiveCheckBox;
+	@FXML private ComboBox<String> deviceComboBox;
+
+	public MidiTabViewController() {
+		super("midiTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle());
+
+		Info[] data = Midi.getMidiDevices();
+		// Gerät anzeigen - Doppelte weg
+		for (Info item : data) {
+			if (!deviceComboBox.getItems().contains(item.getName())) {
+				deviceComboBox.getItems().add(item.getName());
+
+				// aktives Gerät wählen
+				if (item.getName().equals(Profile.currentProfile().getProfileSettings().getMidiDevice())) {
+					deviceComboBox.getSelectionModel().select(item.getName());
+				}
+			}
+		}
+
+	}
+
+	@Override
+	public void init() {
+		midiActiveCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			deviceComboBox.setDisable(!c);
+		});
+	}
+
+	// Midi Device und Presets Choose
+	@FXML
+	private void deviceHandler(ActionEvent event) {
+		ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings();
+		String device = deviceComboBox.getValue();
+
+		// Ändern und Speichern
+		if (device != null) {
+			if (isMidiActive()) {
+				Midi midi = Midi.getInstance();
+				if (!device.equals(profilSettings.getMidiDevice()) || !midi.isOpen()) {
+					try {
+						// Setup
+						midi.lookupMidiDevice(device);
+						profilSettings.setMidiDeviceName(device);
+
+						// UI Rückmeldung
+						if (midi.getInputDevice().isPresent()) {
+							showInfoMessage(Localization.getString(Strings.Info_Midi_Device_Connected, device));
+						}
+					} catch (NullPointerException e) {
+						showErrorMessage(Localization.getString(Strings.Error_Midi_Device_Unavailible, device));
+						e.printStackTrace();
+					} catch (IllegalArgumentException | MidiUnavailableException e) {
+						showErrorMessage(Localization.getString(Strings.Error_Midi_Device_Busy, e.getLocalizedMessage()));
+						e.printStackTrace();
+					}
+				}
+			}
+		}
+	}
+
+	public boolean isMidiActive() {
+		return midiActiveCheckBox.isSelected();
+	}
+
+	@Override
+	public void loadSettings(Profile profile) {
+		midiActiveCheckBox.setSelected(profile.getProfileSettings().isMidiActive());
+		deviceComboBox.setDisable(!profile.getProfileSettings().isMidiActive());
+		deviceComboBox.setValue(profile.getProfileSettings().getMidiDevice());
+	}
+
+	@Override
+	public void saveSettings(Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+
+		// Midi
+		profileSettings.setMidiActive(isMidiActive());
+	}
+
+	@Override
+	public boolean validSettings() {
+		return true;
+	}
+
+	@Override
+	public boolean needReload() {
+		return true;
+	}
+
+	@Override
+	public void reload(Profile profile, Project project, IMainViewController controller) {
+
+	}
+
+	@Override
+	public String name() {
+		return Localization.getString(Strings.UI_Window_Settings_Midi_Title);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/MidiTabViewController2.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/MidiTabViewController2.java
new file mode 100644
index 0000000000000000000000000000000000000000..796c012dc814fa5a745fe6f489cb296f114838d7
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/MidiTabViewController2.java
@@ -0,0 +1,641 @@
+package de.tobias.playpad.viewcontroller.option;
+
+import java.util.Collections;
+import java.util.Optional;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiDevice.Info;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiUnavailableException;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.mididevice.Device;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.midi.MidiListener;
+import de.tobias.playpad.model.Project;
+import de.tobias.playpad.model.midi.Displayable;
+import de.tobias.playpad.model.midi.MidiAction;
+import de.tobias.playpad.model.midi.SubAction;
+import de.tobias.playpad.model.midi.type.MidiKeyActionType;
+import de.tobias.playpad.model.midi.type.MidiKeyActionTypes;
+import de.tobias.playpad.model.midi.type.MidiKeyActionTypes.MidiKeyActionTypeStore;
+import de.tobias.playpad.plugin.viewcontroller.IMainViewController;
+import de.tobias.playpad.plugin.viewcontroller.IMidiTabViewController;
+import de.tobias.playpad.plugin.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.settings.MidiPreset;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.playpad.viewcontroller.PresetsViewController;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.ui.NotificationHandler;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.ui.scene.NotificationPane;
+import de.tobias.utils.util.Localization;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Parent;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class MidiTabViewController2 extends SettingsTabViewController
+		implements IMidiTabViewController, MidiListener, NotificationHandler, ChangeListener<TreeItem<Displayable>> {
+
+	@FXML private AnchorPane rootPane;
+	private NotificationPane notificationPane;
+
+	@FXML private CheckBox midiActiveCheckBox;
+	@FXML private ComboBox<String> deviceComboBox;
+
+	@FXML private ComboBox<MidiPreset> presetsList;
+	@FXML private Button presetsEditButton;
+	@FXML private Button activateButton;
+
+	@FXML private Button addMidiButton;
+	@FXML private Button addMidiDraftButton;
+	@FXML private Button draftButton;
+	@FXML private Button deleteMidiButton;
+	@FXML private Button clearMidiButton;
+
+	@FXML private TreeView<Displayable> contentTreeView;
+	@FXML private ComboBox<MidiKeyActionTypeStore> midiActionTypeComboBox;
+	@FXML private AnchorPane settingsAnchorPane;
+
+	// Midi Record
+	private boolean recordMidi;
+	private boolean useDraft;
+	private org.controlsfx.control.action.Action midiRecordCancelAction;
+
+	private final Window owner;
+
+	public MidiTabViewController2(Window owner) {
+		super("midiTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle());
+		this.owner = owner;
+
+		owner.setOnShown(event ->
+		{
+			if (!Midi.getInstance().isOpen() && Profile.currentProfile().getProfileSettings().isMidiActive()) {
+				showError(Localization.getString(Strings.Info_Settings_Midi_NoDevice));
+			}
+			updateButtonDisable();
+			if (!Profile.currentProfile().getMidiSetting().getDraftAction().isPresent()) {
+				addMidiDraftButton.setDisable(true);
+			}
+		});
+
+		// Midi Listener auf Einstellungen
+		Midi.getInstance().setListener(this);
+	}
+
+	@Override
+	public void init() {
+		// Notifiation Pane
+		midiRecordCancelAction = new org.controlsfx.control.action.Action(Localization.getString(Strings.Actions_Midi_Cancel), event ->
+		{
+			recordMidi = false;
+			notificationPane.hide();
+		});
+
+		notificationPane = new NotificationPane(rootPane);
+		notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK);
+
+		presetsList.valueProperty().addListener((a, b, c) ->
+		{
+			if (c != null) {
+				Collections.sort(c.getMidiActions()); // sortieren
+
+				// Aktivieren Button ein und aus schalten
+				if (c.isActive()) {
+					activateButton.setDisable(true);
+				} else {
+					activateButton.setDisable(false);
+				}
+
+				// items in treeview
+				showMidiPresetActions();
+			}
+		});
+
+		// setup persets and select active or first
+		presetsList.setItems(Profile.currentProfile().getMidiSetting().getPresets());
+		presetsList.getSelectionModel().select(0); // Standart Selectend
+
+		for (MidiPreset preset : Profile.currentProfile().getMidiSetting().getPresets()) { // Preset Auswählen
+			if (preset.isActive()) {
+				presetsList.getSelectionModel().select(preset); // Wenn aktiv dann selecten
+				break;
+			}
+		}
+
+		// Auswahlliste Links Setup
+		showMidiPresetActions();
+		contentTreeView.setShowRoot(false);
+		contentTreeView.getSelectionModel().selectedItemProperty().addListener(this);
+
+		// Action Types Init
+		midiActionTypeComboBox.getItems().setAll(MidiKeyActionTypes.getActions());
+
+		// ActionType Changed
+		midiActionTypeComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
+		{
+			if (c != null) {
+				try {
+					MidiKeyActionType type = c.getActionType().newInstance();
+					Optional<MidiAction> midiAction = getSelectedMidiAction();
+					if (midiAction.isPresent()) {
+						if (!MidiKeyActionType.equals(type, midiAction.get().getActionType())) {
+							Device device = Midi.getInstance().getMidiDevice().get();
+
+							midiAction.get().setActionType(type, device.getDefaultColor(type.getClass()));
+
+							updateChildrenOfRootItem(midiAction.get(), getTreeObject(midiAction.get(), contentTreeView.getRoot()));
+							showSettingsView(midiAction.get());
+						}
+					}
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		});
+
+		deviceComboBox.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_MidiDevice)));
+
+		Info[] data = Midi.getMidiDevices();
+		// Gerät anzeigen - Doppelte weg
+		for (Info item : data) {
+			if (!deviceComboBox.getItems().contains(item.getName())) {
+				deviceComboBox.getItems().add(item.getName());
+
+				// aktives Gerät wählen
+				if (item.getName().equals(Profile.currentProfile().getProfileSettings().getMidiDevice())) {
+					deviceComboBox.getSelectionModel().select(item.getName());
+				}
+			}
+		}
+	}
+
+	@Override
+	public Parent getParent() {
+		return notificationPane;
+	}
+
+	// UI Helper Getter und Setter
+	private void showMidiPresetActions() {
+		contentTreeView.setRoot(createMidiActionsTree(getSelectedPreset()));
+	}
+
+	public void updateChildrenOfRootItem(MidiAction midiAction) {
+		updateChildrenOfRootItem(midiAction, getTreeObject(midiAction, contentTreeView.getRoot()));
+	}
+
+	public void updateChildrenOfRootItem(MidiAction midiAction, TreeItem<Displayable> root) {
+		root.getChildren().clear();
+		if (!midiAction.getActions().isEmpty() && midiAction.getActionType().showSubActions()) {
+			for (SubAction action : midiAction.getActions()) {
+				TreeItem<Displayable> treeItemAction = new TreeItem<>(action);
+				root.getChildren().add(treeItemAction);
+			}
+		}
+		root.setExpanded(true);
+	}
+
+	private void addMidiActionToTree(MidiAction midiAction) {
+		TreeItem<Displayable> treeItemMidi = new TreeItem<>(midiAction);
+		int index = getSelectedPreset().getMidiActions().indexOf(midiAction);
+
+		contentTreeView.getRoot().getChildren().add(index, treeItemMidi);
+		createMidiActionsTree(getSelectedPreset());
+		selectMidiAction(midiAction);
+	}
+
+	private void updateButtonDisable() {
+		Optional<Displayable> displayable = getSelectedAction();
+		if (displayable.isPresent()) {
+			if (displayable.get() instanceof MidiAction) { // Root Node -> MidiAction
+				deleteMidiButton.setDisable(false);
+				draftButton.setDisable(false);
+			} else {
+				deleteMidiButton.setDisable(true);
+				draftButton.setDisable(true);
+			}
+			midiActionTypeComboBox.setDisable(false);
+		} else {
+			deleteMidiButton.setDisable(true);
+			draftButton.setDisable(true);
+			midiActionTypeComboBox.setDisable(true);
+		}
+	}
+
+	private MidiPreset getSelectedPreset() {
+		return presetsList.getSelectionModel().getSelectedItem();
+	}
+
+	public Optional<MidiAction> getSelectedMidiAction() {
+		TreeItem<Displayable> item = contentTreeView.getSelectionModel().getSelectedItem();
+		if (item != null) {
+			if (item.getValue() instanceof MidiAction) {
+				return Optional.of((MidiAction) item.getValue());
+			} else {
+				return Optional.of((MidiAction) item.getParent().getValue());
+			}
+		} else {
+			return Optional.empty();
+		}
+	}
+
+	public Optional<Displayable> getSelectedAction() {
+		TreeItem<Displayable> item = contentTreeView.getSelectionModel().getSelectedItem();
+		if (item != null) {
+			return Optional.of(item.getValue());
+		} else {
+			return Optional.empty();
+		}
+	}
+
+	public TreeItem<Displayable> getTreeObject(Displayable object, TreeItem<Displayable> root) {
+		if (root.getValue() == object) {
+			return root;
+		} else {
+			for (TreeItem<Displayable> child : root.getChildren()) {
+				TreeItem<Displayable> result = getTreeObject(object, child);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	private void selectMidiKeyActionType(MidiKeyActionType type) {
+		MidiKeyActionTypeStore store = MidiKeyActionTypes.getStoreForType(type);
+		midiActionTypeComboBox.setValue(store);
+	}
+
+	// Show Methods
+	private TreeItem<Displayable> createMidiActionsTree(MidiPreset preset) {
+		TreeItem<Displayable> treeItemRoot = new TreeItem<>();
+
+		if (preset != null) {
+			for (MidiAction midiAction : preset.getMidiActions()) {
+				TreeItem<Displayable> treeItemMidi = new TreeItem<>(midiAction);
+				if (!midiAction.getActions().isEmpty() && midiAction.getActionType().showSubActions()) {
+					for (SubAction action : midiAction.getActions()) {
+						TreeItem<Displayable> treeItemAction = new TreeItem<>(action);
+						treeItemMidi.getChildren().add(treeItemAction);
+					}
+				}
+				treeItemRoot.getChildren().add(treeItemMidi);
+			}
+		}
+
+		return treeItemRoot;
+	}
+
+	private void selectPressedMidiAction(MidiMessage message) {
+		getSelectedPreset().getMidiActionForMidi(message).ifPresent(item -> Platform.runLater(() -> selectMidiAction(item)));
+	}
+
+	private void selectMidiAction(MidiAction midiAction) {
+		// select item
+		TreeItem<Displayable> treeItem = getTreeObject(midiAction, contentTreeView.getRoot());
+		contentTreeView.getSelectionModel().select(treeItem);
+
+		// scroll to index (only index)
+		int index = contentTreeView.getSelectionModel().getSelectedIndex();
+		contentTreeView.scrollTo(index);
+	}
+
+	/**
+	 * 
+	 * @param value
+	 *            MidiAction or SubAction
+	 */
+	public void showSettingsView(Displayable value) {
+		settingsAnchorPane.getChildren().clear();
+		midiActionTypeComboBox.setValue(null);
+
+		ContentViewController controller = null;
+		if (value != null) {
+			if (value instanceof MidiAction) {
+				MidiAction midiAction = (MidiAction) value;
+				MidiKeyActionType type = midiAction.getActionType();
+				controller = type.getMainViewController(midiAction, this, this);
+				selectMidiKeyActionType(midiAction.getActionType());
+
+			} else if (value instanceof SubAction) {
+				SubAction action = (SubAction) value;
+				MidiAction midiAction = action.getMidiAction();
+
+				MidiKeyActionType type = midiAction.getActionType();
+				controller = type.getSubViewController(action, this, this);
+				selectMidiKeyActionType(midiAction.getActionType());
+			}
+		}
+
+		// TODO Overhead mit neuen VC fixen, Reuable machen
+		if (controller != null) {
+			ViewController.setAnchor(controller.getParent(), 14, 0, 14, 0);
+			settingsAnchorPane.getChildren().add(controller.getParent());
+		}
+	}
+
+	// Midi Device und Presets Choose
+	@FXML
+	private void deviceHandler(ActionEvent event) {
+		ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings();
+		String device = deviceComboBox.getValue();
+
+		// Ändern und Speichern
+		if (device != null) {
+			if (isMidiActive()) {
+				Midi midi = Midi.getInstance();
+				if (!device.equals(profilSettings.getMidiDevice()) || !midi.isOpen()) {
+					try {
+						// Setup
+						midi.lookupMidiDevice(device);
+						profilSettings.setMidiDeviceName(device);
+
+						// UI Rückmeldung
+						if (midi.getInputDevice().isPresent()) {
+							notify(Localization.getString(Strings.Info_Midi_Device_Connected, device),
+									PlayPadMain.notificationDisplayTimeMillis);
+							// mainPane.setDisable(false); BUG Disable / Enable der GUI wenn kein MIDI da ist
+						}
+					} catch (NullPointerException e) {
+						showError(Localization.getString(Strings.Error_Midi_Device_Unavailible, device));
+						e.printStackTrace();
+					} catch (IllegalArgumentException | MidiUnavailableException e) {
+						showError(Localization.getString(Strings.Error_Midi_Device_Busy, e.getLocalizedMessage()));
+						e.printStackTrace();
+					}
+				}
+			}
+		}
+	}
+
+	@FXML
+	private void presetsEditButtonHandler(ActionEvent event) {
+		PresetsViewController controller = new PresetsViewController(owner);
+		controller.getStage().showAndWait();
+	}
+
+	@FXML
+	private void activateButtonHandler(ActionEvent event) {
+		MidiPreset item = presetsList.getSelectionModel().getSelectedItem();
+		item.setActive(true);
+		activateButton.setDisable(true);
+		PresetsViewController.disableInvalidPresets(true, item, Profile.currentProfile().getMidiSetting());
+	}
+
+	// MidiActionHandlers
+	@FXML
+	private void addMidiButtonHandler(ActionEvent event) {
+		notificationPane.show(Localization.getString(Strings.Info_Midi_Record_Start), null, midiRecordCancelAction);
+		recordMidi = true;
+		useDraft = false;
+	}
+
+	@FXML
+	private void addMidiDraftButtonHandler(ActionEvent event) {
+		notificationPane.show(Localization.getString(Strings.Info_Midi_Record_Start), null, midiRecordCancelAction);
+		recordMidi = true;
+		useDraft = true;
+	}
+
+	@FXML
+	private void draftButtonHandler(ActionEvent event) {
+		Optional<MidiAction> midiAction = getSelectedMidiAction();
+		if (midiAction.isPresent()) {
+			try {
+				Profile.currentProfile().getMidiSetting().setDraftAction(midiAction.get().clone());
+				addMidiDraftButton.setDisable(false);
+			} catch (CloneNotSupportedException e) {
+				e.printStackTrace();
+				showError(Localization.getString(Strings.Error_Standard_Gen, e.getLocalizedMessage()));
+			}
+		}
+	}
+
+	@FXML
+	private void deleteMidiButtonHandler(ActionEvent event) {
+		Optional<MidiAction> midiAction = getSelectedMidiAction();
+		if (midiAction.isPresent()) {
+			getSelectedPreset().removeAction(midiAction.get()); // Model
+
+			// Remove from Tree UI
+			TreeItem<Displayable> midiTreeItem = getTreeObject(midiAction.get(), contentTreeView.getRoot());
+			contentTreeView.getRoot().getChildren().remove(midiTreeItem);
+		}
+	}
+
+	@FXML
+	private void clearMidiButtonHandler(ActionEvent event) {
+		Alert alert = new Alert(AlertType.CONFIRMATION);
+
+		alert.initOwner(owner);
+		alert.initModality(Modality.WINDOW_MODAL);
+		Stage dialog = (Stage) alert.getDialogPane().getScene().getWindow();
+		PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add);
+
+		alert.setContentText(Localization.getString(Strings.Info_Settings_Midi_ClearPreset));
+		alert.showAndWait().filter(item -> item == ButtonType.OK).ifPresent(item ->
+		{
+			getSelectedPreset().clearActions();
+			showMidiPresetActions();
+		});
+	}
+
+	// Accessor for User Input
+	public boolean isMidiActive() {
+		return midiActiveCheckBox.isSelected();
+	}
+
+	// Midi
+	@Override
+	public void onMidiAction(MidiMessage message) {
+		if (message.getLength() >= 3) {
+			if (message.getMessage()[2] != 0) {
+				// Neuer Midi Key (RECORD)
+				if (recordMidi) {
+					recordMidi = false;
+					notificationPane.hide();
+
+					int midiCommand = message.getMessage()[0];
+					byte midiKey = message.getMessage()[1];
+
+					if (getSelectedPreset().isContaining(midiCommand, midiKey)) {
+						notify(Localization.getString(Strings.Error_Midi_Record_Fail), PlayPadMain.notificationDisplayTimeMillis);
+						return;
+					}
+
+					try {
+						final MidiAction midiAction;
+
+						// Neue Aktion
+						if (useDraft == false) {
+							midiAction = new MidiAction(midiCommand, midiKey, getSelectedPreset());
+							if (midiAction != null) {
+								Platform.runLater(() ->
+								{
+									// Model neue Midi Action
+									getSelectedPreset().addAction(midiAction);
+									Collections.sort(getSelectedPreset().getMidiActions());
+
+									// GUI hinzufügen
+									addMidiActionToTree(midiAction);
+									selectPressedMidiAction(message);
+								});
+							}
+						} else {
+							// Verwende Vorlage und passe Midi an
+							midiAction = Profile.currentProfile().getMidiSetting().getDraftAction().get().clone();
+							midiAction.setMidiPreset(getSelectedPreset());
+							midiAction.setMidiCommand(midiCommand);
+							midiAction.setMidiKey(midiKey);
+
+							// Cart ID ändern
+							Platform.runLater(() ->
+							{
+								if (midiAction.getActionType().handleClone(midiAction, this)) {
+									if (midiAction != null) {
+										// Model neue Midi Action
+										getSelectedPreset().addAction(midiAction);
+										Collections.sort(getSelectedPreset().getMidiActions());
+
+										// GUI hinzufügen
+										addMidiActionToTree(midiAction);
+										selectPressedMidiAction(message);
+									}
+								}
+							});
+						}
+					} catch (Exception e) {
+						showError(Localization.getString(Strings.Error_Standard_Gen, e.getLocalizedMessage()));
+						e.printStackTrace();
+					}
+				} else {
+					selectPressedMidiAction(message);
+				}
+			}
+		}
+	}
+
+	// NotificationHandler
+	@Override
+	public void notify(String text, long duration) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showAndHide(text, duration);
+		} else {
+			Platform.runLater(() -> notificationPane.showAndHide(text, duration));
+		}
+	}
+
+	@Override
+	public void notify(String text, long duration, Runnable finish) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showAndHide(text, duration, finish);
+		} else {
+			Platform.runLater(() -> notificationPane.showAndHide(text, duration, finish));
+		}
+	}
+
+	@Override
+	public void show(String message, org.controlsfx.control.action.Action... action) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.show(message, null, action);
+		} else {
+			Platform.runLater(() -> notificationPane.show(message, null, action));
+		}
+	}
+
+	@Override
+	public void showError(String message) {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.showError(message);
+		} else {
+			Platform.runLater(() -> notificationPane.showError(message));
+		}
+	}
+
+	@Override
+	public void hide() {
+		if (Platform.isFxApplicationThread()) {
+			notificationPane.hide();
+		} else {
+			Platform.runLater(() -> notificationPane.hide());
+		}
+	}
+
+	// Update Data (Wird in SettingsViewController bei showCurrentSettings aufgerufen)
+	@Override
+	public void updateData() {
+		ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings();
+		deviceComboBox.setValue(profileSettings.getMidiDevice());
+		midiActiveCheckBox.setSelected(profileSettings.isMidiActive());
+	}
+
+	// Display Settings ViewController der jeweiligen Action, basierend auf dem Type
+	/*
+	 * Wird aufgerufen, wenn in der Liste Links was ausgewählt wird
+	 */
+	@Override
+	public void changed(ObservableValue<? extends TreeItem<Displayable>> observable, TreeItem<Displayable> oldValue,
+			TreeItem<Displayable> newValue) {
+		settingsAnchorPane.getChildren().clear();
+		if (newValue != null)
+			showSettingsView(newValue.getValue());
+		updateButtonDisable();
+	}
+
+	@Override
+	public void loadSettings(Profile profile) {
+		updateData();
+	}
+
+	@Override
+	public void saveSettings(Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+
+		// Midi
+		profileSettings.setMidiActive(isMidiActive());
+	}
+
+	@Override
+	public boolean validSettings() {
+		return true;
+	}
+
+	@Override
+	public boolean needReload() {
+		return true;
+	}
+
+	@Override
+	public void reload(Profile profile, Project project, IMainViewController controller) {
+		if (Midi.getInstance().getMidiDevice().isPresent())
+			try {
+				Midi.getInstance().getMidiDevice().get().showFeedbackForPage(controller.getPage(), controller.getPage(), project);
+			} catch (MidiUnavailableException | InvalidMidiDataException e) {
+				e.printStackTrace();
+			}
+	}
+
+	@Override
+	public String name() {
+		return Localization.getString(Strings.UI_Window_Settings_Midi_Title);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/PlayerTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/PlayerTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..94713e8a15dba9fae93ac619173bdf5eebfd416a
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/PlayerTabViewController.java
@@ -0,0 +1,83 @@
+package de.tobias.playpad.viewcontroller.option;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.TimeMode;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.viewcontroller.cell.EnumCell;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.playpad.viewcontroller.settings.FadeViewController;
+import de.tobias.playpad.viewcontroller.settings.WarningFeedbackViewController;
+import de.tobias.utils.util.Localization;
+import javafx.fxml.FXML;
+import javafx.scene.control.ComboBox;
+import javafx.scene.layout.VBox;
+
+public class PlayerTabViewController extends SettingsTabViewController {
+
+	// Player
+	@FXML private VBox warningFeedbackContainer;
+	@FXML private VBox fadeContainer;
+	@FXML private ComboBox<TimeMode> timeDisplayComboBox;
+
+	public PlayerTabViewController() {
+		super("playerTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle());
+
+		// Player
+		FadeViewController fadeViewController = new FadeViewController();
+		fadeViewController.setFade(Profile.currentProfile().getProfileSettings().getFade());
+		fadeContainer.getChildren().add(fadeViewController.getParent());
+		setAnchor(fadeViewController.getParent(), 0, 0, 0, 0);
+	}
+
+	public ComboBox<TimeMode> getTimeDisplayComboBox() {
+		return timeDisplayComboBox;
+	}
+
+	@Override
+	public void init() {
+		WarningFeedbackViewController controller = new WarningFeedbackViewController();
+		warningFeedbackContainer.getChildren().add(controller.getParent());
+
+		// Player
+		timeDisplayComboBox.getItems().addAll(TimeMode.values());
+		timeDisplayComboBox.setButtonCell(new EnumCell<>(Strings.Pad_TimeMode_BaseName));
+		timeDisplayComboBox.setCellFactory(list -> new EnumCell<>(Strings.Pad_TimeMode_BaseName));
+	}
+
+	@Override
+	public void loadSettings(Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+
+		timeDisplayComboBox.setValue(profileSettings.getPlayerTimeDisplayMode());
+	}
+
+	@Override
+	public void saveSettings(Profile profile) {
+		ProfileSettings profileSettings = profile.getProfileSettings();
+
+		// Player
+		profileSettings.setPlayerTimeDisplayMode(timeDisplayComboBox.getValue());
+	}
+
+	@Override
+	public boolean needReload() {
+		return false;
+	}
+
+	@Override
+	public void reload(Profile profile, Project project, IMainViewController controller) {}
+
+	@Override
+	public boolean validSettings() {
+		return true;
+	}
+
+	@Override
+	public String name() {
+		return Localization.getString(Strings.UI_Window_Settings_Player_Title);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..2e4726e0816543c7489c1b544ec5fdf32bccf8c9
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java
@@ -0,0 +1,169 @@
+package de.tobias.playpad.viewcontroller.option;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
+import de.tobias.playpad.pad.conntent.UnkownPadContentException;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.ISettingsViewController;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.stage.Screen;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class SettingsViewController extends ViewController implements ISettingsViewController {
+
+	@FXML private TabPane tabPane;
+	@FXML private Button finishButton;
+
+	protected List<SettingsTabViewController> tabs = new ArrayList<>();
+
+	public SettingsViewController(Midi midiHandler, Screen screen, Window owner, Project project) {
+		super("settingsView", "de/tobias/playpad/assets/view/option/", null, PlayPadMain.getUiResourceBundle());
+
+		boolean activePlayer = project.getPlayedPlayers() > 0;
+
+		addTab(new GeneralTabViewController(screen, this, activePlayer));
+		addTab(new MappingTabViewController());
+		addTab(new MidiTabViewController());
+		addTab(new LayoutTabViewController());
+		addTab(new PlayerTabViewController());
+
+		// Content Types
+		for (String type : PadContentRegistry.getTypes()) {
+			try {
+				SettingsTabViewController controller = PadContentRegistry.getPadContentConnect(type).getSettingsTabViewController(activePlayer);
+				if (controller != null) {
+					addTab(controller);
+				}
+			} catch (UnkownPadContentException e) {
+				e.printStackTrace();
+			}
+		}
+
+		// Listener
+		PlayPadPlugin.getImplementation().getSettingsViewListener().forEach(l ->
+		{
+			try {
+				l.onInit(this);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		});
+		addTab(new UpdateTabViewController());
+
+		getStage().initOwner(owner);
+
+		// Show Current Settings
+		showCurrentSettings();
+	}
+
+	@Override
+	public void init() {
+		// KeyCode
+		addCloseKeyShortcut(() -> finishButton.fire());
+		finishButton.defaultButtonProperty().bind(finishButton.focusedProperty());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setMinWidth(715);
+		stage.setMinHeight(700);
+		stage.setTitle(Localization.getString(Strings.UI_Window_Settings_Title, Profile.currentProfile().getRef().getName()));
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	// Copy Of Settings
+	public boolean closeRequest() {
+		boolean valid = true;
+		for (SettingsTabViewController controller : tabs) {
+			if (controller.validSettings() == false) {
+				valid = false;
+			}
+		}
+
+		if (valid) { // Einstellungen sind Valide
+			// Listener
+			PlayPadPlugin.getImplementation().getSettingsViewListener().forEach(l -> l.onClose(this));
+
+			saveChanges();
+			getStage().close();
+			updateData();
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	// Settings aus AppSettings
+	private void showCurrentSettings() {
+		Profile profile = Profile.currentProfile();
+		for (SettingsTabViewController controller : tabs) {
+			controller.loadSettings(profile);
+		}
+	}
+
+	private void saveChanges() {
+		Profile profile = Profile.currentProfile();
+		for (SettingsTabViewController controller : tabs) {
+			controller.saveSettings(profile);
+		}
+
+		try {
+			profile.save();
+		} catch (Exception e) {
+			showErrorMessage(Localization.getString(Strings.Error_Profile_Save, e.getLocalizedMessage()));
+			e.printStackTrace();
+		}
+	}
+
+	public boolean needUpdate() {
+		boolean change = false;
+		for (SettingsTabViewController controller : tabs) {
+			if (controller.needReload()) {
+				change = true;
+			}
+		}
+		return change;
+	}
+
+	@FXML
+	private void finishButtonHandler(ActionEvent event) {
+		boolean valid = true;
+		for (SettingsTabViewController controller : tabs) {
+			if (controller.validSettings() == false) {
+				valid = false;
+			}
+		}
+
+		if (valid) { // Einstellungen sind Valide
+			// Listener
+			PlayPadPlugin.getImplementation().getSettingsViewListener().forEach(l -> l.onClose(this));
+
+			saveChanges();
+			getStage().close();
+			updateData();
+		}
+	}
+
+	public void addTab(SettingsTabViewController controller) {
+		tabs.add(controller);
+		tabPane.getTabs().add(new Tab(controller.name(), controller.getParent()));
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/UpdateTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/UpdateTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..0edd9042f39d8a1917d7f57927b18b23d6793074
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/UpdateTabViewController.java
@@ -0,0 +1,260 @@
+package de.tobias.playpad.viewcontroller.option;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Optional;
+
+import de.tobias.playpad.AppUserInfoStrings;
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.Updatable;
+import de.tobias.playpad.UpdateRegistery;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.SettingsTabViewController;
+import de.tobias.playpad.viewcontroller.cell.UpdateCell;
+import de.tobias.playpad.viewcontroller.dialog.UpdaterDialog;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.NativeLauncher;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.util.Localization;
+import de.tobias.utils.util.OS;
+import de.tobias.utils.util.OS.OSType;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListView;
+import javafx.scene.control.ProgressIndicator;
+import javafx.scene.image.Image;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class UpdateTabViewController extends SettingsTabViewController {
+
+	private static final String DOWNLOAD_FOLDER = "Updates";
+	private static final String UPDATER_JAR = "Updater.jar";
+	private static final String UPDATER_EXE = "Updater.exe";
+
+	@FXML private Label currentVersionLabel;
+	@FXML private Label newVersionLabel;
+
+	@FXML private CheckBox automaticSearchCheckBox;
+	@FXML private Button manualSearchButton;
+
+	@FXML private ListView<Updatable> openUpdateList;
+	@FXML private Button updateButton;
+
+	private ProgressIndicator progressIndecator;
+	private Label placeholderLabel;
+
+	public UpdateTabViewController() {
+		super("updateTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle());
+
+		openUpdateList.getItems().setAll(UpdateRegistery.getAvailableUpdates());
+		updateButton.setDisable(openUpdateList.getItems().isEmpty());
+
+		Worker.runLater(() ->
+		{
+			Updatable updater = PlayPadMain.getUpdater();
+			updater.checkUpdate();
+			Platform.runLater(() ->
+			{
+				currentVersionLabel.setText(Localization.getString(Strings.UI_Window_Settings_Updates_CurrentVersion,
+						updater.getCurrentVersion(), updater.getCurrentBuild()));
+				newVersionLabel.setText(Localization.getString(Strings.UI_Window_Settings_Updates_CurrentVersion, updater.getNewVersion(),
+						updater.getNewBuild()));
+			});
+		});
+	}
+
+	@Override
+	public void init() {
+		openUpdateList.setCellFactory(list -> new UpdateCell());
+
+		progressIndecator = new ProgressIndicator(-1);
+		progressIndecator.setMinSize(25, 25);
+
+		placeholderLabel = new Label(Localization.getString(Strings.UI_Placeholder_Updates));
+		openUpdateList.setPlaceholder(placeholderLabel);
+
+		updateButton.setDisable(openUpdateList.getItems().isEmpty());
+	}
+
+	@FXML
+	private void manualSearchHandler(ActionEvent event) {
+		openUpdateList.getItems().clear();
+
+		openUpdateList.setPlaceholder(progressIndecator);
+		UpdateRegistery.lookupUpdates();
+		openUpdateList.setPlaceholder(placeholderLabel);
+
+		openUpdateList.getItems().setAll(UpdateRegistery.getAvailableUpdates());
+		updateButton.setDisable(openUpdateList.getItems().isEmpty());
+	}
+
+	@FXML
+	private void updateHandler(ActionEvent event) {
+		update(getStage());
+	}
+
+	public static void update(Window dialogOwner) {
+		String parameter = UpdateRegistery
+				.buildParamaterString(ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, DOWNLOAD_FOLDER).toString());
+		if (OS.getType() == OSType.Windows) {
+			try {
+				Path fileJar = Paths.get(UPDATER_JAR);
+				Path fileExe = Paths.get(UPDATER_EXE);
+				Path fileJarFolder = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_JAR);
+				Path fileExeFolder = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_EXE);
+
+				if (Files.exists(fileJar)) {
+					startJarFile(parameter, fileJar);
+				} else if (Files.exists(fileExe)) {
+					startExeFile(parameter, fileExe);
+
+				} else if (Files.exists(fileJarFolder)) {
+					startJarFile(parameter, fileJarFolder);
+				} else if (Files.exists(fileExeFolder)) {
+					startExeFile(parameter, fileExeFolder);
+				} else {
+					UpdaterDialog dialog = new UpdaterDialog(dialogOwner);
+					dialog.show();
+
+					Worker.runLater(() ->
+					{
+						String updaterURL = ApplicationUtils.getApplication().getInfo().getUserInfo().get(AppUserInfoStrings.UPDATER_PROGRAM)
+								+ UPDATER_EXE;
+						Path path = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_EXE);
+						try {
+							downloadUpdater(updaterURL, path);
+							startExeFile(parameter, path);
+						} catch (Exception e) {
+							e.printStackTrace();
+							String errorMessage = Localization.getString(Strings.Error_Update_Download, e.getMessage());
+							showErrorMessage(errorMessage, PlayPadPlugin.getImplementation().getIcon(), dialogOwner);
+						}
+					});
+				}
+			} catch (Exception ex) {
+				ex.printStackTrace();
+			}
+		} else {
+			try {
+				Path fileJar = Paths.get(UPDATER_JAR);
+				Path fileJarFolder = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_JAR);
+
+				if (Files.exists(fileJar)) {
+					startJarFile(parameter, fileJar);
+				} else if (Files.exists(fileJarFolder)) {
+					startJarFile(parameter, fileJarFolder);
+				} else {
+					UpdaterDialog dialog = new UpdaterDialog(dialogOwner);
+					dialog.show();
+
+					Worker.runLater(() ->
+					{
+						String updaterURL = ApplicationUtils.getApplication().getInfo().getUserInfo().get(AppUserInfoStrings.UPDATER_PROGRAM)
+								+ UPDATER_JAR;
+						Path path = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_JAR);
+						try {
+							downloadUpdater(updaterURL, path);
+							startJarFile(parameter, path);
+						} catch (Exception e) {
+							e.printStackTrace();
+							String errorMessage = Localization.getString(Strings.Error_Update_Download, e.getMessage());
+							showErrorMessage(errorMessage, PlayPadPlugin.getImplementation().getIcon(), dialogOwner);
+						}
+					});
+				}
+			} catch (Exception ex) {
+				ex.printStackTrace();
+			}
+		}
+	}
+
+	private static void downloadUpdater(String updaterURL, Path path) throws IOException, MalformedURLException {
+		if (Files.notExists(path)) {
+			Files.createDirectories(path.getParent());
+			Files.createFile(path);
+		}
+
+		URLConnection conn = new URL(updaterURL).openConnection();
+
+		InputStream iStr = conn.getInputStream();
+		OutputStream oStr = Files.newOutputStream(path);
+
+		byte[] data = new byte[1024];
+		int dataLength = 0;
+		while ((dataLength = iStr.read(data, 0, data.length)) > 0) {
+			oStr.write(data, 0, dataLength);
+		}
+		oStr.close();
+	}
+
+	private static void startExeFile(String parameter, Path fileExeFolder) {
+		NativeLauncher.executeAsAdministrator(fileExeFolder.toAbsolutePath().toString(), parameter);
+		System.exit(0);
+	}
+
+	private static void startJarFile(String parameter, Path fileJarFolder) throws IOException {
+		ProcessBuilder builder = new ProcessBuilder("java", "-jar", fileJarFolder.toAbsolutePath().toString(), parameter);
+		builder.start();
+		System.exit(0);
+	}
+
+	@Override
+	public void loadSettings(Profile profile) {
+		automaticSearchCheckBox.setSelected(profile.getProfileSettings().isAutoUpdate());
+	}
+
+	@Override
+	public void saveSettings(Profile profile) {
+		profile.getProfileSettings().setAutoUpdate(automaticSearchCheckBox.isSelected());
+	}
+
+	@Override
+	public boolean needReload() {
+		return false;
+	}
+
+	@Override
+	public boolean validSettings() {
+		return true;
+	}
+
+	@Override
+	public String name() {
+		return Localization.getString(Strings.UI_Window_Settings_Updates_Title);
+	}
+
+	private static void showErrorMessage(String message, Optional<Image> icon, Window owner) {
+		if (!Platform.isFxApplicationThread()) {
+			Platform.runLater(() -> showErrorMessage(message, icon, owner));
+			return;
+		}
+
+		Alert alert = new Alert(AlertType.ERROR);
+		alert.initOwner(owner);
+		alert.initModality(Modality.WINDOW_MODAL);
+		alert.setContentText(message);
+		if (icon.isPresent()) {
+			Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
+			stage.getIcons().add(icon.get());
+		}
+		alert.showAndWait();
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/DoubleFeedbackViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/DoubleFeedbackViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..24c6cfb81e5544f1beb8ac696a4a96555a170cf8
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/DoubleFeedbackViewController.java
@@ -0,0 +1,122 @@
+package de.tobias.playpad.viewcontroller.option.feedback;
+
+import java.util.Optional;
+
+import org.controlsfx.control.PopOver;
+import org.controlsfx.control.PopOver.ArrowLocation;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.action.feedback.DisplayableFeedbackColor;
+import de.tobias.playpad.action.feedback.DoubleSimpleFeedback;
+import de.tobias.playpad.action.feedback.FeedbackMessage;
+import de.tobias.playpad.action.mididevice.Device;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.view.ColorView;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.layout.HBox;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Rectangle;
+
+public class DoubleFeedbackViewController extends ContentViewController {
+
+	@FXML private HBox defaultColorParent;
+	@FXML private Button colorChooseDefaultButton;
+	@FXML private Rectangle colorPreviewDefault;
+
+	@FXML private HBox eventColorParent;
+	@FXML private Button colorChooseEventButton;
+	@FXML private Rectangle colorPreviewEvent;
+
+	private PopOver colorChooser;
+
+	private DoubleSimpleFeedback feedback;
+
+	public DoubleFeedbackViewController(DoubleSimpleFeedback feedback, DisplayableFeedbackColor[] colors) {
+		super("doubleFeedback", "de/tobias/playpad/assets/view/option/feedback/", PlayPadMain.getUiResourceBundle());
+		this.feedback = feedback;
+
+		Optional<Device> deviceOptional = Midi.getInstance().getMidiDevice();
+		deviceOptional.ifPresent(device ->
+		{
+			DisplayableFeedbackColor colorDefault = device.getColor(feedback.getValueForFeedbackMessage(FeedbackMessage.STANDARD));
+			if (colorDefault != null) {
+				colorPreviewDefault.setFill(colorDefault.getPaint());
+				setColorChooseButtonColor(colorDefault.getPaint(), colorChooseDefaultButton);
+			}
+			DisplayableFeedbackColor colorPlay = device.getColor(feedback.getValueForFeedbackMessage(FeedbackMessage.EVENT));
+			if (colorPlay != null) {
+				colorPreviewEvent.setFill(colorPlay.getPaint());
+				setColorChooseButtonColor(colorPlay.getPaint(), colorChooseEventButton);
+			}
+		});
+	}
+
+	@Override
+	public void init() {
+		FontIcon iconDefault = new FontIcon(FontAwesomeType.ARROW_CIRCLE_DOWN);
+		iconDefault.getStyleClass().remove(FontIcon.STYLE_CLASS);
+		colorChooseDefaultButton.setGraphic(iconDefault);
+		colorPreviewDefault.widthProperty().bind(colorChooseDefaultButton.widthProperty());
+
+		FontIcon iconEvent = new FontIcon(FontAwesomeType.ARROW_CIRCLE_DOWN);
+		iconEvent.getStyleClass().remove(FontIcon.STYLE_CLASS);
+		colorChooseEventButton.setGraphic(iconEvent);
+		colorPreviewEvent.widthProperty().bind(colorChooseEventButton.widthProperty());
+	}
+
+	@FXML
+	private void colorChooseButtonHandler(ActionEvent event) {
+		if (colorChooser == null) {
+			colorChooser = new PopOver();
+			Midi.getInstance().getMidiDevice().ifPresent((device) ->
+			{
+				DisplayableFeedbackColor color = device.getColor(feedback.getValueForFeedbackMessage(FeedbackMessage.STANDARD));
+				if (event.getSource() == colorChooseDefaultButton) {
+					color = device.getColor(feedback.getValueForFeedbackMessage(FeedbackMessage.STANDARD));
+				} else if (event.getSource() == colorChooseEventButton) {
+					color = device.getColor(feedback.getValueForFeedbackMessage(FeedbackMessage.EVENT));
+				}
+				
+				ColorView colorView = new ColorView(color, device.getColors(), item ->
+				{
+					colorChooser.hide();
+					if (item instanceof DisplayableFeedbackColor) {
+						if (event.getSource() == colorChooseDefaultButton) {
+							feedback.setFeedbackDefaultValue(((DisplayableFeedbackColor) item).midiVelocity());
+							colorPreviewDefault.setFill(item.getPaint());
+							setColorChooseButtonColor(item.getPaint(), colorChooseDefaultButton);
+						} else if (event.getSource() == colorChooseEventButton) {
+							feedback.setFeedbackEventValue(((DisplayableFeedbackColor) item).midiVelocity());
+							colorPreviewEvent.setFill(item.getPaint());
+							setColorChooseButtonColor(item.getPaint(), colorChooseEventButton);
+						}
+					}
+				});
+
+				colorChooser.setContentNode(colorView);
+				colorChooser.setDetachable(false);
+				colorChooser.setOnHiding(e -> colorChooser = null);
+				colorChooser.setCornerRadius(5);
+				colorChooser.setArrowLocation(ArrowLocation.LEFT_CENTER);
+				colorChooser.show((Node) event.getSource());
+			});
+		}
+
+	}
+
+	private void setColorChooseButtonColor(Paint inputColor, Button button) {
+		Color color;
+		if (inputColor.equals(Color.BLACK))
+			color = Color.WHITE;
+		else
+			color = Color.BLACK;
+		((FontIcon) button.getGraphic()).setColor(color);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/SingleFeedbackViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/SingleFeedbackViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a737802e3b7579ce6ea35d480f8cb79356fb002
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/SingleFeedbackViewController.java
@@ -0,0 +1,98 @@
+package de.tobias.playpad.viewcontroller.option.feedback;
+
+import java.util.Optional;
+
+import org.controlsfx.control.PopOver;
+import org.controlsfx.control.PopOver.ArrowLocation;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.action.feedback.DisplayableFeedbackColor;
+import de.tobias.playpad.action.feedback.FeedbackMessage;
+import de.tobias.playpad.action.feedback.SingleSimpleFeedback;
+import de.tobias.playpad.action.mididevice.Device;
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.view.ColorView;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.layout.HBox;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Rectangle;
+
+public class SingleFeedbackViewController extends ContentViewController {
+
+	@FXML private HBox defaultColorParent;
+	@FXML private Button colorChooseDefaultButton;
+	@FXML private Rectangle colorPreviewDefault;
+
+	private PopOver colorChooser;
+
+	private SingleSimpleFeedback feedback;
+
+	public SingleFeedbackViewController(SingleSimpleFeedback feedback, DisplayableFeedbackColor[] colors) {
+		super("singleFeedback", "de/tobias/playpad/assets/view/option/feedback/", PlayPadMain.getUiResourceBundle());
+		this.feedback = feedback;
+
+		Optional<Device> deviceOptional = Midi.getInstance().getMidiDevice();
+		deviceOptional.ifPresent(device ->
+		{
+			DisplayableFeedbackColor colorDefault = device.getColor(feedback.getValueForFeedbackMessage(FeedbackMessage.STANDARD));
+			if (colorDefault != null) {
+				colorPreviewDefault.setFill(colorDefault.getPaint());
+				setColorChooseButtonColor(colorDefault.getPaint(), colorChooseDefaultButton);
+			}
+		});
+	}
+
+	@Override
+	public void init() {
+		FontIcon iconDefault = new FontIcon(FontAwesomeType.ARROW_CIRCLE_DOWN);
+		iconDefault.getStyleClass().remove(FontIcon.STYLE_CLASS);
+		colorChooseDefaultButton.setGraphic(iconDefault);
+		colorPreviewDefault.widthProperty().bind(colorChooseDefaultButton.widthProperty());
+	}
+
+	@FXML
+	private void colorChooseButtonHandler(ActionEvent event) {
+		if (colorChooser == null) {
+			colorChooser = new PopOver();
+			Midi.getInstance().getMidiDevice().ifPresent((device) ->
+			{
+				DisplayableFeedbackColor color = device.getColor(feedback.getValueForFeedbackMessage(FeedbackMessage.STANDARD));
+
+				ColorView colorView = new ColorView(color, device.getColors(), item ->
+				{
+					colorChooser.hide();
+					if (item instanceof DisplayableFeedbackColor) {
+						if (event.getSource() == colorChooseDefaultButton) {
+							feedback.setFeedbackValue(((DisplayableFeedbackColor) item).midiVelocity());
+							colorPreviewDefault.setFill(item.getPaint());
+							setColorChooseButtonColor(item.getPaint(), colorChooseDefaultButton);
+						}
+					}
+				});
+
+				colorChooser.setContentNode(colorView);
+				colorChooser.setDetachable(false);
+				colorChooser.setOnHiding(e -> colorChooser = null);
+				colorChooser.setCornerRadius(5);
+				colorChooser.setArrowLocation(ArrowLocation.LEFT_CENTER);
+				colorChooser.show((Node) event.getSource());
+			});
+		}
+	}
+
+	private void setColorChooseButtonColor(Paint inputColor, Button button) {
+		Color color;
+		if (inputColor.equals(Color.BLACK))
+			color = Color.WHITE;
+		else
+			color = Color.BLACK;
+		((FontIcon) button.getGraphic()).setColor(color);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/GeneralPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/GeneralPadTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..006630b24349cc74a2e18dbf99903f2524fd0226
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/GeneralPadTabViewController.java
@@ -0,0 +1,95 @@
+package de.tobias.playpad.viewcontroller.option.pad;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.TimeMode;
+import de.tobias.playpad.viewcontroller.PadSettingsTabViewController;
+import de.tobias.playpad.viewcontroller.cell.EnumCell;
+import de.tobias.utils.util.Localization;
+import javafx.beans.value.ChangeListener;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Slider;
+import javafx.scene.control.TextField;
+import javafx.stage.Stage;
+
+public class GeneralPadTabViewController extends PadSettingsTabViewController {
+
+	@FXML private TextField titleTextField;
+	@FXML private Slider volumeSlider;
+	@FXML private CheckBox repeatCheckBox;
+
+	@FXML private CheckBox customTimeDisplayCheckBox;
+	@FXML private ComboBox<TimeMode> timeDisplayComboBox;
+
+	@FXML private Button deleteButton;
+
+	private Pad pad;
+
+	private ChangeListener<Number> volumeListener;
+
+	public GeneralPadTabViewController(Pad pad) {
+		super("generalTab", "de/tobias/playpad/assets/view/option/pad/", PlayPadMain.getUiResourceBundle());
+		this.pad = pad;
+	}
+
+	@Override
+	public void init() {
+		// Init Listener
+		volumeListener = (a, b, c) -> pad.setVolume(c.doubleValue() / 100.0);
+
+		volumeSlider.valueProperty().addListener(volumeListener);
+
+		customTimeDisplayCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			timeDisplayComboBox.setDisable(!c);
+			if (c && !pad.isCustomTimeMode())
+				pad.setTimeMode(TimeMode.REST);
+			else if (b && pad.isCustomTimeMode())
+				pad.setTimeMode(null);
+
+		});
+		timeDisplayComboBox.getItems().addAll(TimeMode.values());
+		timeDisplayComboBox.setButtonCell(new EnumCell<>(Strings.Pad_TimeMode_BaseName));
+		timeDisplayComboBox.setCellFactory(list -> new EnumCell<>(Strings.Pad_TimeMode_BaseName));
+	}
+
+	@Override
+	public String getName() {
+		return Localization.getString(Strings.UI_Window_PadSettings_General_Title);
+	}
+
+	@Override
+	public void loadSettings(Pad pad) {
+		// Bindings
+		titleTextField.textProperty().bindBidirectional(pad.nameProperty());
+		repeatCheckBox.selectedProperty().bindBidirectional(pad.loopProperty());
+		timeDisplayComboBox.valueProperty().bindBidirectional(pad.timeModeProperty());
+
+		volumeSlider.setValue(pad.getVolume() * 100);
+
+		// is Custom TimeMode Actvie
+		customTimeDisplayCheckBox.setSelected(pad.isCustomTimeMode());
+		if (!pad.isCustomTimeMode()) {
+			timeDisplayComboBox.setDisable(true);
+		}
+	}
+
+	@Override
+	public void saveSettings(Pad pad) {
+		titleTextField.textProperty().unbindBidirectional(pad.nameProperty());
+		repeatCheckBox.selectedProperty().unbindBidirectional(pad.loopProperty());
+		timeDisplayComboBox.valueProperty().unbindBidirectional(pad.timeModeProperty());
+	}
+
+	// Listener
+	@FXML
+	private void deleteButtonHandler(ActionEvent event) {
+		pad.clear();
+		((Stage) getStage()).close();
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/LayoutPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/LayoutPadTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..775bdb6dd999e39b15e072cf6fee2fc1b0e3f57c
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/LayoutPadTabViewController.java
@@ -0,0 +1,90 @@
+package de.tobias.playpad.viewcontroller.option.pad;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.layout.CartLayout;
+import de.tobias.playpad.layout.LayoutRegistry;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.CartLayoutViewController;
+import de.tobias.playpad.viewcontroller.PadSettingsTabViewController;
+import de.tobias.utils.util.Localization;
+import javafx.fxml.FXML;
+import javafx.scene.control.CheckBox;
+import javafx.scene.layout.VBox;
+
+public class LayoutPadTabViewController extends PadSettingsTabViewController {
+
+	@FXML private VBox layoutContainer;
+	@FXML private CheckBox enableLayoutCheckBox;
+	private CartLayoutViewController layoutViewController;
+
+	private Pad pad;
+
+	public LayoutPadTabViewController(Pad pad) {
+		super("layoutTab", "de/tobias/playpad/assets/view/option/pad/", PlayPadMain.getUiResourceBundle());
+		this.pad = pad;
+	}
+
+	private void setLayoutController(CartLayoutViewController cartLayoutViewController) {
+		if (layoutViewController != null)
+			layoutContainer.getChildren().remove(layoutViewController.getParent());
+
+		if (cartLayoutViewController != null) {
+			layoutViewController = cartLayoutViewController;
+			layoutContainer.getChildren().add(layoutViewController.getParent());
+		}
+	}
+
+	@Override
+	public void init() {
+		enableLayoutCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			if (c && !pad.isCustomLayout()) {
+				try {
+					pad.setCustomLayout(true);
+					try {
+						String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType();
+						CartLayout layout = pad.getLayout(layoutType);
+						setLayoutController(LayoutRegistry.getLayout(layoutType).getCartLayoutViewController(layout));
+					} catch (Exception e) {
+						e.printStackTrace();
+						showErrorMessage(Localization.getString(Strings.Error_Layout_Load, e.getMessage()));
+					}
+				} catch (Exception e) {
+					showErrorMessage(Localization.getString(Strings.Error_Standard_Gen, e.getLocalizedMessage()));
+					e.printStackTrace();
+				}
+			} else if (!c && pad.isCustomLayout()) {
+				pad.setCustomLayout(false);
+				setLayoutController(null);
+			}
+		});
+	}
+
+	@Override
+	public String getName() {
+		return Localization.getString(Strings.UI_Window_PadSettings_Layout_Title);
+	}
+
+	@Override
+	public void loadSettings(Pad pad) {
+		enableLayoutCheckBox.setSelected(pad.isCustomLayout());
+		if (pad.isCustomLayout()) {
+			try {
+				String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType();
+				CartLayout layout = pad.getLayout(layoutType);
+				setLayoutController(LayoutRegistry.getLayout(layoutType).getCartLayoutViewController(layout));
+			} catch (Exception e) {
+				e.printStackTrace();
+				showErrorMessage(Localization.getString(Strings.Error_Layout_Load, e.getMessage()));
+			}
+		}
+	}
+
+	@Override
+	public void saveSettings(Pad pad) {
+		PlayPadPlugin.getImplementation().getMainViewController().loadUserCss();
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a4f591202f5b74d90a8ccb4f7c995e52d14fed9
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java
@@ -0,0 +1,128 @@
+package de.tobias.playpad.viewcontroller.option.pad;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
+import de.tobias.playpad.pad.conntent.UnkownPadContentException;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.IPadSettingsViewController;
+import de.tobias.playpad.viewcontroller.PadSettingsTabViewController;
+import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+
+public class PadSettingsViewController extends ViewController implements IPadSettingsViewController {
+
+	private Pad pad;
+
+	@FXML private TabPane tabPane;
+	protected List<PadSettingsTabViewController> tabs = new ArrayList<>();
+
+	@FXML private Button finishButton;
+
+	public PadSettingsViewController(Pad pad, Window owner) {
+		super("padSettingsView", "de/tobias/playpad/assets/view/option/pad/", null, PlayPadMain.getUiResourceBundle());
+		this.pad = pad;
+
+		addTab(new GeneralPadTabViewController(pad));
+		addTab(new LayoutPadTabViewController(pad));
+		addTab(new PlayerPadTabViewController(pad));
+		addTab(new TriggerPadTabViewController(pad));
+
+		if (pad.getContent() != null) {
+			try {
+				PadSettingsTabViewController contentTab = PadContentRegistry.getPadContentConnect(pad.getContent().getType())
+						.getSettingsViewController(pad);
+				if (contentTab != null)
+					addTab(contentTab);
+			} catch (UnkownPadContentException e) {
+				e.printStackTrace();
+			}
+		}
+
+		// Listener
+		PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l ->
+		{
+			try {
+				l.onInit(this);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		});
+
+		getStage().initOwner(owner);
+
+		// Show Current Settings
+		showCurrentSettings();
+		getStage().setTitle(Localization.getString(Strings.UI_Window_PadSettings_Title, pad.getIndexReadable(), pad.getName()));
+	}
+
+	@Override
+	public void init() {
+		addCloseKeyShortcut(() -> finishButton.fire());
+	}
+
+	@Override
+	public void initStage(Stage stage) {
+		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+		stage.setMinWidth(650);
+		stage.setMinHeight(500);
+
+		Profile.currentProfile().currentLayout().applyCss(getStage());
+	}
+
+	private void showCurrentSettings() {
+		for (PadSettingsTabViewController padSettingsTabViewController : tabs) {
+			padSettingsTabViewController.loadSettings(pad);
+		}
+	}
+
+	@Override
+	public void addTab(PadSettingsTabViewController controller) {
+		tabs.add(controller);
+
+		Tab tab = new Tab(controller.getName(), controller.getParent());
+		tabPane.getTabs().add(tab);
+	}
+
+	@Override
+	public Pad getPad() {
+		return pad;
+	}
+
+	@Override
+	public boolean closeRequest() {
+		saveChanges();
+
+		// Listener
+		PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onClose(this));
+		return true;
+	}
+
+	private void saveChanges() {
+		for (PadSettingsTabViewController controller : tabs) {
+			controller.saveSettings(pad);
+		}
+	}
+
+	@FXML
+	private void finishButtonHandler(ActionEvent event) {
+		saveChanges();
+		// Listener
+		PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onClose(this));
+		getStage().close();
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c6274b3da4766dfbba104f2a49e2f59a0648e8c
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java
@@ -0,0 +1,92 @@
+package de.tobias.playpad.viewcontroller.option.pad;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Fade;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.Warning;
+import de.tobias.playpad.viewcontroller.PadSettingsTabViewController;
+import de.tobias.playpad.viewcontroller.settings.FadeViewController;
+import de.tobias.playpad.viewcontroller.settings.WarningFeedbackViewController;
+import de.tobias.utils.util.Localization;
+import javafx.fxml.FXML;
+import javafx.scene.control.CheckBox;
+import javafx.scene.layout.VBox;
+
+public class PlayerPadTabViewController extends PadSettingsTabViewController {
+
+	@FXML private CheckBox customFadeCheckBox;
+	@FXML private VBox fadeContainer;
+	private FadeViewController fadeViewController;
+
+	@FXML private VBox warningFeedbackContainer;
+	@FXML private CheckBox warningEnableCheckBox;
+	private WarningFeedbackViewController warningFeedbackViewController;
+
+	private Pad pad;
+
+	public PlayerPadTabViewController(Pad pad) {
+		super("playerTab", "de/tobias/playpad/assets/view/option/pad/", PlayPadMain.getUiResourceBundle());
+		this.pad = pad;
+	}
+
+	@Override
+	public void init() {
+		// Embed ViewController
+		fadeViewController = new FadeViewController();
+		fadeContainer.getChildren().add(fadeViewController.getParent());
+
+		warningFeedbackViewController = new WarningFeedbackViewController(null);
+		warningFeedbackContainer.getChildren().add(warningFeedbackViewController.getParent());
+
+		customFadeCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			fadeContainer.setDisable(!c);
+			if (c && !pad.isCustomFade())
+				pad.setFade(new Fade());
+			else if (!c && pad.isCustomFade())
+				pad.setFade(null);
+
+			if (c)
+				fadeViewController.setFade(pad.getFade());
+		});
+
+		warningEnableCheckBox.selectedProperty().addListener((a, b, c) ->
+		{
+			warningFeedbackContainer.setDisable(!c);
+			if (c && !pad.isCustomWarning())
+				pad.setWarning(new Warning());
+			else if (!c && pad.isCustomWarning())
+				pad.setWarning(null);
+
+			if (c)
+				warningFeedbackViewController.setPadWarning(pad);
+		});
+	}
+
+	@Override
+	public String getName() {
+		return Localization.getString(Strings.UI_Window_PadSettings_Player_Title);
+	}
+
+	@Override
+	public void loadSettings(Pad pad) {
+		if (pad.isCustomFade())
+			fadeViewController.setFade(pad.getFade());
+
+		customFadeCheckBox.setSelected(pad.isCustomFade());
+		if (!pad.isCustomFade()) {
+			fadeContainer.setDisable(true);
+		}
+
+		warningEnableCheckBox.setSelected(pad.isCustomWarning());
+		if (!pad.isCustomWarning()) {
+			warningFeedbackContainer.setDisable(true);
+		}
+	}
+
+	@Override
+	public void saveSettings(Pad pad) {
+
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6fb894434191e4df9bb6fe509dfdac2bc9c0413
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java
@@ -0,0 +1,80 @@
+package de.tobias.playpad.viewcontroller.option.pad;
+
+import java.util.HashMap;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.tigger.Trigger;
+import de.tobias.playpad.tigger.TriggerPoint;
+import de.tobias.playpad.trigger.TriggerWrapper;
+import de.tobias.playpad.viewcontroller.PadSettingsTabViewController;
+import de.tobias.playpad.viewcontroller.cell.DisplayableTreeCell;
+import de.tobias.playpad.viewcontroller.option.pad.trigger.TriggerPointViewController;
+import de.tobias.utils.util.Localization;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.fxml.FXML;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+
+public class TriggerPadTabViewController extends PadSettingsTabViewController implements ChangeListener<TreeItem<TriggerWrapper>> {
+
+	@FXML private TreeView<TriggerWrapper> treeView;
+	@FXML private VBox contentView;
+
+	private Pad pad;
+
+	public TriggerPadTabViewController(Pad pad) {
+		super("triggerTab", "de/tobias/playpad/assets/view/option/pad/", PlayPadMain.getUiResourceBundle());
+		this.pad = pad;
+	}
+
+	@Override
+	public void init() {
+		treeView.setCellFactory(list -> new DisplayableTreeCell<>());
+		treeView.getSelectionModel().selectedItemProperty().addListener(this);
+	}
+
+	private void createTreeView() {
+		HashMap<TriggerPoint, Trigger> triggers = pad.getTriggers();
+		TreeItem<TriggerWrapper> rootItem = new TreeItem<>();
+
+		// Sort the tpyes for the treeview
+		for (TriggerPoint point : TriggerPoint.values()) {
+			Trigger trigger = triggers.get(point);
+
+			TreeItem<TriggerWrapper> triggerItem = new TreeItem<>(new TriggerWrapper(trigger));
+			rootItem.getChildren().add(triggerItem);
+		}
+
+		treeView.setRoot(rootItem);
+	}
+
+	public void changed(ObservableValue<? extends TreeItem<TriggerWrapper>> observable, TreeItem<TriggerWrapper> oldValue,
+			TreeItem<TriggerWrapper> newValue) {
+		contentView.getChildren().clear();
+
+		if (newValue != null) {
+			TriggerWrapper triggerWrapper = newValue.getValue();
+			TriggerPointViewController controller = new TriggerPointViewController(triggerWrapper);
+			contentView.getChildren().setAll(controller.getParent());
+			VBox.setVgrow(controller.getParent(), Priority.ALWAYS);
+		}
+	}
+
+	@Override
+	public String getName() {
+		return Localization.getString(Strings.UI_Window_PadSettings_Trigger_Title);
+	}
+
+	@Override
+	public void loadSettings(Pad pad) {
+		createTreeView();
+	}
+
+	@Override
+	public void saveSettings(Pad pad) {}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/CartTriggerViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/CartTriggerViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e5f457bb24a08f10381e3c0053fe3ffb2b73482
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/CartTriggerViewController.java
@@ -0,0 +1,46 @@
+package de.tobias.playpad.viewcontroller.option.pad.trigger;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.trigger.CartTriggerItem;
+import de.tobias.utils.ui.ContentViewController;
+import javafx.fxml.FXML;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.TextField;
+
+
+public class CartTriggerViewController extends ContentViewController {
+
+	@FXML private ComboBox<PadStatus> statusComboBox;
+	@FXML private CheckBox allCartsCheckbox;
+	@FXML private TextField cartTextField;
+
+	private CartTriggerItem item;
+
+	public CartTriggerViewController(CartTriggerItem item) {
+		super("cartTrigger", "de/tobias/playpad/assets/view/option/pad/trigger/", PlayPadMain.getUiResourceBundle());
+		this.item = item;
+
+		statusComboBox.setValue(item.getNewStatus());
+		allCartsCheckbox.setSelected(item.isAllCarts());
+		cartTextField.setText(item.getCartsString());
+	}
+
+	@Override
+	public void init() {
+		statusComboBox.getItems().addAll(PadStatus.PLAY, PadStatus.PAUSE, PadStatus.STOP);
+		statusComboBox.valueProperty().addListener((a, b, c) -> item.setNewStatus(c));
+
+		allCartsCheckbox.selectedProperty().addListener((a, b, c) ->
+		{
+			cartTextField.setDisable(c);
+			item.setAllCarts(c);
+		});
+		cartTextField.textProperty().addListener((a, b, c) ->
+		{
+			if (c != null && !c.isEmpty())
+				item.setCartsString(c);
+		});
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..78e89182813afc0a68d348c1e1f91dd30a0e7f1b
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java
@@ -0,0 +1,82 @@
+package de.tobias.playpad.viewcontroller.option.pad.trigger;
+
+import java.util.Set;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.tigger.TriggerItem;
+import de.tobias.playpad.tigger.TriggerItemConnect;
+import de.tobias.playpad.tigger.TriggerRegistry;
+import de.tobias.playpad.trigger.TriggerWrapper;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.control.Separator;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+
+public class TriggerPointViewController extends ContentViewController {
+
+	@FXML private VBox itemView;
+	@FXML private HBox buttonBox;
+
+	private TriggerWrapper triggerWrapper;
+
+	public TriggerPointViewController(TriggerWrapper triggerWrapper) {
+		super("triggerPoint", "de/tobias/playpad/assets/view/option/pad/trigger/", PlayPadMain.getUiResourceBundle());
+		this.triggerWrapper = triggerWrapper;
+
+		for (TriggerItem item : triggerWrapper.getTrigger().getItems())
+			showTriggerItem(item);
+	}
+
+	@Override
+	public void init() {
+		Set<String> types = TriggerRegistry.getTypes();
+		types.stream().sorted().forEach(item ->
+		{
+			Button button = new Button(TriggerRegistry.getTriggerConnect(item).toString(), new FontIcon(FontAwesomeType.PLUS_CIRCLE));
+			button.setContentDisplay(ContentDisplay.TOP);
+			button.setPrefWidth(150);
+
+			button.setOnAction(e ->
+			{
+				TriggerItemConnect connect = TriggerRegistry.getTriggerConnect(item);
+				TriggerItem triggerItem = connect.newInstance(triggerWrapper.getTrigger());
+
+				triggerWrapper.addItem(triggerItem);
+				showTriggerItem(triggerItem);
+			});
+			buttonBox.getChildren().add(button);
+		});
+	}
+
+	private void showTriggerItem(TriggerItem item) {
+		TriggerItemConnect connect = TriggerRegistry.getTriggerConnect(item.getType());
+
+		VBox itemBox = new VBox(14);
+		ContentViewController contentViewController = connect.getSettingsController(item);
+		if (contentViewController != null) {
+			itemBox.getChildren().add(contentViewController.getParent());
+
+			ContentViewController timeViewController = new TriggerTimeViewController(item);
+			itemBox.getChildren().add(timeViewController.getParent());
+
+			Button deleteButton = new Button("", new FontIcon(FontAwesomeType.TRASH));
+			HBox hbox = new HBox(itemBox, deleteButton);
+			hbox.setSpacing(14);
+
+			VBox rootBox = new VBox(14.0, hbox, new Separator());
+
+			itemView.getChildren().addAll(rootBox);
+
+			deleteButton.setOnAction((e) ->
+			{
+				triggerWrapper.removeItem(item);
+				itemView.getChildren().removeAll(rootBox);
+			});
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerTimeViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerTimeViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1215391fa42224f849baa66c26afede6489bf07
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerTimeViewController.java
@@ -0,0 +1,38 @@
+package de.tobias.playpad.viewcontroller.option.pad.trigger;
+
+import java.util.Optional;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.tigger.TriggerItem;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.TimeUtils;
+import javafx.fxml.FXML;
+import javafx.scene.control.TextField;
+import javafx.util.Duration;
+
+public class TriggerTimeViewController extends ContentViewController {
+
+	@FXML private TextField timeTextField;
+
+	private TriggerItem item;
+
+	public TriggerTimeViewController(TriggerItem item) {
+		super("triggerTime", "de/tobias/playpad/assets/view/option/pad/trigger/", PlayPadMain.getUiResourceBundle());
+		this.item = item;
+
+		timeTextField.setText(String.valueOf(item.getDurationFromPoint().toSeconds()));
+	}
+
+	@Override
+	public void init() {
+		timeTextField.textProperty().addListener((a, b, c) ->
+		{
+			Optional<Duration> duration = TimeUtils.parse(c);
+			if (duration.isPresent()) {
+				item.setDurationFromPoint(duration.get());
+			}
+			timeTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, !duration.isPresent());
+		});
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragHandler.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd6b1c83f66fd9ec94de0e1c644f862eceda730b
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragHandler.java
@@ -0,0 +1,204 @@
+package de.tobias.playpad.viewcontroller.pad;
+
+import java.io.File;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.audio.AudioRegistry;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.plugin.ExtensionHandler;
+import de.tobias.playpad.plugin.PlayPadPlugin;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.view.AudioPadView;
+import de.tobias.utils.ui.NotificationHandler;
+import de.tobias.utils.ui.Refreshable;
+import de.tobias.utils.util.Localization;
+import javafx.scene.SnapshotParameters;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.TransferMode;
+
+// TODO Renew class
+public class PadDragHandler<T extends Refreshable & NotificationHandler> {
+
+	private static final String REGEX = "[0-9]+";
+	private Pad pad;
+	final private AudioPadView view;
+	final private T t;
+
+	private static AudioPadView lastDraggedOver;
+	private static boolean dndMode;
+	private static Project project;
+
+	public PadDragHandler(Pad pad, AudioPadView view, T t) {
+		this.pad = pad;
+		this.view = view;
+		this.t = t;
+
+		// Drag and Drop
+		view.setOnDragOver(event -> dragOver(event));
+		view.setOnDragExited(event -> dragExited());
+		view.setOnDragDropped(event -> dragDropped(event));
+		view.setOnDragDetected(event -> dragDetacted(event));
+	}
+
+	private void dragOver(DragEvent event) {
+		if (event.getGestureSource() != this && event.getDragboard().hasFiles()) {
+			if (event.getDragboard().getFiles().get(0).isFile()) {
+				if (PadViewController.getPlayedPlayers() > 0) {
+					showLiveModeLabel();
+				}
+				File file = event.getDragboard().getFiles().get(0);
+
+				// Build In Filesupport
+				for (String extension : AudioRegistry.geAudioType().getSupportedTypes()) {
+					if (file.getName().toLowerCase().matches("." + extension)) {
+						event.acceptTransferModes(TransferMode.LINK);
+						return;
+					}
+				}
+
+				// Plugins
+				for (ExtensionHandler extensionHandler : PlayPadPlugin.getImplementation().getExtensionsHandler()) {
+					for (String extension : extensionHandler.getExtensions()) {
+						if (file.getName().toLowerCase().matches("." + extension)) {
+							event.acceptTransferModes(TransferMode.LINK);
+							return;
+						}
+					}
+				}
+			}
+		}
+
+		if (event.getDragboard().hasString() && event.getDragboard().getString().trim().matches(REGEX)) {
+			int padID = Integer.valueOf(event.getDragboard().getString());
+			if (padID != view.getController().getPad().getIndex()) {
+
+				// Live Mode
+				if (PadViewController.getPlayedPlayers() > 0) {
+					showLiveModeLabel();
+				} else {
+					event.acceptTransferModes(TransferMode.MOVE);
+					double y = event.getY();
+					if (y < view.getHeight() / 2) {
+						if (lastDraggedOver != null) {
+							view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, false);
+							view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, false);
+						}
+						view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, false);
+						view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, true);
+						lastDraggedOver = view;
+					} else {
+						if (lastDraggedOver != null) {
+							view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, false);
+							view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, false);
+						}
+						view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, false);
+						view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, true);
+						lastDraggedOver = view;
+					}
+				}
+			}
+		}
+		event.consume();
+	}
+
+	private void dragExited() {
+		if (lastDraggedOver != null) {
+			view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, false);
+			view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, false);
+			lastDraggedOver = null;
+		}
+	}
+
+	private void dragDropped(DragEvent event) {
+		// Live Mode
+		if (PadViewController.getPlayedPlayers() > 0) {
+			showLiveModeLabel();
+		} else {
+			Dragboard db = event.getDragboard();
+			boolean success = false;
+			if (db.hasFiles()) {
+				success = true;
+				File file = db.getFiles().get(0);
+
+				boolean custom = false;
+				for (ExtensionHandler extensionHandler : PlayPadPlugin.getImplementation().getExtensionsHandler()) {
+					for (String extension : extensionHandler.getExtensions()) {
+						if (file.getName().toLowerCase().matches("." + extension)) {
+							extensionHandler.handle(file.toPath(), pad);
+							custom = true;
+							break;
+						}
+					}
+				}
+				if (!custom) {
+					this.pad.setPath(file.toPath());
+				}
+			}
+
+			if (db.hasString() && db.getString().matches(REGEX)) {
+				double y = event.getY();
+				if (y < view.getHeight() / 2) {
+					int padID = Integer.valueOf(db.getString());
+					project.movePads(padID, pad.getIndex());
+					t.refreshUI();
+					success = true;
+				} else {
+					int padID = Integer.valueOf(db.getString());
+					project.replacePads(padID, pad.getIndex());
+					t.refreshUI();
+					success = true;
+				}
+			}
+
+			event.setDropCompleted(success);
+			event.consume();
+		}
+	}
+
+	private void dragDetacted(MouseEvent event) {
+		// Live Mode
+		if (PadViewController.getPlayedPlayers() == 0) {
+			if (dndMode) {
+				Dragboard storeImage = view.startDragAndDrop(TransferMode.MOVE);
+				storeImage.setDragView(view.snapshot(new SnapshotParameters(), null));
+
+				ClipboardContent content = new ClipboardContent();
+				content.putString(String.valueOf(pad.getIndex()));
+				storeImage.setContent(content);
+
+				event.consume();
+			}
+		}
+	}
+
+	public static void setDndMode(boolean dndMode) {
+		PadDragHandler.dndMode = dndMode;
+	}
+
+	public static void setLastDraggedOver(AudioPadView lastDraggedOver) {
+		PadDragHandler.lastDraggedOver = lastDraggedOver;
+	}
+
+	public void setPad(Pad pad) {
+		this.pad = pad;
+	}
+
+	public static void setProject(Project project) {
+		PadDragHandler.project = project;
+	}
+
+	private boolean displayLiveLabel;
+
+	private synchronized void showLiveModeLabel() {
+		if (!displayLiveLabel) {
+			displayLiveLabel = true;
+			t.notify(Localization.getString(Strings.Error_Pad_Livemode), PlayPadMain.notificationDisplayTimeMillis,
+					() -> displayLiveLabel = false);
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..0de732ca29d63fb83fade6f6d295b7b8ed94a429
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java
@@ -0,0 +1,179 @@
+package de.tobias.playpad.viewcontroller.pad;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Set;
+
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
+import de.tobias.playpad.pad.conntent.UnkownPadContentException;
+import de.tobias.playpad.pad.drag.PadDragMode;
+import de.tobias.playpad.pad.drag.PadDragModeRegistery;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.view.FileDragOptionView;
+import de.tobias.playpad.view.PadDragOptionView;
+import de.tobias.playpad.view.PadView;
+import de.tobias.utils.util.FileUtils;
+import javafx.scene.SnapshotParameters;
+import javafx.scene.image.WritableImage;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.TransferMode;
+import javafx.scene.paint.Color;
+
+public class PadDragListener {
+
+	private static final String REGEX = "[0-9]+";
+	private Pad pad;
+	final private PadView view;
+
+	private static boolean dndMode;
+	private static Project project;
+
+	private PadDragOptionView padHud;
+	private FileDragOptionView fileHud;
+
+	public PadDragListener(Pad pad, PadView view) {
+		this.pad = pad;
+		this.view = view;
+
+		// Drag and Drop
+		view.setOnDragOver(event -> dragOver(event));
+		view.setOnDragExited(event -> dragExited());
+		view.setOnDragDropped(event -> dragDropped(event));
+		view.setOnDragDetected(event -> dragDetacted(event));
+	}
+
+	private void dragOver(DragEvent event) {
+		if (event.getGestureSource() != this && event.getDragboard().hasFiles()) {
+			if (event.getDragboard().getFiles().get(0).isFile()) {
+				File file = event.getDragboard().getFiles().get(0);
+
+				// Build In Filesupport
+				try {
+					Set<PadContentConnect> connects = PadContentRegistry.getPadContentConnectsForFile(file.toPath());
+
+					if (!connects.isEmpty()) {
+						if (fileHud == null) {
+							fileHud = new FileDragOptionView(view);
+						}
+						fileHud.showDropOptions(connects);
+
+						event.acceptTransferModes(TransferMode.LINK);
+						return;
+					}
+				} catch (UnkownPadContentException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+		if (event.getDragboard().hasString() && event.getDragboard().getString().trim().matches(REGEX)) {
+			int padID = Integer.valueOf(event.getDragboard().getString());
+			if (padID != view.getController().getPad().getIndex()) {
+
+				Collection<PadDragMode> connects = PadDragModeRegistery.getValues();
+
+				if (!connects.isEmpty()) {
+					if (padHud == null) {
+						padHud = new PadDragOptionView(view);
+					}
+					padHud.showDropOptions(connects);
+
+					event.acceptTransferModes(TransferMode.MOVE);
+				}
+			}
+		}
+		event.consume();
+	}
+
+	private void dragExited() {
+		if (padHud != null) {
+			padHud.hide();
+		}
+		if (fileHud != null) {
+			fileHud.hide();
+		}
+	}
+
+	private void dragDropped(DragEvent event) {
+		Dragboard db = event.getDragboard();
+		boolean success = false;
+		if (db.hasFiles()) {
+			success = true;
+			File file = db.getFiles().get(0);
+
+			PadContentConnect connect = fileHud.getSelectedConnect();
+			if (connect != null) {
+				PadContent content = pad.getContent();
+				if (pad.getContent() == null || !pad.getContent().getType().equals(connect.getType())) {
+					content = connect.newInstance(pad);
+				}
+
+				content.handlePath(file.toPath());
+				this.pad.setContent(content);
+				this.pad.setName(FileUtils.getFilenameWithoutExtention(file.toPath().getFileName()));
+
+				view.setPreviewContent(pad);
+				view.addDefaultButton(pad);
+			}
+		}
+
+		if (db.hasString() && db.getString().matches(REGEX)) {
+			int padID = Integer.valueOf(db.getString());
+
+			PadDragMode mode = padHud.getSelectedPadDragMode();
+			mode.handle(padID, pad.getIndex(), project);
+			padHud.hide();
+
+			PlayPadPlugin.getImplementation().getMainViewController()
+					.showPage(PlayPadPlugin.getImplementation().getMainViewController().getPage());
+
+			event.setDropCompleted(success);
+			event.consume();
+		}
+	}
+
+	private void dragDetacted(MouseEvent event) {
+		if (dndMode) {
+			Dragboard dragboard = view.startDragAndDrop(TransferMode.MOVE);
+
+			SnapshotParameters parameters = new SnapshotParameters();
+			parameters.setFill(Color.TRANSPARENT);
+			WritableImage snapshot = view.snapshot(parameters, null);
+			for (int x = 0; x < snapshot.getWidth(); x++) {
+				for (int y = 0; y < snapshot.getHeight(); y++) {
+					Color oldColor = snapshot.getPixelReader().getColor(x, y).darker().darker();
+					snapshot.getPixelWriter().setColor(x, y,
+							new Color(oldColor.getRed(), oldColor.getGreen(), oldColor.getBlue(), oldColor.getOpacity() * 0.5));
+				}
+			}
+
+			dragboard.setDragView(snapshot);
+
+			ClipboardContent content = new ClipboardContent();
+			content.putString(String.valueOf(pad.getIndex()));
+			dragboard.setContent(content);
+
+			event.consume();
+		}
+	}
+
+	public static void setDndMode(boolean dndMode) {
+		PadDragListener.dndMode = dndMode;
+	}
+
+	public void setPad(Pad pad) {
+		this.pad = pad;
+	}
+
+	public static void setProject(Project project) {
+		PadDragListener.project = project;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..c55b73efa8069e3c0d59c7731bcd74d8e5dbdf02
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java
@@ -0,0 +1,345 @@
+package de.tobias.playpad.viewcontroller.pad;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Set;
+
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.TimeMode;
+import de.tobias.playpad.pad.conntent.Durationable;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
+import de.tobias.playpad.pad.conntent.UnkownPadContentException;
+import de.tobias.playpad.pad.listener.PadContentListener;
+import de.tobias.playpad.pad.listener.PadDurationListener;
+import de.tobias.playpad.pad.listener.PadPositionListener;
+import de.tobias.playpad.pad.listener.PadStatusListener;
+import de.tobias.playpad.pad.view.IPadViewController;
+import de.tobias.playpad.view.FileDragOptionView;
+import de.tobias.playpad.view.PadView;
+import de.tobias.playpad.viewcontroller.IPadView;
+import de.tobias.playpad.viewcontroller.option.pad.PadSettingsViewController;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.util.FileUtils;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Stage;
+import javafx.util.Duration;
+
+public class PadViewController implements EventHandler<ActionEvent>, IPadViewController {
+
+	private static final String DURATION_FORMAT = "%d:%02d";
+	private static final String OPEN_FOLDER = "openFolder";
+
+	private PadView view;
+	private Pad pad;
+
+	private PadStatusListener padStatusListener;
+	private PadContentListener padContentListener;
+	private PadDurationListener padDurationListener;
+	private PadPositionListener padPositionListener;
+
+	private PadDragListener padDragListener;
+
+	public PadViewController() {
+		view = new PadView(this);
+
+		padStatusListener = new PadStatusListener(this);
+		padContentListener = new PadContentListener(this);
+		padDurationListener = new PadDurationListener(this);
+		padPositionListener = new PadPositionListener(this);
+	}
+
+	@Override
+	public IPadView getParent() {
+		return view;
+	}
+
+	@Override
+	public void handle(ActionEvent event) {
+		if (event.getSource() == view.getPlayButton()) {
+			onPlay();
+		} else if (event.getSource() == view.getPauseButton()) {
+			onPause();
+		} else if (event.getSource() == view.getStopButton()) {
+			onStop();
+		} else if (event.getSource() == view.getNewButton()) {
+			onNew(event);
+		} else if (event.getSource() == view.getSettingsButton()) {
+			onSettings();
+		}
+	}
+
+	private void onPlay() {
+		if (pad.getContent() != null) {
+			pad.setStatus(PadStatus.PLAY);
+		}
+	}
+
+	private void onPause() {
+		if (pad.getContent() != null) {
+			pad.setStatus(PadStatus.PAUSE);
+		}
+	}
+
+	private void onStop() {
+		if (pad.getContent() != null) {
+			pad.setStatus(PadStatus.STOP);
+		}
+	}
+
+	private void onNew(ActionEvent event) {
+		FileChooser chooser = new FileChooser();
+
+		// File Extension
+		ExtensionFilter extensionFilter = new ExtensionFilter(Localization.getString(Strings.File_Filter_Media),
+				PadContentRegistry.getSupportedFileTypes());
+		chooser.getExtensionFilters().add(extensionFilter);
+
+		// Last Folder
+		Object openFolder = ApplicationUtils.getApplication().getUserDefaults().getData(OPEN_FOLDER);
+		if (openFolder != null) {
+			File folder = new File(openFolder.toString());
+			chooser.setInitialDirectory(folder);
+		}
+
+		File file = chooser.showOpenDialog(((Node) event.getTarget()).getScene().getWindow());
+		if (file != null) {
+			Path path = file.toPath();
+
+			try {
+				Set<PadContentConnect> connects = PadContentRegistry.getPadContentConnectsForFile(file.toPath());
+				if (!connects.isEmpty()) {
+					if (connects.size() > 1) {
+						FileDragOptionView hud = new FileDragOptionView(view);
+						hud.showDropOptions(connects, connect ->
+						{
+							if (connect != null) {
+								setNewPadContent(file, path, connect);
+								hud.hide();
+							}
+						});
+					} else {
+						PadContentConnect connect = connects.iterator().next();
+						setNewPadContent(file, path, connect);
+					}
+				}
+			} catch (UnkownPadContentException e) {
+				e.printStackTrace();
+			}
+
+			ApplicationUtils.getApplication().getUserDefaults().setData(OPEN_FOLDER, path.getParent().toString());
+		}
+	}
+
+	private void setNewPadContent(File file, Path path, PadContentConnect connect) {
+		PadContent content = pad.getContent();
+		if (pad.getContent() == null || !pad.getContent().getType().equals(connect.getType())) {
+			content = connect.newInstance(pad);
+			this.pad.setContent(content);
+		}
+
+		content.handlePath(file.toPath());
+		this.pad.setName(FileUtils.getFilenameWithoutExtention(path.getFileName()));
+	}
+
+	private void onSettings() {
+		Stage owner = PlayPadPlugin.getImplementation().getMainViewController().getStage();
+		PadSettingsViewController controller = new PadSettingsViewController(pad, owner);
+		controller.getStage().setOnHidden(ev ->
+		{
+			view.setTriggerLabelActive(pad.hasTriggerItems());
+		});
+		controller.getStage().show();
+	}
+
+	@Override
+	public void unconnectPad() {
+		view.getIndexLabel().setText("");
+		view.clearPreviewContent();
+		view.getTimeLabel().setText("");
+
+		view.setTriggerLabelActive(false);
+
+		view.getLoopLabel().visibleProperty().unbind();
+
+		if (pad != null) {
+			pad.contentProperty().removeListener(padContentListener);
+			pad.statusProperty().removeListener(padStatusListener);
+
+			if (pad.getContent() instanceof Durationable) {
+				Durationable durationable = (Durationable) pad.getContent();
+				durationable.durationProperty().removeListener(padDurationListener);
+				durationable.positionProperty().removeListener(padPositionListener);
+			}
+			pad.setController(null);
+			padDragListener = null;
+
+			// GUI Cleaning
+			getPadPositionListener().stopWaning();
+			view.removeStyleClasses(pad);
+		}
+		this.pad = null;
+	}
+
+	@Override
+	public Pad getPad() {
+		return pad;
+	}
+
+	@Override
+	public void setPad(Pad pad) {
+		unconnectPad();
+		this.pad = pad;
+
+		view.setPreviewContent(pad);
+		view.addStyleClasses(pad);
+
+		connectPad();
+	}
+
+	@Override
+	public void connectPad() {
+		pad.setController(this);
+
+		try {
+			view.getIndexLabel().setText(String.valueOf(pad.getIndexReadable()));
+			view.getLoopLabel().visibleProperty().bind(pad.loopProperty());
+
+			view.setTriggerLabelActive(pad.hasTriggerItems());
+
+			// Update Listener
+			padContentListener.setPad(pad);
+			padPositionListener.setPad(pad);
+
+			// Pad Content Chnage
+			pad.contentProperty().addListener(padContentListener);
+			// Pad Status Change
+			pad.statusProperty().addListener(padStatusListener);
+
+			// First Listener call with new data
+			padContentListener.changed(null, null, pad.getContent()); // Add Duration listener
+			padStatusListener.changed(null, null, pad.getStatus());
+
+			padDragListener = new PadDragListener(pad, view);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	public void updateTimeLabel() {
+		if (pad.getContent() != null && pad.getStatus() != PadStatus.EMPTY && pad.getStatus() != PadStatus.ERROR) {
+			if (pad.getContent() instanceof Durationable) {
+				Durationable durationable = (Durationable) pad.getContent();
+
+				Duration duration = durationable.getDuration();
+				Duration position = durationable.getPosition();
+
+				if (duration != null) {
+					// Nur Gesamtzeit anzeigen
+					if (pad.getStatus() == PadStatus.READY || position == null) {
+						String time = durationToString(duration);
+						view.getTimeLabel().setText(time);
+						view.getPlayBar().setProgress(0);
+					} else {
+						// Play/Gesamtzeit anzeigen
+						TimeMode timeMode = pad.getTimeMode();
+
+						if (timeMode == TimeMode.REST) {
+							Duration leftTime = duration.subtract(position);
+							view.getTimeLabel().setText("- " + durationToString(leftTime));
+						} else if (timeMode == TimeMode.PLAYED) {
+							view.getTimeLabel().setText(durationToString(position));
+						} else if (timeMode == TimeMode.BOTH) {
+							String time = durationToString(position);
+							String totalTime = durationToString(duration);
+							view.getTimeLabel().setText(time + "/" + totalTime);
+						}
+					}
+				}
+				return;
+			}
+		}
+		view.getPlayBar().setProgress(0);
+		view.getTimeLabel().setText("");
+	}
+
+	public String durationToString(Duration value) {
+		if (value != null) {
+			int secounds = (int) ((value.toMillis() / 1000) % 60);
+			int minutes = (int) ((value.toMillis() / (1000 * 60)) % 60);
+			String time = String.format(DURATION_FORMAT, minutes, secounds);
+			return time;
+		} else {
+			return null;
+		}
+	}
+
+	public void updateButtonDisable() {
+		if (pad.getContent() != null) {
+			if (pad.getStatus() == PadStatus.PLAY) {
+				view.getPlayButton().setDisable(true);
+				view.getPauseButton().setDisable(false);
+				view.getStopButton().setDisable(false);
+				view.getNewButton().setDisable(true);
+				view.getSettingsButton().setDisable(false);
+			} else if (pad.getStatus() == PadStatus.PAUSE) {
+				view.getPlayButton().setDisable(false);
+				view.getPauseButton().setDisable(true);
+				view.getStopButton().setDisable(false);
+				view.getNewButton().setDisable(true);
+				view.getSettingsButton().setDisable(false);
+			} else if (pad.getStatus() == PadStatus.STOP) {
+				view.getPlayButton().setDisable(false);
+				view.getPauseButton().setDisable(true);
+				view.getStopButton().setDisable(true);
+				view.getNewButton().setDisable(true);
+				view.getSettingsButton().setDisable(false);
+			} else if (pad.getStatus() == PadStatus.READY) {
+				view.getPlayButton().setDisable(false);
+				view.getPauseButton().setDisable(true);
+				view.getStopButton().setDisable(true);
+				view.getNewButton().setDisable(false);
+				view.getSettingsButton().setDisable(false);
+			}
+		} else if (pad.getStatus() == PadStatus.EMPTY || pad.getStatus() == PadStatus.ERROR || pad.getContent() == null
+				|| !pad.getContent().isPadLoaded()) {
+			view.getPlayButton().setDisable(true);
+			view.getPauseButton().setDisable(true);
+			view.getStopButton().setDisable(true);
+			view.getNewButton().setDisable(false);
+			view.getSettingsButton().setDisable(false);
+		}
+	}
+
+	@Override
+	public void showDnDLayout(boolean b) {
+		view.pseudoClassState(PseudoClasses.DRAG_CLASS, b);
+	}
+
+	// getter for listener
+	public PadDurationListener getPadDurationListener() {
+		return padDurationListener;
+	}
+
+	public PadStatusListener getPadStatusListener() {
+		return padStatusListener;
+	}
+
+	public PadPositionListener getPadPositionListener() {
+		return padPositionListener;
+	}
+
+	public PadDragListener getPadDragListener() {
+		return padDragListener;
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewControllerOld.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewControllerOld.java
new file mode 100644
index 0000000000000000000000000000000000000000..4fce7090ec092d55de01ac19a7e3021ba4657033
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewControllerOld.java
@@ -0,0 +1,755 @@
+package de.tobias.playpad.viewcontroller.pad;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.controlsfx.dialog.ExceptionDialog;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.action.mapper.listener.MidiHandler;
+import de.tobias.playpad.audio.AudioHandler;
+import de.tobias.playpad.audio.AudioRegistry;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.Pad.PadStatus;
+import de.tobias.playpad.pad.Pad.TimeMode;
+import de.tobias.playpad.model.PadException;
+import de.tobias.playpad.model.PadException.PadExceptionType;
+import de.tobias.playpad.model.Project;
+import de.tobias.playpad.plugin.ExtensionHandler;
+import de.tobias.playpad.plugin.PadListener;
+import de.tobias.playpad.plugin.PlayPadPlugin;
+import de.tobias.playpad.plugin.viewcontroller.IPadViewController;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.view.AudioPadView;
+import de.tobias.playpad.viewcontroller.PadSettingsViewController;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.ui.NotificationHandler;
+import de.tobias.utils.ui.Refreshable;
+import de.tobias.utils.util.Localization;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Stage;
+import javafx.util.Duration;
+
+public class PadViewController implements IPadViewController, EventHandler<ActionEvent>, ChangeListener<Duration> {
+
+	private static final String DURATION_FORMAT = "%d:%02d";
+
+	private static final String OPEN_FOLDER = "openFolder";
+
+	public static ObservableList<PadException> exceptions = FXCollections.observableArrayList();
+
+	private AudioPadView view;
+
+	protected Pad pad;
+	protected int page;
+
+	// Listener
+	private ChangeListener<Duration> totalDurationListener;
+	private ChangeListener<AudioHandler> audioHandlerListener;
+	private ChangeListener<PadStatus> stateListener;
+	private ChangeListener<Boolean> audioLoadedListener;
+	private ChangeListener<String> titleListener;
+	private ChangeListener<PadException> exceptionListener;
+	private PlayDurationEventHandler durationEventHandler;
+
+	// Drag and Drop
+	private PadDragHandler<?> dragAndDrop;
+
+	// Refresh in Window
+	private Refreshable refreshable;
+	private NotificationHandler notificationHandler;
+
+	private MidiHandler handler;
+	protected int midiKeyPressedForPlay;
+
+	// Window Referenz
+	private PadSettingsViewController padSettingsViewController;
+
+	private static int playedPlayers;
+
+	private synchronized static void addPlayer() {
+		playedPlayers++;
+	}
+
+	private synchronized static void removePlayer() {
+		if (playedPlayers > 0) {
+			playedPlayers--;
+		}
+	}
+
+	public synchronized static int getPlayedPlayers() {
+		return playedPlayers;
+	}
+
+	public <T extends Refreshable & NotificationHandler> PadViewController(T t, Project project, MidiHandler handler) {
+		view = new AudioPadView(this);
+		dragAndDrop = new PadDragHandler<T>(pad, view, t);
+
+		this.refreshable = t;
+		this.notificationHandler = t;
+		this.handler = handler;
+
+		view.getErrorLabel().setOnMouseClicked(event ->
+		{
+			showError();
+		});
+	}
+
+	public Pad getPad() {
+		return pad;
+	}
+
+	public void setPad(Pad pad, int page) {
+		if (this.pad != null) {
+			this.pad.setController(null);
+			cleanUp();
+		}
+
+		this.pad = pad;
+		this.page = page;
+		this.pad.setController(this);
+		this.dragAndDrop.setPad(pad);
+
+		view.addDefaultButton();
+		preparePad();
+
+		for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) {
+			try {
+				listener.onPadVisible(pad);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private void preparePad() {
+		// Display Pad Once
+		view.getIndexLabel().setText(String.valueOf(pad.getIndex() + 1));
+
+		view.getTimeLabel().setText("");
+		// Binding und Listener
+		totalDurationListener = (a, b, c) ->
+		{
+			if (c != null) {
+				showPadDuration();
+			} else {
+				Platform.runLater(() -> view.getTimeLabel().setText(""));
+			}
+		};
+
+		stateListener = (a, b, c) -> stateChange(b, c);
+
+		audioLoadedListener = (a, b, c) ->
+		{
+			// TODO Init MIDI Page
+		};
+
+		audioHandlerListener = (a, b, c) ->
+		{
+			b.durationProperty(pad).removeListener(totalDurationListener);
+			c.durationProperty(pad).addListener(totalDurationListener);
+
+			b.loadedProperty().removeListener(audioLoadedListener);
+			c.loadedProperty().addListener(audioLoadedListener);
+		};
+
+		titleListener = (a, b, c) ->
+		{
+			view.getNameLabel().setText(c);
+		};
+
+		exceptionListener = (a, b, c) ->
+		{
+			if (c != null && !exceptions.contains(c)) {
+				view.setErrorLabelActive(true);
+				exceptions.add(c);
+			} else {
+				view.setErrorLabelActive(false);
+				exceptions.remove(b);
+			}
+		};
+
+		// AudioHandler Listener
+		pad.audioHandlerProperty().addListener(audioHandlerListener);
+
+		pad.titleProperty().addListener(titleListener);
+		view.getNameLabel().setText(pad.getTitle());
+
+		// Listener für Gesamtzeit (Wenn neues Media File oder so)
+		pad.getAudioHandler().durationProperty(pad).addListener(totalDurationListener);
+
+		// Time label Clickable für Time Display Art
+		view.getTimeLabel().setOnMouseClicked(event ->
+		{
+			TimeMode timeMode = Profile.currentProfile().getProfileSettings().getPlayerTimeDisplayMode();
+			if (pad.isCustomTimeMode()) {
+				timeMode = pad.getTimeMode().get();
+			}
+
+			if (timeMode == TimeMode.PLAYED) {
+				pad.setTimeMode(TimeMode.REST);
+			} else if (timeMode == TimeMode.REST) {
+				pad.setTimeMode(TimeMode.BOTH);
+			} else if (timeMode == TimeMode.BOTH) {
+				pad.setTimeMode(TimeMode.PLAYED);
+			}
+		});
+
+		view.setLoopLabelActive(pad.isLoop());
+
+		// Für LaunchPad Feedback
+		pad.getAudioHandler().loadedProperty().addListener(audioLoadedListener);
+
+		// State des Pad -> UI Änderungen (wie Progressbar oder Button)
+		pad.statusProperty().addListener(stateListener);
+
+		// Init
+		stateChange(null, pad.getStatus());
+		if (pad.getAudioHandler().durationProperty(pad).isNotNull().get()) {
+			showPadDuration();
+		}
+
+		// Errors
+		pad.lastExceptionProperty().addListener(exceptionListener);
+		view.setErrorLabelActive(pad.getLastException() != null);
+		if (pad.getLastException() != null && !exceptions.contains(pad.getLastException())) {
+			exceptions.add(pad.getLastException());
+		}
+
+		// CSS
+		view.getStyleClass().addAll("pad", "pad" + pad.getIndex());
+
+		view.getIndexLabel().getStyleClass().addAll("pad-index", "pad" + pad.getIndex() + "-index", "pad-info",
+				"pad" + pad.getIndex() + "-info");
+		view.getTimeLabel().getStyleClass().addAll("pad-time", "pad" + pad.getIndex() + "-time", "pad-info", "pad" + pad.getIndex() + "-info");
+		view.getNameLabel().getStyleClass().addAll("pad-title", "pad" + pad.getIndex() + "-title");
+
+		view.getPlayBar().getStyleClass().addAll("pad-playbar", "pad" + pad.getIndex() + "-playbar");
+
+		view.getPlayButton().getStyleClass().addAll("pad-button", "pad-playbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-playbutton");
+		view.getPauseButton().getStyleClass().addAll("pad-button", "pad-pausebutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-pausebutton");
+		view.getStopButton().getStyleClass().addAll("pad-button", "pad-stopbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-stopbutton");
+		view.getNewButton().getStyleClass().addAll("pad-button", "pad-newbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-newbutton");
+		view.getSettingsButton().getStyleClass().addAll("pad-button", "pad-settingsbutton", "pad" + pad.getIndex() + "-button",
+				"pad" + pad.getIndex() + "-settingsbutton");
+
+		view.getPlayButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-playbutton-icon",
+				"pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon");
+		view.getPauseButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-pausebutton-icon",
+				"pad" + pad.getIndex() + "-button-icon", "padv-playbutton--icon");
+		view.getStopButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-stopbutton-icon",
+				"pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon");
+		view.getNewButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-newbutton-icon", "pad" + pad.getIndex() + "-button-icon",
+				"pad" + pad.getIndex() + "-playbutton-icon");
+		view.getSettingsButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-deletebutton-icon",
+				"pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon");
+
+		view.getButtonBox().getStyleClass().add("pad-button-box");
+		view.getRoot().getStyleClass().add("pad-root");
+	}
+
+	/*
+	 * Button Action
+	 */
+	@Override
+	public void handle(ActionEvent event) {
+		if (event.getSource() == view.getPlayButton()) {
+			pad.setStatus(PadStatus.PLAY);
+		} else if (event.getSource() == view.getPauseButton()) {
+			pad.setStatus(PadStatus.PAUSE);
+		} else if (event.getSource() == view.getStopButton()) {
+			pad.setStatus(PadStatus.STOP);
+		} else if (event.getSource() == view.getSettingsButton()) {
+			openSettings();
+		} else if (event.getSource() == view.getNewButton()) {
+			if (getPlayedPlayers() > 0) {
+				notificationHandler.notify(Localization.getString(Strings.Error_Pad_Livemode), PlayPadMain.notificationDisplayTimeMillis);
+			} else {
+				chooseFile(event);
+			}
+		}
+	}
+
+	private void chooseFile(ActionEvent event) {
+		FileChooser chooser = new FileChooser();
+
+		// File Extension
+		ExtensionFilter extensionFilter = new ExtensionFilter(Localization.getString(Strings.File_Filter_Media),
+				AudioRegistry.geAudioType().getSupportedTypes());
+		chooser.getExtensionFilters().add(extensionFilter);
+		for (ExtensionHandler handler : PlayPadPlugin.getImplementation().getExtensionsHandler()) {
+			chooser.getExtensionFilters().add(new ExtensionFilter(handler.getName(), handler.getExtensions()));
+		}
+
+		// Last Folder
+		Object openFolder = ApplicationUtils.getApplication().getUserDefaults().getData(OPEN_FOLDER);
+		if (openFolder != null) {
+			File folder = new File(openFolder.toString());
+			chooser.setInitialDirectory(folder);
+		}
+
+		File file = chooser.showOpenDialog(((Node) event.getTarget()).getScene().getWindow());
+		if (file != null) {
+			Path path = file.toPath();
+			ExtensionFilter filter = chooser.getSelectedExtensionFilter();
+
+			for (ExtensionHandler handler : PlayPadPlugin.getImplementation().getExtensionsHandler()) {
+				if (filter.getDescription().equals(handler.getName())) {
+					handler.handle(path, pad);
+					return;
+				}
+			}
+
+			pad.setPath(path);
+			ApplicationUtils.getApplication().getUserDefaults().setData(OPEN_FOLDER, path.getParent().toString());
+		}
+	}
+
+	private void openSettings() {
+		if (padSettingsViewController == null) {
+			padSettingsViewController = new PadSettingsViewController(pad, this, view.getScene().getWindow());
+			padSettingsViewController.getStage().showAndWait();
+			refreshable.updateData();
+
+			padSettingsViewController = null;
+		} else if (padSettingsViewController.getStage().isShowing()) {
+			padSettingsViewController.getStage().toFront();
+		}
+	}
+
+	@Override
+	public void changed(ObservableValue<? extends Duration> arg0, Duration arg1, Duration newValue) {
+		// Progressbar (Prozente)
+		if (pad != null) {
+			double value = newValue.toMillis() / pad.getAudioHandler().getDuration(pad).toMillis();
+			view.getPlayBar().setProgress(value);
+
+			// Label (Restlaufzeit)
+			TimeMode timeMode = Profile.currentProfile().getProfileSettings().getPlayerTimeDisplayMode();
+			if (pad.isCustomTimeMode()) {
+				timeMode = pad.getTimeMode().get();
+			}
+			if (timeMode == TimeMode.REST) {
+				Duration leftTime = pad.getAudioHandler().getDuration(pad).subtract(newValue);
+				view.getTimeLabel().setText("- " + durationToString(leftTime));
+			} else if (timeMode == TimeMode.PLAYED) {
+				view.getTimeLabel().setText(durationToString(newValue));
+			} else if (timeMode == TimeMode.BOTH) {
+				String time = durationToString(newValue);
+				String totalTime = durationToString(pad.getAudioHandler().getDuration(pad));
+
+				view.getTimeLabel().setText(time + "/" + totalTime);
+			}
+		}
+	}
+
+	private String durationToString(Duration value) {
+		int secounds = (int) ((value.toMillis() / 1000) % 60);
+		int minutes = (int) ((value.toMillis() / (1000 * 60)) % 60);
+		String time = String.format(DURATION_FORMAT, minutes, secounds);
+		return time;
+	}
+
+	private void showPadDuration() {
+		Duration c = pad.getAudioHandler().getDuration(pad);
+		if (c != null) {
+			Platform.runLater(() -> view.getTimeLabel().setText(durationToString(c)));
+		} else {
+			Platform.runLater(() -> view.getTimeLabel().setText(""));
+		}
+	}
+
+	// GUI Veränderung und Pad Aktionen wenn sich der Sate durch die Buttons oder durch MIDI ändert
+	public void stateChange(PadStatus oldState, PadStatus newState) {
+		Profile profile = Profile.currentProfile();
+		if (pad.isCustomLayout()) {
+			pad.getLayout(profile.getProfileSettings().getLayoutType()).ifPresent(layout -> layout.updatePadView(this, oldState, newState));
+		} else {
+			profile.currentLayout().updatePadView(this, oldState, newState);
+		}
+
+		switch (newState) {
+		case PLAY:
+			playState(oldState, newState);
+			break;
+		case PAUSE:
+			pauseState(oldState, newState);
+			break;
+		case STOP:
+			stopState(oldState, newState);
+			break;
+		case READY:
+			readyState();
+			break;
+		case EMPTY:
+			emptyState();
+			break;
+		}
+	}
+
+	private void playState(PadStatus oldState, PadStatus newState) {
+		// PadListener
+		boolean ignoreNoMedia = false;
+		for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) {
+			try {
+				if (listener.ignoreNoMedia(pad)) {
+					ignoreNoMedia = true;
+					break;
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+
+		if (!ignoreNoMedia) {
+			if (!pad.getAudioHandler().isMediaLoaded(pad)) {
+				pad.loadMedia(); // Try to Load wenn nicht geladen
+				if (!pad.getAudioHandler().isMediaLoaded(pad)) {
+					String file = pad.getFile();
+					if (file != null)
+						file = file.replace("%20", " ");
+					notificationHandler
+							.showError(Localization.getString(Strings.Error_Pad_BaseName + PadExceptionType.FILE_NOT_FOUND.toString(), file));
+					pad.setState(PadStatus.READY);
+					return;
+				}
+			}
+		}
+
+		// PadListener
+		for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener())
+			try {
+				if (!listener.onPlay(pad))
+					return;
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+
+		// Bei Pause werden die Listener nicht entfernt, bei Stop schon. bei Stop wird der Listener = null. Nur dann muss er neu
+		// hinzugefügt werden
+		if (durationEventHandler == null && pad.currentDurationProperty() != null) {
+			durationEventHandler = new PlayDurationEventHandler(this);
+			pad.currentDurationProperty().addListener(durationEventHandler);
+			pad.currentDurationProperty().addListener(this);
+		}
+		if (durationEventHandler != null)
+			durationEventHandler.send = false;
+
+		// midi Feedback
+		// TODO MIDI Send Feedback
+		// try {
+		// } catch (MidiUnavailableException | InvalidMidiDataException e) {
+		// notificationHandler.showError(Localization.getString(Strings.Error_Midi_Send, e.getLocalizedMessage()));
+		// e.printStackTrace();
+		// }
+
+		if (pad.getAudioHandler().isMediaLoaded(pad))
+			pad.play();
+		addPlayer();
+
+		Platform.runLater(() ->
+		{
+			view.getPlayButton().setDisable(true);
+			view.getPauseButton().setDisable(false);
+			view.getStopButton().setDisable(false);
+			view.pseudoClassState(PseudoClasses.PLAY_CALSS, true);
+		});
+	}
+
+	private void pauseState(PadStatus oldState, PadStatus newState) {
+		pad.pause(true, () ->
+		{
+			// Bei Fade Out Ende löschen
+			view.pseudoClassState(PseudoClasses.FADE_CLASS, false);
+			removePlayer();
+			durationEventHandler.stopWaning();
+		});
+
+		Platform.runLater(() ->
+		{
+			view.getPlayButton().setDisable(false);
+			view.getPauseButton().setDisable(true);
+			view.getStopButton().setDisable(false);
+
+			view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+
+			// Fade Out Style hintufügen
+			if (!pad.isEof() && (pad.isCustomFade() && pad.getFade().get().getFadeOut().toMillis() > 0
+					|| !pad.isCustomFade() && Profile.currentProfile().getProfileSettings().getFade().getFadeOut().toSeconds() > 0))
+				view.pseudoClassState(PseudoClasses.FADE_CLASS, true);
+		});
+		sendFeedback(oldState, newState);
+	}
+
+	private void stopState(PadStatus oldState, PadStatus newState) {
+		if (pad.currentDurationProperty() != null) {
+			pad.currentDurationProperty().removeListener(this);
+			if (durationEventHandler != null)
+				pad.currentDurationProperty().removeListener(durationEventHandler);
+		}
+
+		// PadListener
+		for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener())
+			try {
+				listener.onStop(pad);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+
+		// TODO Init MIDI Page
+
+		boolean fadeListener = true;
+		for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) {
+			if (!listener.allowFade(pad)) {
+				fadeListener = false;
+			}
+		}
+
+		final boolean fade = fadeListener;
+
+		// UI Clean in State READY
+		Platform.runLater(() ->
+		{
+			view.getPauseButton().setDisable(true);
+			view.getStopButton().setDisable(true);
+
+			if (durationEventHandler != null)
+				durationEventHandler.stopWaning();
+			durationEventHandler = null;
+
+			view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+
+			if (oldState != PadStatus.PAUSE && fade) {
+				if (!pad.isEof() && (pad.isCustomFade() && pad.getFade().get().getFadeOut().toMillis() > 0
+						|| !pad.isCustomFade() && Profile.currentProfile().getProfileSettings().getFade().getFadeOut().toSeconds() > 0)) {
+					view.pseudoClassState(PseudoClasses.FADE_CLASS, true);
+				}
+			}
+		});
+
+		pad.stop(oldState != PadStatus.PAUSE && fade, () ->
+		{
+			// Bei Ende von Fade Out wird CSS removed
+			view.pseudoClassState(PseudoClasses.FADE_CLASS, false);
+		});
+
+		sendFeedback(oldState, newState);
+	}
+
+	private void readyState() {
+		// Clean UI vom Play
+		Platform.runLater(() ->
+		{
+			view.getPlayBar().setProgress(0.0);
+			showPadDuration();
+
+			view.getPlayButton().setDisable(false);
+			view.getPauseButton().setDisable(true);
+			view.getStopButton().setDisable(true);
+
+			view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			view.pseudoClassState(PseudoClasses.FADE_CLASS, false);
+			view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+
+			// PadListener
+			for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener())
+				try {
+					listener.onReady(pad);
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+		});
+
+		removePlayer();
+	}
+
+	private void emptyState() {
+		view.getPlayButton().setDisable(true);
+		view.getPauseButton().setDisable(true);
+		view.getStopButton().setDisable(true);
+	}
+
+	public void sendFeedback(PadStatus oldState, PadStatus newState) {
+		// TODO MIDI Send Feedback
+	}
+
+	public void cleanUp() {
+		if (pad != null) {
+			// Wenn Play oder Pause dann erst Stop, bevor alles Aufgeräumt wird
+			if (pad.getStatus() == PadStatus.PLAY || pad.getStatus() == PadStatus.PAUSE)
+				pad.setStatus(PadStatus.STOP);
+
+			pad.stop(false, null);
+
+			// Listener für Gesamtzeit weg
+			// State des Pad -> UI Änderungen (wie Progressbar oder Button)
+			pad.getAudioHandler().durationProperty(pad).removeListener(totalDurationListener);
+			pad.stateProperty().removeListener(stateListener);
+			pad.getAudioHandler().loadedProperty().removeListener(audioLoadedListener);
+			pad.titleProperty().removeListener(titleListener);
+			pad.lastExceptionProperty().removeListener(exceptionListener);
+			pad.audioHandlerProperty().removeListener(audioHandlerListener);
+
+			// view.getNameLabel().textProperty().unbind(); // Clear Title Label
+			view.getTimeLabel().setText(""); // Clear Time Label
+			view.getPlayBar().setProgress(0); // Zeit Leiste
+			view.setErrorLabelActive(false); // Error Weg
+
+			view.getStyleClass().removeAll("pad", "pad" + pad.getIndex());
+
+			view.pseudoClassState(PseudoClasses.PLAY_CALSS, false);
+			view.pseudoClassState(PseudoClasses.FADE_CLASS, false);
+			view.pseudoClassState(PseudoClasses.WARN_CLASS, false);
+
+			view.getIndexLabel().getStyleClass().removeAll("pad-index", "pad" + pad.getIndex() + "-index", "pad-info",
+					"pad" + pad.getIndex() + "-info");
+			view.getTimeLabel().getStyleClass().removeAll("pad-time", "pad" + pad.getIndex() + "-time", "pad-info",
+					"pad" + pad.getIndex() + "-info");
+			view.getNameLabel().getStyleClass().removeAll("pad-title", "pad" + pad.getIndex() + "-title");
+			view.getPlayBar().getStyleClass().removeAll("pad-playbar", "pad" + pad.getIndex() + "-playbar");
+
+			view.getPlayButton().getStyleClass().removeAll("pad-button", "pad-playbutton", "pad" + pad.getIndex() + "-button",
+					"pad" + pad.getIndex() + "-playbutton");
+			view.getPauseButton().getStyleClass().removeAll("pad-button", "pad-pausebutton", "pad" + pad.getIndex() + "-button",
+					"pad" + pad.getIndex() + "-pausebutton");
+			view.getStopButton().getStyleClass().removeAll("pad-button", "pad-stopbutton", "pad" + pad.getIndex() + "-button",
+					"pad" + pad.getIndex() + "-stopbutton");
+			view.getNewButton().getStyleClass().removeAll("pad-button", "pad-newbutton", "pad" + pad.getIndex() + "-button",
+					"pad" + pad.getIndex() + "-newbutton");
+			view.getSettingsButton().getStyleClass().removeAll("pad-button", "pad-settingsbutton", "pad" + pad.getIndex() + "-button",
+					"pad" + pad.getIndex() + "-settingsbutton");
+
+			view.getPlayButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-playbutton-icon",
+					"pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon");
+			view.getPauseButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-pausebutton-icon",
+					"pad" + pad.getIndex() + "-button-icon", "padv-playbutton--icon");
+			view.getStopButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-stopbutton-icon",
+					"pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon");
+			view.getNewButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-newbutton-icon",
+					"pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon");
+			view.getSettingsButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-deletebutton-icon",
+					"pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon");
+
+			view.getButtonBox().getStyleClass().removeAll("pad-button-box");
+			view.getRoot().getStyleClass().removeAll("pad-root");
+		}
+	}
+
+	public AudioPadView getView() {
+		return view;
+	}
+
+	// TODO ErrorHandling
+	private void showError() {
+		PadException lastException = pad.getLastException();
+
+		try {
+			ExceptionDialog dialog = new ExceptionDialog(lastException);
+			dialog.setHeaderText(Localization.getString(Strings.Error_Pad_BaseName + lastException.getType().name(), pad.getPath()));
+
+			if (PlayPadMain.stageIcon.isPresent()) {
+				Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
+				stage.getIcons().add(PlayPadMain.stageIcon.get());
+			}
+
+			dialog.setTitle(Localization.getString(Strings.UI_Dialog_Error_Title));
+			dialog.initOwner(refreshable.getStage());
+			dialog.showAndWait();
+
+			view.setErrorLabelActive(false);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Fügt einen Button zum Pad hinzu
+	 * 
+	 * @param button
+	 * 
+	 * @since 2.0.2
+	 */
+	public void addButton(Button button, ButtonPosition buttonPosition) {
+		if (buttonPosition == ButtonPosition.TOP) {
+			if (!view.getButtonBox().getChildren().contains(button)) {
+				view.getInfoBox().getChildren().add(button);
+			}
+		} else if (buttonPosition == ButtonPosition.BOTTOM) {
+			if (!view.getButtonBox().getChildren().contains(button)) {
+				view.getButtonBox().getChildren().add(button);
+			}
+		}
+	}
+
+	/**
+	 * Fügt einen Button zum Pad hinzu
+	 * 
+	 * @param button
+	 *            Button
+	 * @param index
+	 *            Index
+	 * 
+	 * @since 2.0.2
+	 */
+	public void addNode(Node button, int index, ButtonPosition buttonPosition) {
+		if (buttonPosition == ButtonPosition.TOP) {
+			if (!view.getButtonBox().getChildren().contains(button)) {
+				view.getInfoBox().getChildren().add(index, button);
+			}
+		} else if (buttonPosition == ButtonPosition.BOTTOM) {
+			if (!view.getButtonBox().getChildren().contains(button)) {
+				view.getButtonBox().getChildren().add(index, button);
+			}
+		}
+	}
+
+	/**
+	 * Löscht einen Button vom Pad
+	 * 
+	 * @param button
+	 * 
+	 * @since 2.0.2
+	 */
+	public void removeNode(Node button) {
+		if (view.getButtonBox().getChildren().contains(button)) {
+			view.getButtonBox().getChildren().remove(button);
+		} else if (view.getInfoBox().getChildren().contains(button)) {
+			view.getInfoBox().getChildren().remove(button);
+		}
+	}
+
+	public List<Node> getCustomNodes() {
+		List<Node> buttons = new ArrayList<>();
+		for (Node node : view.getButtonBox().getChildren()) {
+			if (node != view.getPlayButton() || node != view.getPauseButton() || node != view.getStopButton() || node != view.getNewButton()
+					|| node != view.getSettingsButton()) {
+				buttons.add((Button) node);
+			}
+		}
+		return buttons;
+	}
+
+	public void showDnDLayout(boolean show) {
+		view.pseudoClassState(PseudoClasses.DRAG_CLASS, show);
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PlayDurationEventHandler.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PlayDurationEventHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..d603e65dbed0e8c5261784ffc4624391c1ba859f
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PlayDurationEventHandler.java
@@ -0,0 +1,95 @@
+package de.tobias.playpad.viewcontroller.pad;
+
+import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.Warning;
+import de.tobias.playpad.settings.Profile;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.util.Duration;
+
+// TODO Renew class
+class PlayDurationEventHandler implements ChangeListener<Duration>, Runnable {
+
+	/**
+	 * 
+	 */
+	private final PadViewController padViewController;
+
+	/**
+	 * @param padViewController
+	 */
+	PlayDurationEventHandler(PadViewController padViewController) {
+		this.padViewController = padViewController;
+	}
+
+	boolean send = false;
+
+	private Thread warningThread;
+
+	@Override
+	public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
+		if (!send) {
+			if (padViewController != null && padViewController.pad != null && !this.padViewController.pad.isLoop()) {
+				Duration rest = this.padViewController.pad.getAudioHandler().getDuration(this.padViewController.pad).subtract(newValue);
+				double seconds = rest.toSeconds();
+
+				Midi midi = Midi.getInstance();
+
+				if (this.padViewController.midiKeyPressedForPlay != -1) {
+					if (this.padViewController.pad.isCustomWarning()) {
+						if (this.padViewController.pad.getWarningFeedback().get().getTime().toSeconds() > seconds) {
+							startWarningThread();
+
+							if (midi.getMidiDevice().isPresent()) {
+								// TODO MIDI Send Feedback
+							}
+							send = true;
+						}
+					} else {
+						if (Profile.currentProfile().getProfileSettings().getWarningFeedback().getTime().toSeconds() > seconds) {
+							startWarningThread();
+
+							if (midi.getMidiDevice().isPresent()) {
+								// TODO MIDI Send Feedback
+							}
+							send = true;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/*
+	 * EoF GUI Flash
+	 */
+	@Override
+	public void run() {
+		Pad pad = padViewController.getPad();
+
+		Profile currentProfile = Profile.currentProfile();
+		Warning warning = pad.getWarningFeedback().orElseGet(() -> currentProfile.getProfileSettings().getWarningFeedback());
+		if (pad.isCustomLayout()) {
+			pad.currentLayout().ifPresent(layout -> layout.handleWarning(padViewController, warning));
+		} else {
+			currentProfile.currentLayout().handleWarning(padViewController, warning);
+		}
+	}
+
+	protected void startWarningThread() {
+		if (warningThread != null) {
+			warningThread.interrupt();
+		}
+		warningThread = new Thread(this);
+		warningThread.start();
+	}
+
+	protected void stopWaning() {
+		if (warningThread != null) {
+			warningThread.interrupt();
+			padViewController.getView().setStyle("");
+			warningThread = null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/settings/FadeViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/settings/FadeViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a4ee9720e830b10eedb994e8534521a945c4ec2
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/settings/FadeViewController.java
@@ -0,0 +1,74 @@
+package de.tobias.playpad.viewcontroller.settings;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Fade;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+import javafx.fxml.FXML;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.Slider;
+import javafx.util.Duration;
+
+public class FadeViewController extends ContentViewController {
+
+	@FXML private Slider fadeInSlider;
+	@FXML private Slider fadeOutSlider;
+	@FXML private Label fadeInLabel;
+	@FXML private Label fadeOutLabel;
+
+	@FXML private CheckBox fadeInStartCheckBox;
+	@FXML private CheckBox fadeInPauseCheckBox;
+	@FXML private CheckBox fadeOutPauseCheckBox;
+	@FXML private CheckBox fadeOutStopCheckBox;
+
+	private Fade fade;
+
+	public FadeViewController() {
+		super("fadeView", "de/tobias/playpad/assets/settings/", PlayPadMain.getUiResourceBundle());
+	}
+
+	@Override
+	public void init() {
+		fadeInSlider.valueProperty().addListener((a, b, c) ->
+		{
+			Duration seconds = Duration.seconds(c.doubleValue());
+			double displayedTime = Math.round(seconds.toSeconds() * 10) / 10.0;
+			fadeInLabel.setText(Localization.getString(Strings.Standard_Time_Seconds, displayedTime));
+			fade.setFadeIn(seconds);
+		});
+
+		fadeOutSlider.valueProperty().addListener((a, b, c) ->
+		{
+			Duration seconds = Duration.seconds(c.doubleValue());
+			double displayedTime = Math.round(seconds.toSeconds() * 10) / 10.0;
+			fadeOutLabel.setText(Localization.getString(Strings.Standard_Time_Seconds, displayedTime));
+			fade.setFadeOut(seconds);
+		});
+
+		fadeInStartCheckBox.selectedProperty().addListener((a, b, c) -> fade.setFadeInStart(c));
+		fadeInPauseCheckBox.selectedProperty().addListener((a, b, c) -> fade.setFadeInPause(c));
+		fadeOutPauseCheckBox.selectedProperty().addListener((a, b, c) -> fade.setFadeOutPause(c));
+		fadeOutStopCheckBox.selectedProperty().addListener((a, b, c) -> fade.setFadeOutStop(c));
+	}
+
+	public void setFade(Fade fade) {
+		this.fade = fade;
+
+		if (fade != null) {
+			fadeInSlider.setValue(fade.getFadeIn().toSeconds());
+			double displayedInTime = Math.round(fade.getFadeIn().toSeconds() * 10) / 10.0;
+			fadeInLabel.setText(Localization.getString(Strings.Standard_Time_Seconds, displayedInTime));
+			
+			fadeOutSlider.setValue(fade.getFadeOut().toSeconds());
+			double displayedOutTime = Math.round(fade.getFadeOut().toSeconds() * 10) / 10.0;
+			fadeOutLabel.setText(Localization.getString(Strings.Standard_Time_Seconds, displayedOutTime));
+			
+			fadeInStartCheckBox.setSelected(fade.isFadeInStart());
+			fadeInPauseCheckBox.setSelected(fade.isFadeInPause());
+			fadeOutPauseCheckBox.setSelected(fade.isFadeOutPause());
+			fadeOutStopCheckBox.setSelected(fade.isFadeOutStop());
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..f09d2e2dd0cc36f3cdc27f4a0588b961eb18445c
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java
@@ -0,0 +1,61 @@
+package de.tobias.playpad.viewcontroller.settings;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.util.Localization;
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+import javafx.scene.control.Slider;
+import javafx.util.Duration;
+
+public class WarningFeedbackViewController extends ContentViewController {
+
+	@FXML private Slider warningFeedbackTimeSlider;
+	@FXML private Label warningFeedbackTimeLabel;
+
+	public WarningFeedbackViewController() {
+		super("warningFeedbackSettingsView", "de/tobias/playpad/assets/settings/", PlayPadMain.getUiResourceBundle());
+		ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings();
+
+		warningFeedbackTimeSlider.setValue(profilSettings.getWarningFeedback().getTime().toSeconds());
+		setTimeLabel();
+
+		warningFeedbackTimeSlider.valueProperty().addListener((a, b, c) ->
+		{
+			profilSettings.getWarningFeedback().setTime(Duration.seconds(c.doubleValue()));
+		});
+	}
+
+	public WarningFeedbackViewController(Pad pad) {
+		super("warningFeedbackSettingsView", "de/tobias/playpad/assets/settings/", PlayPadMain.getUiResourceBundle());
+	}
+
+	@Override
+	public void init() {
+		warningFeedbackTimeSlider.valueProperty().addListener((a, b, c) ->
+		{
+			setTimeLabel();
+		});
+	}
+
+	private void setTimeLabel() {
+		double displayedTime = Math.round(warningFeedbackTimeSlider.getValue() * 10) / 10.0;
+		warningFeedbackTimeLabel.setText(Localization.getString(Strings.Standard_Time_Seconds, displayedTime));
+	}
+
+	public void setPadWarning(Pad pad) {
+		if (pad.getWarning() != null) {
+			warningFeedbackTimeSlider.setValue(pad.getWarning().getTime().toSeconds());
+			setTimeLabel();
+		}
+
+		warningFeedbackTimeSlider.valueProperty().addListener((a, b, c) ->
+		{
+			pad.getWarning().setTime(Duration.seconds(c.doubleValue()));
+		});
+	}
+}
diff --git a/PlayWall/src/icon.icns b/PlayWall/src/icon.icns
new file mode 100644
index 0000000000000000000000000000000000000000..0b82f6e32cec646a917652b1f7438fe6d9814b27
Binary files /dev/null and b/PlayWall/src/icon.icns differ
diff --git a/PlayWall/src/icon.ico b/PlayWall/src/icon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..376f9b44f0795408da217e99f1ad84c7f8382ba1
Binary files /dev/null and b/PlayWall/src/icon.ico differ
diff --git a/PlayWall/src/icon.png b/PlayWall/src/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2fe4bc8d837c9cb9a166b85503af202dbf4331f
Binary files /dev/null and b/PlayWall/src/icon.png differ
diff --git a/PlayWall/src/icon_small.png b/PlayWall/src/icon_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8acf8263a66f86581c5b5f65f0ad11ff11bf60b
Binary files /dev/null and b/PlayWall/src/icon_small.png differ
diff --git a/PlayWall/test/TestPlayPad.java b/PlayWall/test/TestPlayPad.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8a7b9bebfc3baf679278807749018c5c5654337
--- /dev/null
+++ b/PlayWall/test/TestPlayPad.java
@@ -0,0 +1,37 @@
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.DataLine.Info;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+public class TestPlayPad {
+
+	public static void main(String[] args) throws LineUnavailableException {
+		Mixer mixer = AudioSystem.getMixer(AudioSystem.getMixerInfo()[0]);
+
+		DataLine.Info info = new Info(Clip.class, null);
+		try {
+			Clip clip = (Clip) mixer.getLine(info);
+
+			Path path = Paths.get("/Users/tobias/Downloads/TURN ALL THE LIGHTS ON.wav");
+			AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(path.toFile());
+
+			clip.open(audioInputStream);
+			clip.start();
+
+			do {
+				Thread.sleep(50);
+			} while (clip.isActive());
+
+			clip.close();
+			mixer.close();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+}