/**
* Copyright (C) 2015 Valkyrie RCP
*
* 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.valkyriercp.command.support;
import org.valkyriercp.command.config.CommandButtonConfigurer;
import org.valkyriercp.factory.ButtonFactory;
import org.valkyriercp.util.ValkyrieRepository;
import javax.annotation.PostConstruct;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class SplitPaneExpansionToggleCommand extends ActionCommand
{
private DefaultButtonModel model;
public SplitPaneExpansionToggleCommand(String commandId, JSplitPane splitPane, boolean switchedAway)
{
super(commandId);
this.model = new SplitPaneExpansionButtonModel(splitPane, switchedAway);
ValkyrieRepository.getInstance().getApplicationConfig().commandConfigurer().configure(this);
}
protected void doExecuteCommand()
{
//toggle
this.model.setSelected(!this.model.isSelected());
}
public void doHide()
{
this.model.setSelected(false);
}
public void doShow()
{
this.model.setSelected(true);
}
public AbstractButton createButton(String faceDescriptorId, ButtonFactory buttonFactory,
CommandButtonConfigurer configurer)
{
AbstractButton button = buttonFactory.createToggleButton();
attach(button, faceDescriptorId, configurer);
return button;
}
public void attach(AbstractButton button, String faceDescriptorId,
CommandButtonConfigurer configurer)
{
super.attach(button, faceDescriptorId, configurer);
button.setModel(this.model);
}
public static class SplitPaneExpansionButtonModel extends DefaultButtonModel
{
private final JSplitPane splitPane;
private enum SWITCH_STATE
{
NO_ACTION, SWITCHED_AWAY, SWITCHED_AWAY_AND_MOVED
}
;
private SWITCH_STATE state = SWITCH_STATE.NO_ACTION;
private transient PropertyChangeListener listener = new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent evt)
{
fireStateChanged();
if (state == SWITCH_STATE.SWITCHED_AWAY)
state = SWITCH_STATE.SWITCHED_AWAY_AND_MOVED;
else if (state == SWITCH_STATE.SWITCHED_AWAY_AND_MOVED)
state = SWITCH_STATE.NO_ACTION;
}
};
public SplitPaneExpansionButtonModel(JSplitPane mySplitPane, boolean switchedAway)
{
super();
this.splitPane = mySplitPane;
this.splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY,
listener);
this.splitPane.addComponentListener(new ComponentAdapter()
{
@Override
public void componentResized(ComponentEvent e)
{
if (state == SWITCH_STATE.SWITCHED_AWAY || state == SWITCH_STATE.SWITCHED_AWAY_AND_MOVED)
hidePanel();
}
});
if (switchedAway)
this.state = SWITCH_STATE.SWITCHED_AWAY;
}
public boolean isSelected()
{
return isShown();
}
public void setSelected(boolean makeVisible)
{
super.setSelected(makeVisible);
if (makeVisible)
{
splitPane.resetToPreferredSizes();
state = SWITCH_STATE.NO_ACTION;
}
else
{
hidePanel();
}
}
private void hidePanel()
{
splitPane.setDividerLocation(getHideRightComponentDividerLocation());
state = SWITCH_STATE.SWITCHED_AWAY;
}
private boolean isShown()
{
return splitPane.getDividerLocation() < (getHideRightComponentDividerLocation());
}
private int getHideRightComponentDividerLocation()
{
Dimension size = splitPane.getSize();
int max = getRelevantDimensionpart(size);
Insets insets = splitPane.getInsets();
int relevantInset = getRelevantInsetpart(insets); // we need to correct with the border size
int dividerSize = splitPane.getDividerSize();// we need to correct with the size of the divider!
return max - (relevantInset + dividerSize);
}
private int getRelevantInsetpart(Insets insets)
{
int orientation = splitPane.getOrientation();
int result = (orientation == JSplitPane.VERTICAL_SPLIT) ? // for vertical
(insets.bottom) : //take the height
(insets.right); // else the width
return result;
}
private int getRelevantDimensionpart(Dimension size)
{
int orientation = splitPane.getOrientation();
int result = (orientation == JSplitPane.VERTICAL_SPLIT) ? // for vertical
(int) Math.ceil(size.getHeight()) : //take the height
(int) Math.ceil(size.getWidth()); // else the width
return result;
}
}
}