diff --git a/examples/src/Program.bf b/examples/src/Program.bf index 7b9bb81..2f15680 100644 --- a/examples/src/Program.bf +++ b/examples/src/Program.bf @@ -34,68 +34,24 @@ class MainScreen : Screen AddChild("Toolbar", toAdd); AddChild("Button", new Button(new (val) => {Console.WriteLine("Hellau :)");})); + AddChild("Label", new Label("LMAO")); + AddChild("CBox", new Checkbox("Box")); + RadioButton r = new .(); + r.Label.Add(new .("One")); + r.Label.Add(new .("Two")); + r.Label.Add(new .("Three")); + AddChild("radio", r); Layout = new (val, width) => { val.Component("Toolbar"); + val.Component("Label", 10); + val.Linebreak(); val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - val.Component("Button"); - - + val.Component("CBox", 5); + val.Linebreak(); + val.Component("radio"); }; } } diff --git a/src/Components/Checkbox.bf b/src/Components/Checkbox.bf new file mode 100644 index 0000000..59a3fb5 --- /dev/null +++ b/src/Components/Checkbox.bf @@ -0,0 +1,73 @@ +namespace TheaterGui.Components; +using TheaterGui.Core; +using TheaterGui.Core.Structs; + +using System; +using System.Collections; + +class Checkbox : Component +{ + private bool _Hovered = false; + private bool _AlreadyHovered = false; + + public String Label ~ delete _; + public bool Checked = false; + + public this(StringView pName) + { + Label = new .(pName); + } + + public override void Update(TGRuntime rt) + { + if(_Hovered != _AlreadyHovered) + { + _Hovered = _AlreadyHovered; + rt.Dirty(); + } + _AlreadyHovered = false; + } + + public override void Draw(TGRuntime rt, rect rect) + { + var textureSize = rt.Platform.MeasureTextureSize("Checkbox"); + if(!Checked) + rt.Platform.DrawTexture("Checkbox", .() {x = rect.x, y = rect.y, width = textureSize[0], height = textureSize[1]}, rt.Scheme.PrimaryColor); + else + rt.Platform.DrawTexture("Checkbox_Checked", .() {x = rect.x, y = rect.y, width = textureSize[0], height = textureSize[1]}, rt.Scheme.PrimaryColor); + + if(_Hovered) + rt.Platform.DrawTexture("Checkbox", .() {x = rect.x, y = rect.y, width = textureSize[0], height = textureSize[1]}, rt.Scheme.HoverColor); + + var tsize = rt.Platform.MeasureTextSize(Label, "Font_Normal"); + rt.Platform.DrawText(Label, "Font_Normal", + .(rect.x + textureSize[0] + 5 + ,(.)(rect.y + 0.5*rect.height - tsize[1]*0.5)) + ,rt.Scheme.TextColor); + } + + public override int32[2] Resize(TGRuntime rt, int32 width) + { + var textureSize = rt.Platform.MeasureTextureSize("Checkbox"); + var tsize = rt.Platform.MeasureTextSize(Label, "Font_Normal"); + textureSize[0] += 5 + tsize[0]; + if(tsize[1] > textureSize[1]) + textureSize[1] = tsize[1]; + return textureSize; + } + + public override bool OnHover(TGRuntime rt, int32[2] mPos) + { + _AlreadyHovered = true; + return true; + } + + public override bool OnLeftClick(TGRuntime rt, int32[2] mPos) + { + Checked = !Checked; + return true; + } + + public override bool OnScroll(TGRuntime rt, float pOffset) => false; + public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => false; +} \ No newline at end of file diff --git a/src/Components/Label.bf b/src/Components/Label.bf new file mode 100644 index 0000000..d9b95dd --- /dev/null +++ b/src/Components/Label.bf @@ -0,0 +1,40 @@ +namespace TheaterGui.Components; +using TheaterGui.Core; +using TheaterGui.Core.Structs; + +using System; +using System.Collections; + +class Label : Component +{ + public String Label = null ~ delete _; + + public this(StringView pLabel) + { + Label = new .(pLabel); + } + + public override void Update(TGRuntime rt) + { + + } + + public override void Draw(TGRuntime rt, rect rect) + { + rt.Platform.DrawText(Label, "Font_Normal", .(rect.x, rect.y), rt.Scheme.TextColor); + } + + public override int32[2] Resize(TGRuntime rt, int32 width) + { + var s = rt.Platform.MeasureTextSize(Label, "Font_Normal"); + return .(s[0], s[1]); + } + + public override bool OnHover(TGRuntime rt, int32[2] mPos) => false; + + public override bool OnLeftClick(TGRuntime rt, int32[2] mPos) => false; + + public override bool OnScroll(TGRuntime rt, float pOffset) => false; + + public override bool OnRightClick(TGRuntime rt, int32[2] mPos, List<(String, delegate void(TGRuntime))> pList) => true; +} \ No newline at end of file diff --git a/src/Components/RadioButton.bf b/src/Components/RadioButton.bf new file mode 100644 index 0000000..a1327a4 --- /dev/null +++ b/src/Components/RadioButton.bf @@ -0,0 +1,103 @@ +namespace TheaterGui.Components; +using TheaterGui.Core; +using TheaterGui.Core.Structs; + +using System; +using System.Collections; + +class RadioButton : Component +{ + private int32 _Checked = 0; + private int32 _Hovered = -1; + private int32 _AlreadyHovered = -1; + + public List Label = new .() ~ DeleteContainerAndItems!(_); + + public this() + { + } + + public override void Update(TGRuntime rt) + { + if(_Hovered != _AlreadyHovered) + { + _Hovered = _AlreadyHovered; + rt.Dirty(); + } + _AlreadyHovered = -1; + } + + public override void Draw(TGRuntime rt, rect rect) + { + int32 startingY = 0; + var textureSize = rt.Platform.MeasureTextureSize("Checkbox"); + for(var i in Label) + { + if(!(_Checked == (.)@i.Index)) + rt.Platform.DrawTexture("Checkbox", .() {x = rect.x, y = rect.y + startingY, width = textureSize[0], height = textureSize[1]}, rt.Scheme.PrimaryColor); + else + rt.Platform.DrawTexture("Checkbox_Checked", .() {x = rect.x, y = rect.y + startingY, width = textureSize[0], height = textureSize[1]}, rt.Scheme.PrimaryColor); + + if(_Hovered == @i.Index) + rt.Platform.DrawTexture("Checkbox", .() {x = rect.x, y = rect.y + startingY, width = textureSize[0], height = textureSize[1]}, rt.Scheme.HoverColor); + + var tsize = rt.Platform.MeasureTextSize(i, "Font_Normal"); + rt.Platform.DrawText(i, "Font_Normal", + .(rect.x + textureSize[0] + 5 + ,(.)(rect.y + 0.5*textureSize[1] - tsize[1]*0.5 + startingY)) + ,rt.Scheme.TextColor); + + startingY += textureSize[1]; + } + } + + + public override int32[2] Resize(TGRuntime rt, int32 width) + { + var textureSize = rt.Platform.MeasureTextureSize("Checkbox"); + int32 xAddition = 0; + for(var label in Label) + { + var tsize = rt.Platform.MeasureTextSize(label, "Font_Normal"); + if(tsize[0] + 5 < xAddition) + xAddition = tsize[0] + 5; + textureSize[1] += rt.Platform.MeasureTextureSize("Checkbox")[1]; + } + + textureSize[0] += xAddition; + return textureSize; + } + + private int32 GetSelectedItem(TGRuntime rt, int32[2] mPos) + { + int32 startingY = 0; + int32 itemHeight = rt.Platform.MeasureTextureSize("Checkbox")[1]; + for(var i in Label) + { + if(mPos[1] >= startingY && mPos[1] < startingY + itemHeight) + { + var textSize = rt.Platform.MeasureTextSize(i, "Font_Normal"); + if(mPos[0] <= rt.Platform.MeasureTextureSize("Checkbox")[0] + 5 + textSize[0]) + return (.)@i.Index; + } + startingY += itemHeight; + } + + return -1; + } + + public override bool OnHover(TGRuntime rt, int32[2] mPos) + { + _AlreadyHovered = GetSelectedItem(rt, mPos); + return true; + } + + public override bool OnLeftClick(TGRuntime rt, int32[2] mPos) + { + _Checked = GetSelectedItem(rt, mPos); + return true; + } + + public override bool OnScroll(TGRuntime rt, float pOffset) => false; + public override bool OnRightClick(TGRuntime rt, int32[2] mPos, System.Collections.List<(String, delegate void(TGRuntime))> pList) => false; +} diff --git a/src/Core/EventSystem.bf b/src/Core/EventSystem.bf new file mode 100644 index 0000000..3942da1 --- /dev/null +++ b/src/Core/EventSystem.bf @@ -0,0 +1,59 @@ +namespace TheaterGui.Core; + +using System; +using System.Collections; + +class EventSystem +{ + private Dictionary> _Events = new .() ~ delete _; + private uint64 _Id = 0; + + public ~this() + { + for(var i in _Events) + { + delete i.key; + for(var j in i.value) + delete j.1; + delete i.value; + } + } + + ///Invoke a event, conditionally pass in a event object, and return the amount of events called + public int32 Invoke(StringView name, void* obj) + { + if(!_Events.ContainsKeyAlt(name)) + return -1; + int32 toReturn = 0; + for(var i in _Events[scope .(name)]) + { + i.1(obj); + toReturn++; + } + return toReturn; + } + + ///Returns the deregistration id to be used when deregistering + public uint64 Register(StringView name, delegate void(void*) func) + { + if(!_Events.ContainsKeyAlt(name)) + _Events.Add(new .(name), new .()); + _Events[scope .(name)].Add((_Id+1, func)); + _Id++; + return _Id; + } + + public void DeRegister(StringView name, uint64 id) + { + if(!_Events.ContainsKeyAlt(name)) + return; + for(var i in _Events[scope .(name)]) + { + if(i.0 == id) + { + delete i.1; + @i.Remove(); + } + } + } +} \ No newline at end of file diff --git a/src/Core/Structs/theme.bf b/src/Core/Structs/theme.bf index 6e00e8d..ae45916 100644 --- a/src/Core/Structs/theme.bf +++ b/src/Core/Structs/theme.bf @@ -6,20 +6,20 @@ struct theme { private static uint8[?] _Theme_Font = Compiler.ReadBinary("assets/Din.ttf"); private static uint8[?] _Theme_Button = Compiler.ReadBinary("assets/button.png"); + private static uint8[?] _Theme_Checkbox = Compiler.ReadBinary("assets/checkbox.png"); + private static uint8[?] _Theme_Checkbox_Checked = Compiler.ReadBinary("assets/checkbox_checked.png"); /* private static uint8[?] Texture_SquareButton = Compiler.ReadBinary("assets/square_button.png"); private static uint8[?] Texture_LargeButton = Compiler.ReadBinary("assets/large_button.png"); private static uint8[?] Texture_NButton = Compiler.ReadBinary("assets/n_button.png"); - private static uint8[?] Texture_Checkbox = Compiler.ReadBinary("assets/checkbox.png"); - private static uint8[?] Texture_Checkbox_Checked = Compiler.ReadBinary("assets/checkbox_checked.png"); + private static uint8[?] Horizontal_Patch = Compiler.ReadBinary("assets/horizontal_patch.png"); private static uint8[?] Dropdown = Compiler.ReadBinary("assets/dropdown.png"); */ - public (Span, uint8) Font_Normal = ( - .(&_Theme_Font, _Theme_Font.Count), - 16 - ); + public (Span, uint8) Font_Normal = (.(&_Theme_Font, _Theme_Font.Count),16); public Span Button = .(&_Theme_Button, _Theme_Button.Count); + public Span Checkbox = .(&_Theme_Checkbox, _Theme_Checkbox.Count); + public Span Checkbox_Checked = .(&_Theme_Checkbox_Checked, _Theme_Checkbox_Checked.Count); } \ No newline at end of file diff --git a/src/Core/TGRuntime.api.bf b/src/Core/TGRuntime.api.bf index 54e2ddb..df19cfb 100644 --- a/src/Core/TGRuntime.api.bf +++ b/src/Core/TGRuntime.api.bf @@ -7,6 +7,8 @@ using System.Collections; extension TGRuntime { + public EventSystem Events = new .() ~ delete _; + public theme Theme; public colorScheme Scheme;; diff --git a/src/Core/TGRuntime.core.bf b/src/Core/TGRuntime.core.bf index 7f00cd5..2a2a081 100644 --- a/src/Core/TGRuntime.core.bf +++ b/src/Core/TGRuntime.core.bf @@ -119,6 +119,9 @@ class TGRuntime Platform.ChangeBackgroundColor(pScheme.BackgroundColor); Platform.LoadFont(pStartingTheme.Font_Normal.0, "Font_Normal", pStartingTheme.Font_Normal.1); Platform.LoadTexture(pStartingTheme.Button, "Button"); + Platform.LoadTexture(pStartingTheme.Checkbox, "Checkbox"); + Platform.LoadTexture(pStartingTheme.Checkbox_Checked, "Checkbox_Checked"); + } private void OpenRightClickPopup(TGRuntime rt, int32[2] pos, List<(String, delegate void(TGRuntime))> data) diff --git a/src/TODO b/src/TODO new file mode 100644 index 0000000..bb05c1c --- /dev/null +++ b/src/TODO @@ -0,0 +1,18 @@ +TODO: +TabbedContainers +Fixed size containers +Collapseables +Dropdown +Textfields +Textboxes +TextDisplays +Icon buttons +Horizontal sliders +Vertical sliders +Code cleanup + + +Being Worked on: + +Done +Radio Buttons \ No newline at end of file