Files
starruler-linux/scripts/toolkit/elements/GuiButton.as
T
2018-07-17 14:15:37 +02:00

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();
}
};