package com.pointcliki.ui;
import java.util.Iterator;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;
import com.pointcliki.core.Entity;
import com.pointcliki.core.EntityContainer;
import com.pointcliki.input.MouseEvent;
/**
* The UIEntity class is a special entity container that exposes mouse events
* through the FocusEvent class, allowing UI entities to control how to behave
* with different clicks, dragging and focusing.
*
* @author Hugheth
* @since 3
*/
public class UIEntity extends EntityContainer {
/**
* Serial key
*/
private static final long serialVersionUID = -4301991704266922108L;
protected boolean fFocused = false;
protected boolean fCapturing = false;
protected boolean fHovering = false;
protected boolean fEnabled = true;
public void handleUIMouseEvent(String type, Vector2f local, MouseEvent event) {
if (!fEnabled) return;
fDispatcher.dispatchEvent(type, event);
// Iterate through children
Iterator<Entity> it = fChildren.descendingIterator();
boolean clickThrough = true;
while (it.hasNext()) {
Entity e = it.next();
// Ensure we haven't cleaned up this entity
if (id() == -1) return;
if (e.id() == -1) continue;
// Try
if (e instanceof UIEntity) {
UIEntity u = (UIEntity) e;
Vector2f pos = new Vector2f(local.x - u.position().x, local.y - u.position().y);
if (type.equals("mouse.down")) {
if (u.capturePoint(type, pos, event)) {
if (clickThrough) {
if (!u.fFocused) u.focus();
u.captureStart();
u.handleUIMouseEvent(type, pos, event);
}
if (u.greedyCapture(type, pos, event)) clickThrough = false;
} else if (u.fFocused) {
u.blur();
u.handleUIMouseEvent("blur", pos, event);
}
} else if (type.equals("mouse.up")) {
u.handleUIMouseEvent(type, pos, event);
if (u.fCapturing && u.id() >= 0) {
u.handleUIMouseEvent("mouse.click", pos, event);
u.captureEnd();
}
} else if (type.equals("mouse.drag")) {
if (u.fCapturing) {
u.handleUIMouseEvent(type, pos, event);
} else if (u.capturePoint(type, pos, event)) {
u.handleUIMouseEvent("mouse.move", pos, event);
}
} else if (type.equals("mouse.move")) {
if (u.fHovering && !u.capturePoint(type, pos, event)) {
u.hoverOut();
u.handleUIMouseEvent(type, pos, event);
} else if (u.capturePoint(type, pos, event)) {
if (!u.fHovering) u.hoverOver();
u.handleUIMouseEvent(type, pos, event);
}
} else if (type.equals("blur")) {
if (u.fFocused && !u.capturePoint(type, pos, event)) {
u.blur();
u.handleUIMouseEvent("blur", pos, event);
}
}
}
}
}
public boolean greedyCapture(String type, Vector2f v, MouseEvent event) {
return true;
}
public boolean capturePoint(String type, Vector2f v, MouseEvent event) {
if (fSpan == null) return false;
return (v.x < fSpan.getMaxX() + 1 && v.y < fSpan.getMaxY() + 1 && v.x >= fSpan.getX() && v.y >= fSpan.getY());
}
public void enable() {
fEnabled = true;
}
public void disable() {
fEnabled = false;
}
public boolean enabled() {
return fEnabled;
}
public void focus() {
fFocused = true;
}
public void blur() {
fFocused = false;
}
public void hoverOver() {
fHovering = true;
}
public void hoverOut() {
fHovering = false;
}
public void captureStart() {
fCapturing = true;
}
public void captureEnd() {
fCapturing = false;
}
public boolean capturing() {
return fCapturing;
}
public boolean focused() {
return fFocused;
}
public boolean hovering() {
return fHovering;
}
@Override
public void cleanup() {
disable();
super.cleanup();
}
@Override
public UIEntity resize(Vector2f span) {
fSpan = new Rectangle(0, 0, span.x, span.y);
return this;
}
}