372 lines
7.7 KiB
ActionScript
372 lines
7.7 KiB
ActionScript
import elements.BaseGuiElement;
|
|
import elements.GuiSprite;
|
|
|
|
export GuiButton, onButtonClick;
|
|
|
|
interface onButtonClick {
|
|
bool onClick(GuiButton@ btn);
|
|
};
|
|
|
|
class GuiButton : BaseGuiElement {
|
|
string Text;
|
|
FontType TextFont = FT_Button;
|
|
vec2i textOffset;
|
|
vec2i textSize;
|
|
double HorizAlign = 0.5;
|
|
double VertAlign = 0.5;
|
|
bool Pressed = false;
|
|
bool Hovered = false;
|
|
bool Focused = false;
|
|
bool disabled = false;
|
|
bool Toggle = false;
|
|
bool allowOtherButtons = false;
|
|
Color textColor = colors::Invisible;
|
|
Color color;
|
|
Sprite Icon;
|
|
GuiSprite@ fullIcon;
|
|
|
|
onButtonClick@ onClick;
|
|
|
|
SkinStyle style = SS_Button;
|
|
Sprite spriteStyle;
|
|
|
|
GuiButton(IGuiElement@ ParentElement, const recti& Rectangle) {
|
|
super(ParentElement, Rectangle);
|
|
updateAbsolutePosition();
|
|
navigable = true;
|
|
}
|
|
|
|
GuiButton(IGuiElement@ ParentElement, const recti& Rectangle, const string&in DefaultText) {
|
|
super(ParentElement, Rectangle);
|
|
updateAbsolutePosition();
|
|
text = DefaultText;
|
|
navigable = true;
|
|
}
|
|
|
|
GuiButton(IGuiElement@ ParentElement, Alignment@ Align) {
|
|
super(ParentElement, Align);
|
|
updateAbsolutePosition();
|
|
navigable = true;
|
|
}
|
|
|
|
GuiButton(IGuiElement@ ParentElement, Alignment@ Align, const string& DefaultText) {
|
|
super(ParentElement, Align);
|
|
updateAbsolutePosition();
|
|
text = DefaultText;
|
|
navigable = true;
|
|
}
|
|
|
|
GuiButton(IGuiElement@ ParentElement, const recti& Rectangle, const Sprite& sprt) {
|
|
super(ParentElement, Rectangle);
|
|
updateAbsolutePosition();
|
|
setIcon(sprt);
|
|
navigable = true;
|
|
}
|
|
|
|
GuiButton(IGuiElement@ ParentElement, Alignment@ Align, const Sprite& sprt) {
|
|
super(ParentElement, Align);
|
|
updateAbsolutePosition();
|
|
setIcon(sprt);
|
|
navigable = true;
|
|
}
|
|
|
|
GuiButton(bool NoParent) {
|
|
super(NoParent);
|
|
}
|
|
|
|
string get_elementType() const {
|
|
return "button";
|
|
}
|
|
|
|
bool onGuiEvent(const GuiEvent& event) {
|
|
switch(event.type) {
|
|
case GUI_Mouse_Entered:
|
|
if(event.caller is this) {
|
|
if(!skin.isIrregular(style))
|
|
Hovered = true;
|
|
}
|
|
break;
|
|
case GUI_Mouse_Left:
|
|
if(event.caller is this) {
|
|
Hovered = false;
|
|
if(!Toggle)
|
|
Pressed = false;
|
|
}
|
|
break;
|
|
case GUI_Focused:
|
|
Focused = true;
|
|
break;
|
|
case GUI_Focus_Lost:
|
|
if(!isAncestorOf(event.other)) {
|
|
Focused = false;
|
|
if(!Toggle)
|
|
Pressed = false;
|
|
}
|
|
break;
|
|
case GUI_Controller_Down:
|
|
if(event.caller is this) {
|
|
if(event.value == GP_A) {
|
|
if(Toggle) {
|
|
Pressed = !Pressed;
|
|
emitClick();
|
|
}
|
|
else {
|
|
Pressed = true;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
case GUI_Controller_Up:
|
|
if(Focused) {
|
|
if(event.value == GP_A) {
|
|
if(Pressed && !Toggle) {
|
|
Pressed = false;
|
|
emitClick();
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return BaseGuiElement::onGuiEvent(event);
|
|
}
|
|
|
|
void emitClick(int btn = 0) {
|
|
if(onClick !is null && onClick.onClick(this))
|
|
return;
|
|
GuiEvent evt;
|
|
evt.type = GUI_Clicked;
|
|
@evt.caller = this;
|
|
evt.value = btn;
|
|
onGuiEvent(evt);
|
|
}
|
|
|
|
bool onMouseEvent(const MouseEvent& event, IGuiElement@ source) {
|
|
if(source is this || source.isChildOf(this)) {
|
|
if(disabled) {
|
|
if(event.type == MET_Button_Down && (event.button == 0 || allowOtherButtons))
|
|
return true;
|
|
if(event.type == MET_Button_Up && (event.button == 0 || allowOtherButtons)) {
|
|
sound::error.play(priority=true);
|
|
return true;
|
|
}
|
|
}
|
|
else switch(event.type) {
|
|
case MET_Moved:
|
|
if(skin.isIrregular(style)) {
|
|
if(AbsolutePosition.isWithin(mousePos)) {
|
|
Hovered = skin.isPixelActive(
|
|
style, flags, AbsolutePosition,
|
|
mousePos - AbsolutePosition.topLeft);
|
|
}
|
|
}
|
|
break;
|
|
case MET_Button_Down:
|
|
if(!Hovered)
|
|
return true;
|
|
if(event.button == 0 || allowOtherButtons) {
|
|
if(Toggle) {
|
|
Pressed = !Pressed;
|
|
emitClick(event.button);
|
|
}
|
|
else {
|
|
Pressed = true;
|
|
}
|
|
return true;
|
|
}
|
|
break;
|
|
case MET_Button_Up:
|
|
if(Focused) {
|
|
if(event.button == 0 || allowOtherButtons) {
|
|
if(Pressed && !Toggle) {
|
|
Pressed = false;
|
|
if(Hovered)
|
|
emitClick(event.button);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return BaseGuiElement::onMouseEvent(event, source);
|
|
}
|
|
|
|
bool onKeyEvent(const KeyboardEvent& event, IGuiElement@ source) {
|
|
if(source is this || source.isChildOf(this)) {
|
|
if(disabled) {
|
|
if(event.key == KEY_ENTER) {
|
|
if(event.type == KET_Key_Up) {
|
|
sound::error.play(priority=true);
|
|
return true;
|
|
}
|
|
else if(event.type == KET_Key_Down) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
else switch(event.type) {
|
|
case KET_Key_Down:
|
|
if(event.key == KEY_ENTER) {
|
|
if(Toggle) {
|
|
Pressed = !Pressed;
|
|
emitClick();
|
|
}
|
|
else {
|
|
Pressed = true;
|
|
}
|
|
return true;
|
|
}
|
|
break;
|
|
case KET_Key_Up:
|
|
if(event.key == KEY_ENTER) {
|
|
if(Pressed && !Toggle) {
|
|
Pressed = false;
|
|
emitClick();
|
|
}
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return BaseGuiElement::onKeyEvent(event, source);
|
|
}
|
|
|
|
void set_horizAlign(double align) {
|
|
HorizAlign = align;
|
|
centerText();
|
|
}
|
|
|
|
void set_vertAlign(double align) {
|
|
VertAlign = align;
|
|
centerText();
|
|
}
|
|
|
|
void centerText() {
|
|
const Font@ font = skin.getFont(TextFont);
|
|
vec2i textSize = font.getDimension(Text);
|
|
int metric = min(size.height - 6, textSize.y + 8);
|
|
|
|
if(Icon.valid)
|
|
textSize.x += metric + 6;
|
|
textOffset = Position.size - textSize;
|
|
textOffset.x = double(textOffset.x - 8) * HorizAlign + 4;
|
|
textOffset.y = double(textOffset.y) * VertAlign;
|
|
textOffset.y += (textSize.y - font.getBaseline()) / 2;
|
|
if(Icon.valid)
|
|
textOffset.x += metric + 4;
|
|
}
|
|
|
|
void set_font(FontType type) {
|
|
if(TextFont == type)
|
|
return;
|
|
TextFont = type;
|
|
centerText();
|
|
}
|
|
|
|
void set_buttonIcon(const Sprite& sprt) {
|
|
Icon = sprt;
|
|
centerText();
|
|
}
|
|
|
|
GuiSprite@ setIcon(const Sprite& sprt, int padding = 5) {
|
|
if(Text.length != 0) {
|
|
buttonIcon = sprt;
|
|
return null;
|
|
}
|
|
else {
|
|
if(!sprt.valid) {
|
|
if(fullIcon !is null)
|
|
fullIcon.remove();
|
|
return null;
|
|
}
|
|
if(fullIcon is null)
|
|
@fullIcon = GuiSprite(this, Alignment().padded(padding));
|
|
fullIcon.desc = sprt;
|
|
return fullIcon;
|
|
}
|
|
}
|
|
|
|
void set_text(const string& text) {
|
|
Text = text;
|
|
centerText();
|
|
}
|
|
|
|
string get_text() {
|
|
return Text;
|
|
}
|
|
|
|
vec2i get_textSize() {
|
|
const Font@ font = skin.getFont(TextFont);
|
|
return font.getDimension(Text);
|
|
}
|
|
|
|
void set_toggleButton(bool t) {
|
|
Toggle = t;
|
|
Pressed = false;
|
|
}
|
|
|
|
bool get_toggleButton() {
|
|
return Toggle;
|
|
}
|
|
|
|
bool get_pressed() {
|
|
return Toggle ? Pressed : false;
|
|
}
|
|
|
|
void set_pressed(bool p) {
|
|
if(Toggle)
|
|
Pressed = p;
|
|
}
|
|
|
|
void updateAbsolutePosition() {
|
|
BaseGuiElement::updateAbsolutePosition();
|
|
|
|
if(Text.length() > 0)
|
|
centerText();
|
|
}
|
|
|
|
uint get_flags() {
|
|
uint flags = SF_Normal;
|
|
if(disabled)
|
|
flags |= SF_Disabled;
|
|
if(Pressed)
|
|
flags |= SF_Active;
|
|
if(Hovered)
|
|
flags |= SF_Hovered;
|
|
if(Focused)
|
|
flags |= SF_Focused;
|
|
return flags;
|
|
}
|
|
|
|
void draw() {
|
|
if(spriteStyle.valid) {
|
|
spriteStyle.index = 0;
|
|
if(Hovered)
|
|
spriteStyle.index = 1;
|
|
spriteStyle.draw(AbsolutePosition, color);
|
|
}
|
|
else {
|
|
skin.draw(style, flags, AbsolutePosition, color);
|
|
}
|
|
|
|
Color textCol = textColor;
|
|
if(textCol.a == 0) {
|
|
if(disabled)
|
|
textCol = skin.getColor(SC_Disabled);
|
|
else
|
|
textCol = skin.getColor(SC_ButtonText);
|
|
}
|
|
|
|
if(Icon.valid) {
|
|
int metric = min(size.height - 6, textSize.y + 8);
|
|
recti pos = recti_area(AbsolutePosition.topLeft +
|
|
vec2i(textOffset.x - metric - 6, (AbsolutePosition.height - metric) / 2 + 1 ), vec2i(metric, metric));
|
|
Icon.draw(pos);
|
|
}
|
|
skin.draw(TextFont, AbsolutePosition.topLeft + textOffset, Text, textCol);
|
|
BaseGuiElement::draw();
|
|
}
|
|
};
|