Open source Star Ruler 2 source code!
This commit is contained in:
@@ -0,0 +1,371 @@
|
||||
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();
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user