package org.korsakow.ide.ui.interfacebuilder.widget;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JComponent;
import javax.swing.JLabel;
import org.korsakow.domain.interf.IMedia;
import org.korsakow.domain.mapper.input.MediaInputMapper;
import org.korsakow.ide.Application;
import org.korsakow.ide.lang.LanguageBundle;
import org.korsakow.ide.resources.ResourceType;
import org.korsakow.ide.resources.WidgetType;
import org.korsakow.ide.resources.media.MediaFactory;
import org.korsakow.ide.resources.media.Playable;
import org.korsakow.ide.resources.property.AbstractProperty;
import org.korsakow.ide.resources.property.BooleanProperty;
import org.korsakow.ide.resources.property.LongProperty;
import org.korsakow.ide.resources.widget.PlayMode;
import org.korsakow.ide.resources.widget.ScalingPolicy;
import org.korsakow.ide.resources.widget.WidgetComponent;
import org.korsakow.ide.resources.widget.WidgetModel;
import org.korsakow.ide.resources.widget.WidgetPropertiesEditor;
import org.korsakow.ide.resources.widget.editors.MediaAreaWidgetEditor;
import org.korsakow.ide.ui.components.ResourceIcon;
public class MediaArea extends WidgetModel
{
private static class MediaAreaWidgetComponent extends WidgetComponent
{
private JLabel label;
private ResourceIcon icon;
private Component mediaComponent;
private AspectRatioWrapper wrapper;
private Playable playable;
public MediaAreaWidgetComponent(WidgetModel owner)
{
super(owner);
}
@Override
protected void initUI()
{
super.initUI();
setLayout(new BorderLayout());
setSize(80, 80);
add(label = new JLabel(LanguageBundle.getString("widget.mediaarea.label")), BorderLayout.NORTH);
label.setAlignmentX(JComponent.CENTER_ALIGNMENT);
label.setAlignmentX(JComponent.CENTER_ALIGNMENT);
icon = new ResourceIcon();
}
@Override
public void setEnabled(boolean b)
{
super.setEnabled(b);
}
public void setMedia(IMedia media)
{
if (media != null)
icon.setResource(ResourceType.forId(media.getType()).getIcon(), media.getName());
else
icon.clear();
if (playable != null) {
playable.dispose();
playable = null;
}
if (mediaComponent != null) {
mediaComponent.getParent().remove(mediaComponent);
mediaComponent = null;
}
label.setVisible(media == null);
if (media != null) {
playable = MediaFactory.getMediaNoThrow(media);
mediaComponent = playable.getComponent();
wrapper = new AspectRatioWrapper(mediaComponent, playable, getWidget().getScalingPolicy());
add(wrapper, BorderLayout.CENTER);
}
revalidate();
repaint();
}
@Override
public MediaArea getWidget() {
return (MediaArea)super.getWidget();
}
public AspectRatioWrapper getWrapper() {
return wrapper;
}
}
@Override
protected WidgetComponent createComponent()
{
return new MediaAreaWidgetComponent(this);
}
@Override
protected WidgetPropertiesEditor createWidgetEditor()
{
return new MediaAreaWidgetEditor(this);
}
private IMedia media;
private PlayMode playMode = PlayMode.Always;
private Boolean looping = Boolean.FALSE;
protected ScalingPolicy scalingPolicy = ScalingPolicy.MaintainAspectRatio;
public MediaArea()
{
super(WidgetType.MediaArea);
addProperty(new LongProperty("mediaId") {
@Override
public Long getValue() { return getMedia()!=null?getMedia().getId():null; }
@Override
public void setValue(Long value) {
try {
setMedia(value!=null?MediaInputMapper.map(value):null);
} catch (Exception e) {
Application.getInstance().showUnhandledErrorDialog(LanguageBundle.getString("general.errors.uncaughtexception.title"), e);
}
}
});
addProperty(new AbstractProperty("scalingPolicy") {
@Override
public Object getValue() { return getScalingPolicy().getId(); }
@Override
public void setValue(Object value) {
if (value instanceof ScalingPolicy == false)
value = ScalingPolicy.forId(value.toString());
setScalingPolicy((ScalingPolicy)value);
}
});
addProperty(new AbstractProperty("playMode") {
@Override
public Object getValue() { return getPlayMode().getId(); }
@Override
public void setValue(Object value) {
if (value instanceof PlayMode == false)
value = PlayMode.forId(value.toString());
setPlayMode((PlayMode)value);
}
});
addProperty(new BooleanProperty("looping", false) {
@Override
public Boolean getValue() { return getLooping(); }
@Override
public void setValue(Boolean value) {
setLooping(value);
}
});
}
@Override
public MediaAreaWidgetComponent getComponent() {
return (MediaAreaWidgetComponent)super.getComponent();
}
public void setMedia(IMedia media)
{
getComponent().setMedia(media);
IMedia oldMedia = this.media;
this.media = media;
firePropertyChange("media", oldMedia, media);
}
public IMedia getMedia()
{
return media;
}
public ScalingPolicy getScalingPolicy()
{
return scalingPolicy;
}
public void setScalingPolicy(ScalingPolicy scalingPolicy)
{
ScalingPolicy oldValue = scalingPolicy;
this.scalingPolicy = scalingPolicy;
if (getComponent().getWrapper() != null)
getComponent().getWrapper().setScalingPolicy(scalingPolicy);
firePropertyChange("scalingPolicy", oldValue, scalingPolicy);
}
public Boolean getLooping()
{
return looping;
}
public void setLooping(Boolean looping)
{
this.looping = looping;
}
public PlayMode getPlayMode()
{
return playMode;
}
public void setPlayMode(PlayMode playMode)
{
PlayMode oldValue = playMode;
this.playMode = playMode;
firePropertyChange("playMode", oldValue, playMode);
}
public static class AspectRatioWrapper extends JComponent
{
private final Component content;
private final Playable playable;
private ScalingPolicy scalingPolicy;
public AspectRatioWrapper(Component content, Playable playable, ScalingPolicy scalingPolicy)
{
this.content = content;
this.playable = playable;
this.scalingPolicy = scalingPolicy;
add(content);
setLayout(null);
}
@Override
public Dimension getPreferredSize() {
return content.getPreferredSize();
}
@Override
public void doLayout() {
Dimension d = getSize();
switch (scalingPolicy)
{
case ExactFit:
d = getSize();
break;
case MaintainAspectRatio:
d = playable.getAspectRespectingDimension(d);
break;
case ScaleDownMaintainAspectRatio:
Dimension pref = content.getPreferredSize();
if (d.width < pref.width || d.height < pref.height)
d = playable.getAspectRespectingDimension(d);
else
d = pref;
break;
case None:
d = content.getPreferredSize();
break;
}
content.setSize(d);
content.setLocation((getWidth() - d.width)/2, (getHeight() - d.height) /2);
}
public void setScalingPolicy(ScalingPolicy scalingPolicy) {
this.scalingPolicy = scalingPolicy;
repaint();
revalidate();
}
}
}