package org.openflexo.view;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.UIManager;
import org.openflexo.components.widget.FIBProjectSelector;
import org.openflexo.foundation.rm.FlexoProject;
import org.openflexo.icon.IconLibrary;
import org.openflexo.localization.FlexoLocalization;
import org.openflexo.module.Module;
import org.openflexo.module.ModuleLoader;
import org.openflexo.module.ModuleLoadingException;
import org.openflexo.swing.BarButton;
import org.openflexo.swing.CustomPopup;
import org.openflexo.toolbox.PropertyChangeListenerRegistrationManager;
import org.openflexo.view.controller.FlexoController;
import org.openflexo.view.controller.model.ControllerModel;
import org.openflexo.view.controller.model.FlexoPerspective;
public class MainPaneTopBar extends JMenuBar {
private static final java.util.logging.Logger logger = org.openflexo.logging.FlexoLogger.getLogger(MainPaneTopBar.class.getPackage()
.getName());
private PropertyChangeListenerRegistrationManager registrationManager;
private ControllerModel model;
private JPanel left;
private JPanel center;
private JPanel right;
private JComponent header;
private JButton leftViewToggle;
private JButton rightViewToggle;
private JPanel perspectives;
private boolean forcePreferredSize;
private final FlexoController controller;
private FIBProjectSelector projectSelector;
public MainPaneTopBar(@Nonnull FlexoController controller) {
this.controller = controller;
this.model = controller.getControllerModel();
registrationManager = new PropertyChangeListenerRegistrationManager();
setLayout(new BorderLayout());
this.forcePreferredSize = true/*ToolBox.getPLATFORM() != ToolBox.MACOS*/;
add(left = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)), BorderLayout.WEST);
add(center = new JPanel(new BorderLayout()));
add(right = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)), BorderLayout.EAST);
left.setOpaque(false);
center.setOpaque(false);
right.setOpaque(false);
initLeftRightViewVisibilityControls();
initModules();
if (controller.getModule().getModule().requireProject()) {
initProjectSelector();
}
// initNavigationControls();
initPerspectives();
}
public void delete() {
registrationManager.delete();
if (projectSelector != null) {
projectSelector.delete();
}
}
private void initModules() {
for (final Module module : model.getModuleLoader().getAvailableModules()) {
final JButton button = new BarButton(module.getMediumIcon());
button.setToolTipText(FlexoLocalization.localizedTooltipForKey(module.getName(), button));
button.setEnabled(true);
button.setFocusable(false);
if (forcePreferredSize) {
button.setPreferredSize(new Dimension(button.getIcon().getIconWidth() + 4, button.getIcon().getIconHeight() + 4));
}
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
model.getModuleLoader().switchToModule(module);
} catch (ModuleLoadingException e1) {
e1.printStackTrace();
FlexoController.notify(e1.getLocalizedMessage());
}
}
});
PropertyChangeListener listener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
button.setIcon(model.getModuleLoader().isLoaded(module) ? module.getMediumIconWithHover() : module.getMediumIcon());
button.setSelected(model.getModuleLoader().isActive(module));
}
};
registrationManager.new PropertyChangeListenerRegistration(ModuleLoader.ACTIVE_MODULE, listener, model.getModuleLoader());
registrationManager.new PropertyChangeListenerRegistration(ModuleLoader.MODULE_ACTIVATED, listener, model.getModuleLoader());
registrationManager.new PropertyChangeListenerRegistration(ModuleLoader.MODULE_LOADED, listener, model.getModuleLoader());
registrationManager.new PropertyChangeListenerRegistration(ModuleLoader.MODULE_UNLOADED, listener, model.getModuleLoader());
left.add(button);
}
}
private void initNavigationControls() {
final JButton backwardButton = new BarButton(IconLibrary.NAVIGATION_BACKWARD_ICON);
if (forcePreferredSize) {
backwardButton.setPreferredSize(new Dimension(24, 24));
}
backwardButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.historyBack();
}
});
final JButton forwardButton = new BarButton(IconLibrary.NAVIGATION_FORWARD_ICON);
if (forcePreferredSize) {
forwardButton.setPreferredSize(new Dimension(24, 24));
}
forwardButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.historyForward();
}
});
final JButton upButton = new BarButton(IconLibrary.NAVIGATION_UP_ICON);
if (forcePreferredSize) {
upButton.setPreferredSize(new Dimension(24, 24));
}
upButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.goUp();
}
});
PropertyChangeListener listener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateNavigationControlState(backwardButton, forwardButton, upButton);
}
};
registrationManager.new PropertyChangeListenerRegistration(ControllerModel.CURRENT_LOCATION, listener, model);
registrationManager.new PropertyChangeListenerRegistration(ControllerModel.CURRENT_EDITOR, listener, model);
left.add(backwardButton);
left.add(upButton);
left.add(forwardButton);
updateNavigationControlState(backwardButton, forwardButton, upButton);
}
private void initProjectSelector() {
projectSelector = new FIBProjectSelector(null) {
@Override
public boolean evaluateSelectableCondition(FlexoProject project) {
return model.isSelectableProject(project);
}
};
projectSelector.addApplyCancelListener(new CustomPopup.ApplyCancelListener() {
@Override
public void fireApplyPerformed() {
if (projectSelector.getEditedObject() != null) {
model.setCurrentProject(projectSelector.getEditedObject());
} else {
projectSelector.setEditedObject(model.getCurrentProject());
}
}
@Override
public void fireCancelPerformed() {
}
});
registrationManager.new PropertyChangeListenerRegistration(ControllerModel.CURRENT_EDITOR, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
projectSelector.setEditedObject(model.getCurrentProject());
}
}, model);
projectSelector.setShowReset(false);
projectSelector.setFlexoController(controller);
projectSelector.setProjectLoader(model.getProjectLoader());
left.add(projectSelector);
}
protected void updateNavigationControlState(final JButton backwardButton, final JButton forwardButton, final JButton upButton) {
backwardButton.setEnabled(model.canGoBack());
forwardButton.setEnabled(model.canGoForward());
upButton.setEnabled(model.canGoUp());
}
private void initPerspectives() {
right.add(perspectives = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0)), 0);
perspectives.setOpaque(false);
registrationManager.new PropertyChangeListenerRegistration(ControllerModel.PERSPECTIVES, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() != null) {
insertPerspective((FlexoPerspective) evt.getNewValue());
} else {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Perspective removal not supported by top bar.");
}
}
}
}, model);
for (final FlexoPerspective p : model.getPerspectives()) {
insertPerspective(p);
}
}
private void insertPerspective(final FlexoPerspective p) {
final JButton button = new BarButton(p.getActiveIcon());
if (forcePreferredSize) {
int size = Math.max(button.getIcon().getIconWidth() + 8, button.getIcon().getIconHeight() + 4);
button.setPreferredSize(new Dimension(size, size));
}
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.setCurrentPerspective(p);
}
});
registrationManager.new PropertyChangeListenerRegistration(ControllerModel.CURRENT_LOCATION, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateIconForButtonPerspective(button, p);
}
}, model);
updateIconForButtonPerspective(button, p);
perspectives.add(button);
}
protected void updateIconForButtonPerspective(JButton buttonPerspective, FlexoPerspective p) {
buttonPerspective.setSelected(model.getCurrentPerspective() == p);
}
private void initLeftRightViewVisibilityControls() {
leftViewToggle = getToggleVisibilityButton();
leftViewToggle.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.setLeftViewVisible(!model.isLeftViewVisible());
}
});
left.add(leftViewToggle, 0);
registrationManager.new PropertyChangeListenerRegistration(ControllerModel.LEFT_VIEW_VISIBLE, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateLeftViewToggleIcon();
}
}, model);
updateLeftViewToggleIcon();
rightViewToggle = getToggleVisibilityButton();
rightViewToggle.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.setRightViewVisible(!model.isRightViewVisible());
}
});
right.add(rightViewToggle);
registrationManager.new PropertyChangeListenerRegistration(ControllerModel.RIGHT_VIEW_VISIBLE, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateRightViewToggleIcon();
}
}, model);
updateRightViewToggleIcon();
}
protected void updateLeftViewToggleIcon() {
leftViewToggle.setIcon(model.isLeftViewVisible() ? IconLibrary.TOGGLE_ARROW_BOTTOM_ICON : IconLibrary.TOGGLE_ARROW_TOP_ICON);
leftViewToggle.setRolloverIcon(model.isLeftViewVisible() ? IconLibrary.TOGGLE_ARROW_BOTTOM_SELECTED_ICON
: IconLibrary.TOGGLE_ARROW_TOP_SELECTED_ICON);
}
protected void updateRightViewToggleIcon() {
rightViewToggle.setIcon(model.isRightViewVisible() ? IconLibrary.TOGGLE_ARROW_BOTTOM_ICON : IconLibrary.TOGGLE_ARROW_TOP_ICON);
rightViewToggle.setRolloverIcon(model.isRightViewVisible() ? IconLibrary.TOGGLE_ARROW_BOTTOM_SELECTED_ICON
: IconLibrary.TOGGLE_ARROW_TOP_SELECTED_ICON);
}
private JButton getToggleVisibilityButton() {
final JButton button = new BarButton(IconLibrary.TOGGLE_ARROW_TOP_ICON);
button.setRolloverIcon(IconLibrary.TOGGLE_ARROW_TOP_SELECTED_ICON);
if (forcePreferredSize) {
button.setPreferredSize(new Dimension(button.getIcon().getIconWidth() + 2, button.getIcon().getIconHeight() + 20));
}
return button;
}
public void setHeader(JComponent header) {
if (this.header != header) {
if (this.header != null) {
right.remove(this.header);
right.revalidate();
}
this.header = header;
if (header != null) {
header.setOpaque(false);
right.add(header, 0);
right.revalidate();
}
}
}
public void setLeftViewToggle(boolean visible) {
leftViewToggle.setEnabled(visible);
}
public void setRightViewToggle(boolean visible) {
rightViewToggle.setEnabled(visible);
}
@Override
public void updateUI() {
super.updateUI();
setBackground(UIManager.getDefaults().getColor("ToolBar.floatingForeground"));
}
}