/*
* Copyright 2015 Sudipto Chandra.
*
* 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.sandsoft.cymric.view;
import org.sandsoft.cymric.model.CymricCore;
import org.sandsoft.cymric.model.SideButton;
import org.sandsoft.cymric.util.Commons;
import org.sandsoft.cymric.util.Logs;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.Tooltip;
import javafx.util.Duration;
/**
* FXML Controller class
*
* @author Sudipto Chandra
*/
public class SidePane extends javafx.scene.layout.BorderPane {
/**
* Creates a new SidePane control.
*
* @param core CymricCore to use.
* @return null if failed.
*/
public static SidePane createNew(CymricCore core) {
try {
//load sidepane
SidePane sidePane = (SidePane) Commons.loadPaneFromFXML(SidePane.class);
//gets the controller
core.setSidePane(sidePane);
sidePane.setCymricCore(core);
sidePane.initialize();
return sidePane;
} catch (Exception ex) {
Logs.showStackTrace(ex);
}
return null;
}
//cymric
private CymricCore mCore;
//whether sidepane expanded
private BooleanProperty mExpanded;
//selected button
private SimpleObjectProperty<SideButton> mSelectedButton;
// FXML definitions
@FXML
private double EXPANDED_WIDTH;
@FXML
private double COLLAPSED_WIDTH;
@FXML
private ToggleGroup sideButton;
// FXML objects
@FXML
private Button menuButton;
@FXML
private ToggleButton snippetsButton;
@FXML
private ToggleButton editorButton;
@FXML
private ToggleButton toolsButton;
@FXML
private ToggleButton notesButton;
@FXML
private ToggleButton projectsButton;
@FXML
private ToggleButton softwaresButton;
@FXML
private ToggleButton settingsButton;
// constructor
public SidePane() {
}
/*
* Initializer for other values after FXML is loaded
*/
public void initialize() {
//init values
mExpanded = new SimpleBooleanProperty(true);
mSelectedButton = new SimpleObjectProperty<>(SideButton.NONE);
//minimize the side pane
handleMenuButtonAction();
//add toggle listener
sideButton.selectedToggleProperty().addListener(
(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) -> {
if (newValue != null) {
selectedButtonChanged((ToggleButton) newValue);
} else {
oldValue.setSelected(true);
}
});
}
/**
* Sets the Cymric core to this object. It should be called after all
* initialization has been completed.
*
* @param core Reference to original Cymric core object.
*/
public void setCymricCore(CymricCore core) {
mCore = core;
}
/**
* Property to control expanded or collapsed state..
*
* @return expanded property
*/
public ReadOnlyBooleanProperty expandedProperty() {
return (ReadOnlyBooleanProperty) mExpanded;
}
/**
* Gets if the side pane is in expanded state.
*
* @return True if is in expanded state, False otherwise.
*/
public boolean isExpanded() {
return mExpanded.getValue();
}
/**
* Property for selected side pane button.
*
* @return Property for selected side pane button.
*/
public SimpleObjectProperty<SideButton> selectedButtonProperty() {
return mSelectedButton;
}
/**
* Gets the side button that has been selected.
*
* @return Button that has been selected.
*/
public SideButton getSelectedButton() {
return mSelectedButton.getValue();
}
/**
* Select a side button.
*
* @param button Button to select.
*/
public void setSelectedButton(SideButton button) {
switch (button) {
case EDITOR_BUTTON:
editorButton.setSelected(true);
break;
case NOTES_BUTTON:
notesButton.setSelected(true);
break;
case PROJECT_BUTTON:
projectsButton.setSelected(true);
break;
case SETTING_BUTTON:
settingsButton.setSelected(true);
break;
case SNIPPET_BUTTON:
snippetsButton.setSelected(true);
break;
case SOFTWARE_BUTTON:
softwaresButton.setSelected(true);
break;
case TOOLS_BUTTON:
toolsButton.setSelected(true);
break;
default:
break;
}
}
//
// FXML action handlers
//
@FXML
private void handleMenuButtonAction() {
if (mExpanded.get()) {
setTooltips();
mExpanded.setValue(false);
resizeAnimation(COLLAPSED_WIDTH);
} else {
removeTooltips();
mExpanded.setValue(true);
resizeAnimation(EXPANDED_WIDTH);
}
}
/**
* Sets ToolTips to toggle buttons
*/
private void setTooltips() {
menuButton.setTooltip(new Tooltip("Menu"));
snippetsButton.setTooltip(new Tooltip(snippetsButton.getText()));
editorButton.setTooltip(new Tooltip(editorButton.getText()));
toolsButton.setTooltip(new Tooltip(toolsButton.getText()));
notesButton.setTooltip(new Tooltip(notesButton.getText()));
projectsButton.setTooltip(new Tooltip(projectsButton.getText()));
softwaresButton.setTooltip(new Tooltip(softwaresButton.getText()));
settingsButton.setTooltip(new Tooltip(settingsButton.getText()));
}
/**
* Removes ToolTips from toggle buttons
*/
private void removeTooltips() {
menuButton.setTooltip(null);
snippetsButton.setTooltip(null);
editorButton.setTooltip(null);
toolsButton.setTooltip(null);
notesButton.setTooltip(null);
projectsButton.setTooltip(null);
softwaresButton.setTooltip(null);
settingsButton.setTooltip(null);
}
/**
* Play transition animation to change side pane width.
*
* @param destWidth Destination size of the side pane.
*/
private void resizeAnimation(double destWidth) {
Timeline timeline = new Timeline();
timeline.getKeyFrames().addAll(
new KeyFrame(Duration.ZERO,
new KeyValue(this.prefWidthProperty(), this.getWidth())),
new KeyFrame(Duration.millis(100),
new KeyValue(this.prefWidthProperty(), destWidth)));
timeline.play();
}
/**
* Called when button selection is changed. It updates the value of
* mSelectedButton and make a call to RootLayout to display the selected
* content.
*/
private void selectedButtonChanged(ToggleButton button) {
if (editorButton == button) {
if (mSelectedButton.get() != SideButton.EDITOR_BUTTON) {
mCore.getRootLayout().addLayout(mCore.getEditorLayout());
mSelectedButton.set(SideButton.EDITOR_BUTTON);
}
} else if (snippetsButton == button) {
if (mSelectedButton.get() != SideButton.SNIPPET_BUTTON) {
mCore.getRootLayout().addLayout(mCore.getSnippetLayout());
mSelectedButton.set(SideButton.SNIPPET_BUTTON);
}
} else if (notesButton == button) {
if (mSelectedButton.get() != SideButton.NOTES_BUTTON) {
mCore.getRootLayout().addLayout(mCore.getNotesLayout());
mSelectedButton.set(SideButton.NOTES_BUTTON);
}
} else if (toolsButton == button) {
if (mSelectedButton.get() != SideButton.TOOLS_BUTTON) {
mCore.getRootLayout().addLayout(mCore.getToolsLayout());
mSelectedButton.set(SideButton.TOOLS_BUTTON);
}
} else if (projectsButton == button) {
if (mSelectedButton.get() != SideButton.PROJECT_BUTTON) {
mCore.getRootLayout().addLayout(mCore.getProjectLayout());
mSelectedButton.set(SideButton.PROJECT_BUTTON);
}
} else if (softwaresButton == button) {
if (mSelectedButton.get() != SideButton.SOFTWARE_BUTTON) {
mCore.getRootLayout().addLayout(mCore.getSoftwareLayout());
mSelectedButton.set(SideButton.SOFTWARE_BUTTON);
}
} else if (settingsButton == button) {
if (mSelectedButton.get() != SideButton.SETTING_BUTTON) {
mCore.getRootLayout().addLayout(mCore.getSettingsLayout());
mSelectedButton.set(SideButton.SETTING_BUTTON);
}
} else {
mCore.getRootLayout().addLayout(null);
mSelectedButton.set(SideButton.NONE);
}
}
}