Turtle programming game that was never finished to a playable state (but had cute graphics and sounds)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tortuga/src/net/tortuga/gui/widgets/GuiRoot.java

374 lines
6.7 KiB

package net.tortuga.gui.widgets;
import static net.tortuga.util.Align.*;
import static org.lwjgl.opengl.GL11.*;
import java.util.HashSet;
import java.util.Set;
import net.tortuga.App;
import net.tortuga.fonts.Fonts;
import net.tortuga.fonts.LoadedFont;
import net.tortuga.gui.panels.Panel;
import net.tortuga.gui.widgets.layout.Gap;
import net.tortuga.util.Align;
import org.lwjgl.input.Mouse;
import com.porcupine.color.RGB;
import com.porcupine.coord.Coord;
/**
* Root widget, container of layouts
*
* @author Ondřej Hruška (MightyPork)
*/
public class GuiRoot implements Comparable<GuiRoot> {
/**
* Widget event listener
*
* @author Ondřej Hruška (MightyPork)
*/
public static interface EventListener {
/**
* On action performed - button clicked etc.
*
* @param widget widget responsible for the event.
*/
public void actionPerformed(Widget widget);
}
public double renderIndex = 0;
private Set<IRefreshable> needingRefresh = new HashSet<IRefreshable>();
/** root child */
public Widget child = new Gap(0, 0);
/** focused widget */
public Widget focus = null;
/** event listener */
public EventListener listener = null;
/** Horizontal align to window */
public int alignH = CENTER;
/** Vertical align to window */
public int alignV = CENTER;
private Panel panel;
private String tooltipText = "";
private RGB tooltipColor = RGB.WHITE;
private boolean tooltipShown = false;
/**
* Set rendering index
*
* @param index index
* @return this
*/
public GuiRoot setRenderIndex(double index)
{
this.renderIndex = index;
return this;
}
public void scheduleRefresh(IRefreshable w)
{
needingRefresh.add(w);
}
public void clearTooltip()
{
tooltipShown = false;
}
public void setTooltip(String text, RGB color)
{
tooltipText = text.trim();
tooltipColor = color;
tooltipShown = true;
}
/**
* Gui widget root element
*
* @param listener listener - for widget events
* @param child root child (a layout)
*/
public GuiRoot(EventListener listener, Widget child) {
this.listener = listener;
this.child = child;
if (listener instanceof Panel) panel = (Panel) listener;
}
public GuiRoot setParentPanel(Panel p)
{
this.panel = p;
return this;
}
public boolean isPanelOnTop()
{
return panel.isFocused();
}
/**
* Add primary child
*
* @param layout
*/
public void setRootWidget(Widget layout)
{
this.child = layout;
}
/**
* Set alignment relative to window; Use constants from Align class.
*
* @param horizontal horizontal align
* @param vertical vertical align
* @return this
*/
public GuiRoot setAlign(int horizontal, int vertical)
{
alignH = horizontal;
alignV = vertical;
return this;
}
/**
* Set alignment relative to window; Use constants from Align class.
*
* @param horizontal horizontal align
* @return this
*/
public GuiRoot setAlignH(int horizontal)
{
alignH = horizontal;
return this;
}
/**
* Set alignment relative to window; Use constants from Align class.
*
* @param vertical vertical align
* @return this
*/
public GuiRoot setAlignV(int vertical)
{
alignV = vertical;
return this;
}
/**
* Do render - centered on screen.
*/
public void render()
{
clearTooltip();
glPushMatrix();
Coord lower = getLowerPoint();
glTranslated(lower.x, lower.y, 0);
glPushMatrix();
child.render(getRelativeMousePos());
glPopMatrix();
if (tooltipShown && isPanelOnTop()) {
Coord mouse = getRelativeMousePos();
LoadedFont font = Fonts.tooltip;
RGB shadowC = new RGB(0, 0.2);
int width = font.getWidth(tooltipText);
int h = font.getHeight();
if (Mouse.getX() + 20 + width + 100 > App.inst.getSize().x) {
Coord pos = mouse.add(-20, -10 - (h / 2), 60);
font.drawFuzzy(pos, tooltipText, Align.RIGHT, tooltipColor, shadowC, 2);
} else {
Coord pos = mouse.add(20, -10 - (h / 2), 60);
font.drawFuzzy(pos, tooltipText, Align.LEFT, tooltipColor, shadowC, 2);
}
}
glPopMatrix();
}
private Coord getRelativeMousePos()
{
Coord lower = getLowerPoint();
return new Coord(Mouse.getX() - lower.x, Mouse.getY() - lower.y);
}
/**
* Get lower point of this root widget - base for relative coordinates.
*
* @return lower coord.
*/
private Coord getLowerPoint()
{
Coord cSize = child.getSize();
Coord wSize = App.inst.getSize();
Coord lower = new Coord();
switch (alignH) {
case LEFT:
lower.x = child.margins.left;
break;
case CENTER:
lower.x = (wSize.x - cSize.x) / 2;
break;
case RIGHT:
lower.x = wSize.x - cSize.x - child.margins.right;
break;
}
switch (alignV) {
case BOTTOM:
lower.y = child.margins.bottom;
break;
case CENTER:
lower.y = (wSize.y - cSize.y) / 2;
break;
case TOP:
lower.y = wSize.y - cSize.y - child.margins.top;
break;
}
return lower;
}
/**
* Remove old focus and focus given widget.
*
* @param newFocus widget to focus or null.
*/
public void setFocus(Widget newFocus)
{
if (focus != null) {
focus.focused = false;
focus.onBlur();
}
focus = newFocus;
if (focus != null) {
focus.focused = true;
focus.onFocus();
}
}
/**
* Handle mouse button
*
* @param button button id
* @param down is down
*/
public void onMouseButton(int button, boolean down)
{
Widget consumer = child.onMouseButton(getRelativeMousePos(), button, down);
if (consumer != focus && down) {
setFocus(consumer);
}
if (consumer != null) listener.actionPerformed(consumer);
}
/**
* handle mouse scroll
*
* @param scroll -1,0,1
*/
public void onScroll(int scroll)
{
Widget consumer = child.onScroll(getRelativeMousePos(), scroll);
if (consumer != focus && consumer != null) {
setFocus(consumer);
}
if (consumer != null) listener.actionPerformed(consumer);
}
/**
* handle key press
*
* @param key key index
* @param chr character typed
* @param down
*/
public void onKeyDown(int key, char chr, boolean down)
{
Widget consumer = child.onKey(key, chr, down);
if (consumer != focus && consumer != null) {
setFocus(consumer);
}
if (consumer != null) listener.actionPerformed(consumer);
}
/**
* Handle analog inputs
*/
public void handleStaticInputs()
{
child.handleStaticInputs(getRelativeMousePos());
}
/**
* Recalculate children positions and sizes.
*/
public void updatePositions()
{
for (IRefreshable w : needingRefresh) {
w.refresh();
}
child.setGuiRoot(this);
child.calcChildSizes();
}
/**
* Get the panel.
*
* @return panel
*/
public Panel getPanel()
{
return panel;
}
@Override
public int compareTo(GuiRoot o)
{
return Double.valueOf(renderIndex).compareTo(Double.valueOf(o.renderIndex));
}
}