/* * Copyright 2013 eWidgetFX. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.ewidgetfx.applauncher.apptrayfx; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Dimension2D; import javafx.scene.Node; import javafx.scene.input.MouseEvent; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.stage.Screen; import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.util.Duration; import org.ewidgetfx.applauncher.apptrayfx.iconswipelist.IconSwipeListInfo; import org.ewidgetfx.applauncher.apptrayfx.iconswipelist.IconSwipeListPane; import org.ewidgetfx.applauncher.apptrayfx.tab.VerticalTab; import org.ewidgetfx.applauncher.apptrayfx.tab.VerticalTabPane; import org.ewidgetfx.applauncher.apptrayfx.tileselector.TileSelector; import org.ewidgetfx.core.Widget; import org.ewidgetfx.core.WidgetIcon; import org.ewidgetfx.util.DragStagePane; import org.ewidgetfx.util.WidgetFactory; import java.util.*; import javafx.scene.effect.DropShadow; import org.apache.log4j.Logger; /** * * @author Carl Dea <carl.dea@gmail.com> * @since 1.0 */ public final class VerticalAppTray extends AppTray { private static final Logger logger = Logger.getLogger(VerticalAppTray.class); private VBox vBox; Text appNameText; Dimension2D iconDim = new Dimension2D(50, 50); // Tab 2 workspaces. Maps the jar filename with the Widget. TileSelector tileSelector = new TileSelector(2, 2); Map<Integer, Set<Widget>> workspaceWidgetMap = new HashMap<>(); Map<Widget, WidgetInfo> widgetWidgetInfoMap = new HashMap<>(); public VerticalAppTray(Stage primaryStage, String[][] icons) { super(primaryStage, icons); init(); } public void init() { primaryStage.initStyle(StageStyle.TRANSPARENT); // create 4 workspaces. workspaceWidgetMap.put(1, new HashSet<>()); workspaceWidgetMap.put(2, new HashSet<>()); workspaceWidgetMap.put(3, new HashSet<>()); workspaceWidgetMap.put(4, new HashSet<>()); // build tab control # of tabs VerticalTabPane tabPane = new VerticalTabPane(VerticalTabPane.Side.LEFT, 220, 300); // add draggable title // applications tabPane.addTab(createTab1(tabPane)); // WorkSpaces tabPane.addTab(createTab2(tabPane)); // Settings tabPane.addTab(createTab3(tabPane)); tabPane.selectTab(0); // place the drag area (dragStagePane) and the application tray thingy. getChildren().addAll(tabPane); } public void addIconToTray(Widget widget) { sizeWidgetIcon(widget, iconDim, appNameText); getWidgetIconList().add(0, widget.getWidgetIcon()); } private VerticalTab createTab1(VerticalTabPane tabPane) { DropShadow dropShadow = new DropShadow(); dropShadow.setOffsetX(USE_PREF_SIZE); dropShadow.setOffsetY(USE_PREF_SIZE); dropShadow.setColor(Color.rgb(50, 50, 50, .588)); appNameText = new Text(5, 140, ""); appNameText.setFill(Color.YELLOW); appNameText.setEffect(dropShadow); appNameText.setFont(Font.font("Serif", 20)); ObservableList<WidgetIcon> nodes = buildIcons2(primaryStage, iconDim, appNameText); // Vertical //IconListPaneVertical iconListPane = new IconListPaneVertical(new IconListVertical(nodes)); IconSwipeListInfo info = new IconSwipeListInfo(); // size of the surface of the icon swipe list. info.widthProperty().set(50); info.heightProperty().set(300); // create a view port for the swipe area. info.getScrollViewPort().xProperty().set(10); info.getScrollViewPort().yProperty().set(10); info.getScrollViewPort() .widthProperty() .bind(info.widthProperty()); info.getScrollViewPort() .heightProperty().bind(info.heightProperty() .subtract(info.getScrollViewPort() .yProperty() .multiply(2))); vBox = new VBox(); vBox.setMaxWidth(50); vBox.setMinWidth(50); vBox.setMaxHeight(50); vBox.setMinWidth(50); vBox.setLayoutX(10); vBox.setLayoutY(5); vBox.getChildren().addListener(new ListChangeListener<Node>() { @Override public void onChanged(Change<? extends Node> change) { if (change.next() && change.wasAdded()) { change.getAddedSubList().forEach(o -> { WidgetIcon icon = (WidgetIcon) o; Widget w = WidgetFactory.lookup(icon.getWidgetFilename()); if (w == null) { return; } logger.info("widget " + w); // if a widget was closed remove them from the workspace. w.getWidgetState().stopPropertyProperty().addListener((ChangeListener) (observableValue, aBoolean, aBoolean2) -> { if ((Boolean) aBoolean2) { workspaceWidgetMap.values().stream().forEach((workspace) -> { workspace.remove(w); }); } }); icon.addEventHandler(MouseEvent.MOUSE_CLICKED, (EventHandler) (mouseEvent) -> { logger.info("setting workspace " + icon.getWidgetFilename()); // this check if a widget is already in a workspace. boolean found = false; for (Set<Widget> workspace : workspaceWidgetMap.values()) { if (workspace.contains(w)) { found = true; break; } } // add the launched widget onto the current workspace if (!found) { workspaceWidgetMap.get(tileSelector.getCellNumber()).add(WidgetFactory.lookup(icon.getWidgetFilename())); } }); }); } } }); vBox.getChildren().addAll(nodes); IconSwipeListPane iconListPane = new IconSwipeListPane(info, vBox, IconSwipeListPane.SwipeAxis.VERTICAL); DragStagePane dragStagePane = new DragStagePane(primaryStage); dragStagePane.setLayoutX(60); dragStagePane.setLayoutY(10); Rectangle whiteRectangle = new Rectangle(200 - 50 - 20,300 - 20,Color.rgb(255, 255, 255, .30)); dragStagePane.getChildren().addAll(whiteRectangle, appNameText); VerticalTab tab1 = new VerticalTab("Apps", 0, tabPane); Pane tab1Content = new Pane(); tab1Content.getChildren().addAll(dragStagePane, iconListPane); tab1.setContent(tab1Content); return tab1; } private VerticalTab createTab2(VerticalTabPane tabPane) { VerticalTab tab = new VerticalTab("Spaces", 1, tabPane); Pane tabContent = new Pane(); tileSelector.layoutXProperty().bind(tabPane.widthProperty().subtract(VerticalTab.TAB_WIDTH) .subtract(tileSelector.widthProperty()) .divide(2)); tileSelector.layoutYProperty().bind(tabPane.heightProperty() .subtract(tileSelector.heightProperty()) .divide(2)); tabContent.getChildren().add(tileSelector); tileSelector.cellNumberProperty().set(1); tileSelector.cellNumberProperty().addListener((ObservableValue<? extends Number> observableValue, Number oldNumber, Number newNumber) -> { List<KeyFrame> moveWindowsOut = new ArrayList<>(); List<KeyFrame> moveWindowsIn = new ArrayList<>(); // move widget's out of view. workspaceWidgetMap.get(oldNumber.intValue()).forEach((Widget widget) -> { logger.info(widget.getName() + " in workspace " + oldNumber); // save current location Stage widgetStage = widget.getParentStage(); logger.info("moving out code: stage: " + widgetStage.hashCode()); double x = widgetStage.getX(); double y = widgetStage.getY(); WidgetInfo widgetInfo = widgetWidgetInfoMap.get(widget); // TODO: Clean this up!!! needs to be more efficient. if (widgetInfo == null) { widgetInfo = new WidgetInfo(); } if (widgetInfo.getCurrentXChangeListener() != null) { widgetInfo.currentXProperty().removeListener(widgetInfo.getCurrentXChangeListener()); widgetInfo.currentYProperty().removeListener(widgetInfo.getCurrentYChangeListener()); } widgetInfo.setCurrentXChangeListener((ChangeListener<Number>) (observableValue1, oldX, newX) -> { widgetStage.setX(newX.doubleValue()); }); widgetInfo.setCurrentYChangeListener((ChangeListener<Number>) (observableValue1, oldY, newY) -> { widgetStage.setY(newY.doubleValue()); }); widgetInfo.currentXProperty().addListener(widgetInfo.getCurrentXChangeListener()); widgetInfo.currentYProperty().addListener(widgetInfo.getCurrentYChangeListener()); widgetInfo.setSavedX(x); widgetInfo.setSavedY(y); widgetInfo.setCurrentX(x); widgetInfo.setCurrentY(y); // move from current to new y // determine go top or bottom double h = widgetStage.getHeight(); double midPoint = Screen.getPrimary().getBounds().getHeight() / 2; double direction = ((y + h) - midPoint) - (midPoint - y); boolean top = direction <= 0; double moveYTo = (top) ? (-h) : Screen.getPrimary().getBounds().getHeight(); KeyValue keyValue = new KeyValue(widgetInfo.currentYProperty(), moveYTo); KeyFrame keyFrame = new KeyFrame(Duration.millis(200), keyValue); moveWindowsOut.add(keyFrame); widgetWidgetInfoMap.put(widget, widgetInfo); }); // create animation to move widget's out of view. Timeline moveOutTimeline = new Timeline(); moveOutTimeline.setOnFinished((ActionEvent actionEvent) -> { workspaceWidgetMap.get(oldNumber.intValue()).forEach((Widget widget) -> { widget.pause(); }); }); moveOutTimeline.getKeyFrames().addAll(moveWindowsOut); logger.info("workspace selected: " + newNumber); workspaceWidgetMap.get(newNumber.intValue()).forEach((widget) -> { logger.info(widget.getName() + " in workspace " + newNumber); WidgetInfo widgetInfo = widgetWidgetInfoMap.get(widget); KeyValue keyValue = new KeyValue(widgetInfo.currentYProperty(), widgetInfo.getSavedY()); KeyFrame keyFrame = new KeyFrame(Duration.millis(200), keyValue); moveWindowsIn.add(keyFrame); widget.getParentStage().show(); widget.resume(); widget.getParentStage().toFront(); }); // create animation to move widget's out of view. Timeline moveInTimeline = new Timeline(); moveInTimeline.getKeyFrames().addAll(moveWindowsIn); moveOutTimeline.playFromStart(); moveInTimeline.playFromStart(); }); setStyle("-fx-background-color: transparent;"); tab.setContent(tabContent); return tab; } private VerticalTab createTab3(VerticalTabPane tabPane) { VerticalTab tab = new VerticalTab("Settings", 2, tabPane); Pane tabContent = new Pane(); //tabContent.getChildren().add(); tab.setContent(tabContent); return tab; } public ObservableList<Node> getWidgetIconList() { return vBox.getChildren(); } }