Skip to content

Instantly share code, notes, and snippets.

@unstoppablecarl
Created February 11, 2013 18:49
Show Gist options
  • Save unstoppablecarl/4756595 to your computer and use it in GitHub Desktop.
Save unstoppablecarl/4756595 to your computer and use it in GitHub Desktop.
ig.module(
'plugins.gui'
)
.requires(
'impact.game',
'impact.system'
)
.defines(function () {
// Create GUI container
ig.gui = {
initialized : false,
elements: [],
elementsByName: {},
hovered: false,
add:function(button){
this.elements.push(button);
this.elementsByName[button.name] = button;
},
getByName: function(name){
return this.elementsByName[name];
},
update:function(){
this.hovered = false;
for (var i = 0, len = this.elements.length; i < len; i++) {
this.elements[i].update();
}
},
draw:function(){
for (var i = 0, len = this.elements.length; i < len; i++) {
this.elements[i].draw();
}
}
}
ig.gui.Element = ig.Class.extend({
name: null,
group: null,
// if visible button will be rendered
visible : true,
// show disabled state of button
disabled: false,
// keyboard key to bind, functions same as mouse click
keybind: null,
selected: false,
// states can contain any settings to override for that state
states: {
idle: {
size: {
x: 16,
y: 16
},
offset: {
x: 0,
y: 0
},
pos: {
x: 0,
y:0,
// if true, x will be set relative to the right edge of the game canvas
relativeToRight: false,
// if true y will be set relative tot he bottom edge of the game canvas
relativeToBottom: false
},
// padding to be added around text vertically and horizontally
padding: {
enabled:true,
top: 0,
right: 0,
bottom: 0,
left: 0
},
bar: {
active: false,
size: {
x: 0,
y: 0
},
pos: {
x: 0,
y: 0
},
backgroundColor : null
},
/**
* select a source to set the width / height from: null, 'text', 'image' (overrides this.size)
* text: generated automatically from text width / height
* image : generated automatically from text width / height
*/
autoSetWidthFrom: null,
autoSetHeightFrom: null,
showImage: true,
image: null,
zIndex: 0,
backgroundColor: null,
showBorder: true,
borderColor: null,
borderWidth: 1,
showText: true,
text: null,
font: new ig.Font( 'media/verdana.font.png' ),
textAlign: ig.Font.ALIGN
},
hover: {},
click: {},
disabled: {}
},
prevTickState: null,
// name of current state
state: 'idle',
// current state data merged with idle state data
stateData: {},
// functions to call on events
events: {
idle: null,
hover:null,
click:null
},
init: function(settings) {
ig.merge(this, settings);
this.setState('idle');
},
mouseOver:function(x, y, width, height){
var mx = ig.input.mouse.x,
my = ig.input.mouse.y,
x = x || this.getPosX(),
y = y || this.getPosY(),
width = width || this.getWidth(),
height = height || this.getHeight();
return (mx >= x && mx <= x + width && my >= y && my <= y + height && !this.disabled);
},
click:function(){
return ((ig.input.state('leftMouse') || ig.input.pressed('leftMouse'))) || (ig.input.pressed(this.keybind));
},
beforeUpdate:function(){
},
isSelected: function(){
return this.selected;
},
update:function(){
this.beforeUpdate();
if(!this.state || !this.stateData){
this.setState('idle');
}
var mouseOver = this.mouseOver(),
click = this.click();
if(mouseOver){
ig.gui.hovered = true;
}
if (this.isSelected()){
this.state = 'selected';
}
else if(this.disabled){
this.state = 'disabled';
} else if(mouseOver && click){
this.state = 'click';
} else if(mouseOver){
this.state = 'hover';
} else {
this.state = 'idle';
}
// state changed
if(this.prevTickState != this.state){
this.setState(this.state);
// fire events
if(this.events[this.state]){
var eventFunc = this.events[this.state];
eventFunc.call(this);
}
}
this.prevTickState = this.state;
},
clearState: function(){
this.state = null;
this.stateData = null;
},
setState: function(state){
this.state = state;
// copy idle props as default values to stateData
this.stateData = ig.copy(this.states.idle);
if(state != 'idle'){
// override idle state data with current state data
var x = ig.copy(this.states[state]);
this.stateData = ig.merge(this.stateData, x);
}
},
getPosX:function(considerSystemScale){
considerSystemScale = considerSystemScale || true;
var x = this.stateData.pos.x;
if(considerSystemScale){
x *= ig.system.scale;
}
if(this.stateData.pos.relativeToRight){
var systemWidth = ig.system.width;
if(considerSystemScale){
systemWidth *= ig.system.scale;
}
x += systemWidth;
}
return x;
},
getPosY:function(considerSystemScale){
considerSystemScale = considerSystemScale || true;
var y = this.stateData.pos.y;
if(considerSystemScale){
y *= ig.system.scale;
}
if(this.stateData.pos.relativeToBottom){
var systemHeight = ig.system.height;
if(considerSystemScale){
systemHeight *= ig.system.scale;
}
y += systemHeight;
}
return y;
},
getWidth: function(){
var state = this.stateData,
width = state.size.x;
if(state.autoSetWidthFrom == 'text'){
width = state.font.widthForString(state.text);
}
if(state.padding.enabled){
width += state.padding.left;
width += state.padding.right;
}
if(state.autoSetWidthFrom == 'image'){
width = state.image.width;
}
return width;
},
getHeight: function(){
var state = this.stateData,
height = state.size.y;
if(state.autoSetHeightFrom == 'text'){
height = state.font.heightForString(state.text);
}
if(state.padding.enabled){
height += state.padding.top;
height += state.padding.bottom;
}
if(state.autoSetHeightFrom == 'image'){
height = state.image.height;
}
return height;
},
draw:function(){
var visible = this.visible;
if(typeof this.visible == 'function'){
visible = this.visible();
}
if(!visible){
return;
}
var state = this.stateData;
var width = this.getWidth() * ig.system.scale,
height = this.getHeight() * ig.system.scale,
x = this.getPosX(),
y = this.getPosY();
if(state.backgroundColor){
ig.system.context.fillStyle = state.backgroundColor;
ig.system.context.fillRect(x, y, width, height);
}
if(state.showImage && state.image && 'draw' in state.image){
state.image.draw(x, y);
}
if(state.showBorder && state.borderColor && state.borderWidth){
var borderWidth = state.borderWidth * ig.system.scale;
ig.system.context.lineWidth = borderWidth;
ig.system.context.strokeStyle = state.borderColor;
var strokeX = x + borderWidth / 2,
strokeY = y + borderWidth / 2,
strokeW = width - borderWidth,
strokeH = height - borderWidth;
ig.system.context.strokeRect(strokeX, strokeY, strokeW, strokeH);
}
if(state.bar && state.bar.active){
ig.system.context.fillStyle = state.bar.backgroundColor;
ig.system.context.fillRect(x + state.bar.pos.x, y + state.bar.pos.y, state.bar.size.x, state.bar.size.y);
}
if (state.showText && state.font && state.text) {
var textPosX = this.getPosX(false);
if(state.padding.enabled){
textPosX += state.padding.left;
}
var textPosY = this.getPosY(false);
if(state.padding.enabled){
textPosY += state.padding.top;
}
state.font.draw(state.text, textPosX, textPosY, state.textAlign);
}
}
});
// Initialize and draw
ig.Game.inject({
init: function(settings){
this.parent(settings);
ig.input.bind(ig.KEY.mouse1, 'leftMouse');
ig.gui.Element.states.font = ig.game.font;
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment