package org.jtheque.ui.impl;
import org.jtheque.core.Core;
import org.jtheque.states.Load;
import org.jtheque.states.Save;
import org.jtheque.states.State;
import org.jtheque.utils.annotations.GuardedInternally;
import org.jtheque.utils.annotations.ThreadSafe;
import org.jtheque.utils.collections.CollectionUtils;
import org.jtheque.utils.ui.SwingUtils;
import org.jtheque.xml.utils.Node;
import org.jtheque.xml.utils.NodeAttribute;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
/*
* Copyright JTheque (Baptiste Wicht)
*
* 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.
*/
/**
* A state for persist different views configuration.
*
* @author Baptiste Wicht
*/
@ThreadSafe
@State(id = "jtheque-windows-configuration", delegated = true)
public final class WindowsConfiguration {
@GuardedInternally
private final Map<String, WindowConfiguration> configurations = CollectionUtils.newConcurrentMap(10);
private final Core core;
/**
* Create a new WindowsConfiguration.
*
* @param core The core.
*/
public WindowsConfiguration(Core core) {
super();
this.core = core;
}
/**
* Load the nodes into the state.
*
* @param nodes The nodes to load.
*/
@Load
public void delegateLoad(Iterable<Node> nodes) {
for (Node node : nodes) {
if ("window".equals(node.getName())) {
WindowConfiguration configuration = new WindowConfiguration();
for (Node child : node.getChildrens()) {
applyValueFromChild(configuration, child);
}
add(node.getAttributeValue("name"), configuration);
}
}
}
/**
* Apply the value from child.
*
* @param configuration The window configuration.
* @param child The child.
*/
private static void applyValueFromChild(WindowConfiguration configuration, Node child) {
if ("width".equals(child.getName())) {
configuration.setWidth(Integer.parseInt(child.getText()));
} else if ("height".equals(child.getName())) {
configuration.setHeight(Integer.parseInt(child.getText()));
} else if ("posX".equals(child.getName())) {
configuration.setPositionX(Integer.parseInt(child.getText()));
} else if ("posY".equals(child.getName())) {
configuration.setPositionY(Integer.parseInt(child.getText()));
}
}
/**
* Save the nodes of the state.
*
* @return All the nodes to be saved by the state.
*/
@Save
public Collection<Node> delegateSave() {
Collection<Node> states = CollectionUtils.newList();
for (Entry<String, WindowConfiguration> configuration : configurations.entrySet()) {
Node state = new Node("window");
state.addAttribute(new NodeAttribute("name", configuration.getKey()));
state.addChild(new Node("width", Integer.toString(configuration.getValue().getWidth())));
state.addChild(new Node("height", Integer.toString(configuration.getValue().getHeight())));
state.addChild(new Node("posX", Integer.toString(configuration.getValue().getPositionX())));
state.addChild(new Node("posY", Integer.toString(configuration.getValue().getPositionY())));
states.add(state);
}
return states;
}
/**
* Add a window configuration for a view.
*
* @param name The name of the view.
* @param configuration The configuration to add.
*/
private void add(String name, WindowConfiguration configuration) {
configurations.put(name, configuration);
}
/**
* Update the configuration with the view.
*
* @param name The name of the view.
* @param view The view.
*/
public void update(String name, Window view) {
if (core.getConfiguration().retainSizeAndPositionOfWindow()) {
WindowConfiguration configuration = get(name);
if (configuration != null) {
configuration.setWidth(view.getWidth());
configuration.setHeight(view.getHeight());
configuration.setPositionX(view.getLocation().x);
configuration.setPositionY(view.getLocation().y);
}
}
}
/**
* Return the window configuration for a view.
*
* @param name The name of the view.
*
* @return The window configuration for the view.
*/
private WindowConfiguration get(String name) {
return configurations.get(name);
}
/**
* Configure the view.
*
* @param name The name of the view.
* @param view The view.
* @param defaultWidth The default width of the view.
* @param defaultHeight The default height of the view.
*/
public void configure(String name, Window view, int defaultWidth, int defaultHeight) {
if (core.getConfiguration().retainSizeAndPositionOfWindow()) {
WindowConfiguration configuration = get(name);
if (configuration == null) {
configuration = new WindowConfiguration();
configuration.setWidth(defaultWidth);
configuration.setHeight(defaultHeight);
configuration.setPositionX(-1);
configuration.setPositionY(-1);
add(name, configuration);
}
view.setSize(configuration.getWidth(), configuration.getHeight());
if (configuration.getPositionX() == -1 || configuration.getPositionY() == -1) {
SwingUtils.centerFrame(view);
} else {
if (GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().contains(
configuration.getPositionX(), configuration.getPositionY())) {
view.setLocation(configuration.getPositionX(), configuration.getPositionY());
} else {
SwingUtils.centerFrame(view);
}
}
} else {
view.setSize(defaultWidth, defaultHeight);
SwingUtils.centerFrame(view);
}
}
/**
* A Window Configuration. It seems a state to persist the location and the size on a window in closing.
*
* @author Baptiste Wicht
*/
private static final class WindowConfiguration {
private int width;
private int height;
private int positionX;
private int positionY;
/**
* Set the width of the window.
*
* @param width The width of the window.
*/
public void setWidth(int width) {
this.width = width;
}
/**
* Set the height of the window.
*
* @param height The height of the window.
*/
public void setHeight(int height) {
this.height = height;
}
/**
* Set the X position of the window.
*
* @param positionX The X position of the window.
*/
public void setPositionX(int positionX) {
this.positionX = positionX;
}
/**
* Set the Y position of the window.
*
* @param positionY The Y position of the window.
*/
public void setPositionY(int positionY) {
this.positionY = positionY;
}
/**
* Return the width of the window.
*
* @return The width of the window.
*/
public int getWidth() {
return width;
}
/**
* Return the height of the window.
*
* @return The height of the window.
*/
public int getHeight() {
return height;
}
/**
* Return the Y position of the window.
*
* @return The Y position of the window.
*/
public int getPositionY() {
return positionY;
}
/**
* Return the X position of the window.
*
* @return The X position of the window.
*/
public int getPositionX() {
return positionX;
}
}
}