From fbbe2b19000748032bb30d6863694f9abf59302d Mon Sep 17 00:00:00 2001 From: Booklordofthedings Date: Fri, 7 Jun 2024 18:05:24 +0200 Subject: [PATCH] scrolling --- src/App.bf | 145 +++++++++++++++++-------------- src/Components/Button.bf | 10 +-- src/Components/Checkbox.bf | 10 +-- src/Components/Component.bf | 2 +- src/Components/Container.bf | 8 +- src/Components/IconButton.bf | 10 +-- src/Components/Label.bf | 6 +- src/Components/LargeButton.bf | 8 +- src/Components/NButton.bf | 10 +-- src/Components/Placeholder.bf | 2 +- src/Components/PopupComponent.bf | 12 +++ src/Components/Toolbar.bf | 19 ++-- src/Components/ToolbarPopup.bf | 69 +++++++++++++-- 13 files changed, 200 insertions(+), 111 deletions(-) create mode 100644 src/Components/PopupComponent.bf diff --git a/src/App.bf b/src/App.bf index 679ecbf..13316fa 100644 --- a/src/App.bf +++ b/src/App.bf @@ -9,7 +9,13 @@ class App { //All loaded textures - private static List Popups = new .() ~ DeleteContainerAndItems!(_); + private static List Popups = new .() ~ DeleteContainerAndItems!(_); + + //For hover items + private static Vector2 oldPos = .(0,0); + private static double movTime = 0; + private static String hoverText = new .() ~ delete _; + public static Textures Textures ~ delete _; public static Component Selected; //Currently selected component public static bool AllowReorder = true; @@ -59,7 +65,7 @@ class App CurrentScreen.Reorder(Width); } - public static void OpenPopup(Component popup) + public static void OpenPopup(PopupComponent popup) { Popups.Add(popup); } @@ -98,85 +104,41 @@ class App ///Start the application on the input stream public static void Start(Screen pScreen) { - Vector2 oldSize = .(0,0); - //For hover items - Vector2 oldPos = .(0,0); - double movTime = 0; - String hoverText = scope .(); - CurrentScreen = pScreen; + Vector2 oldSize = .(0,0); + while(!Raylib.WindowShouldClose()) { if(oldSize != .(Width,Height)) { CurrentScreen.Reorder(Width); - oldSize = .(Width,Height); + oldSize = .(Width,Math.Min(Height, CurrentScreen.Height)); } //This could probably be solved better if(CurrentScreen.Height - Height > 0) { - Wheel = -Wheel; - Wheel += 7 * Raylib.GetMouseWheelMove(); + var w = Raylib.GetMouseWheelMove(); + Wheel += w * w * w; Wheel = Math.Clamp(Wheel, -1*(CurrentScreen.Height - Height), 0); - Wheel = -Wheel; - } - - if(Raylib.IsMouseButtonPressed(0)) - { - if(Popups.Count > 0) - { - var top = Popups[Popups.Count-1]; - if(Rectangle(top.X, top.Y, top.Width, top.Height).Overlaps(Raylib.GetMouseX(), Raylib.GetMouseY())) - top.OnClick(Raylib.GetMouseX(), Raylib.GetMouseY()); - else - { - Popups.Remove(top); - delete top; - - CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()+App.Wheel)); - } - } - else - CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()+App.Wheel)); - } else - { - if(Popups.Count > 0) - { - var top = Popups[Popups.Count-1]; - if(Rectangle(top.X, top.Y, top.Width, top.Height).Overlaps(Raylib.GetMouseX(), Raylib.GetMouseY())) - { + Wheel = 0; - } - } - else - { - var hov = CurrentScreen.OnHover(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()+App.Wheel)); - if(hov != null) - { - if(hov.Enabled) - Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_POINTING_HAND); - //TODO: If we go offscreen with the mouse it doesnt work anymore - if(oldPos != Mouse) - movTime = Raylib.GetTime(); - if(Raylib.GetTime() - movTime >= 0.5) - hoverText.Append(hov.Description); - oldPos = Mouse; - } - else - Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_DEFAULT); - } - } + if(Raylib.IsMouseButtonPressed(0)) + HandleLeftClick(); + else + HandleHover(); //Drawing logic Raylib.BeginDrawing(); Raylib.ClearBackground(Theme.Background); - CurrentScreen.Render(); + + CurrentScreen.Render((.)Wheel); + for(var i in Popups) - i.Render(); + i.Render((.)Wheel); if(hoverText != String.Empty) { //TODO: When you move outside of the window, the hover fucks up @@ -197,6 +159,10 @@ class App Raylib.DrawTextEx(Theme.FontSmall, hoverText, Raymath.Vector2Add(Mouse, .(xOffset,yOffset)), Theme.FontSizeSmall, 0, Raylib.BLACK); } + Raylib.EndTextureMode(); + + + Raylib.EndDrawing(); if(hoverText != String.Empty) @@ -204,14 +170,67 @@ class App } } - ///Checks wether any popup catches the hover, returns wether it has been caught - public bool HandleHoverPopups() + ///Handles the leftclick action + private static void HandleLeftClick() + { + if(Popups.Count > 0) + { //Only checking the topmost popup + var top = Popups[Popups.Count-1]; + if(Rectangle(top.X, top.Y, top.Width, top.Height).Overlaps(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()-Wheel))) + top.OnClick(Raylib.GetMouseX(), Raylib.GetMouseY()); + else + { + Popups.Remove(top); + top.OnClose(); //Any last words ? + delete top; + + CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()-App.Wheel)); //So that we dont eat any inputs + } + } + else + CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()-App.Wheel)); + } + + ///Handles the hovering effect + private static void HandleHover() + { + Component hoverRes = HandleHoverPopups(); + if(hoverRes == null) + hoverRes = HandleHoverScreen(); + + if(hoverRes == null) + Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_DEFAULT); + else + { + if(hoverRes.Enabled) + Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_POINTING_HAND); + + if(oldPos != Mouse) + movTime = Raylib.GetTime(); + if(Raylib.GetTime() - movTime >= 0.5) + hoverText.Append(hoverRes.Description); + oldPos = Mouse; + } + } + + ///Handle the hover effect for all screen objects + private static Component HandleHoverScreen() + { + return CurrentScreen.OnHover(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()-App.Wheel)); + } + + ///Checks if any popup catches the hover + private static Component HandleHoverPopups() { //Topmost first for(var i in Popups.Reversed) { - + var hoverResult = i.OnHover(Raylib.GetMouseX(), Raylib.GetMouseY()-(.)Wheel); + if(hoverResult == null) + continue; + return hoverResult; } + return null; } } \ No newline at end of file diff --git a/src/Components/Button.bf b/src/Components/Button.bf index 0609176..0b59f31 100644 --- a/src/Components/Button.bf +++ b/src/Components/Button.bf @@ -36,19 +36,19 @@ abstract class Button : Component return false; } - public override void Render() + public override void Render(int32 soy) { - Sprite.Render(X,Y, Tint); + Sprite.Render(X,Y + soy, Tint); var measure = Raylib.MeasureTextEx(Theme.Font, Label.ToScopeCStr!(), Theme.FontSize, 0); - Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2), Theme.FontSize, 0, Theme.Text); + Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text); if(!Enabled) { - Sprite.Render(X,Y, Theme.DisabledTint); + Sprite.Render(X,Y + soy, Theme.DisabledTint); } else { if(_IsHovered) - Sprite.Render(X,Y, HoverTint); + Sprite.Render(X,Y + soy, HoverTint); } _IsHovered = false; } diff --git a/src/Components/Checkbox.bf b/src/Components/Checkbox.bf index 83ede84..1eafc43 100644 --- a/src/Components/Checkbox.bf +++ b/src/Components/Checkbox.bf @@ -34,16 +34,16 @@ abstract class Checkbox : Component return true; } - public override void Render() + public override void Render(int32 soy) { if(!Checked) - Sprite.Render(X,Y,Tint); + Sprite.Render(X,Y + soy,Tint); else - SpriteChecked.Render(X,Y,Tint); + SpriteChecked.Render(X,Y + soy,Tint); var measure = Raylib.MeasureTextEx(Theme.Font, Label.ToScopeCStr!(), Theme.FontSize, 0); - Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), .(X + Sprite.Width + 2, (.)(Y + Sprite.Height/2 - 0.5*measure.y)), Theme.FontSize, 0, Theme.Text); + Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), .(X + Sprite.Width + 2, (.)(Y + Sprite.Height/2 - 0.5*measure.y) + soy), Theme.FontSize, 0, Theme.Text); if(_IsHovered) - Sprite.Render(X,Y, HoverTint); + Sprite.Render(X,Y + soy, HoverTint); _IsHovered = false; } } \ No newline at end of file diff --git a/src/Components/Component.bf b/src/Components/Component.bf index 088d9df..fdf7d31 100644 --- a/src/Components/Component.bf +++ b/src/Components/Component.bf @@ -94,7 +94,7 @@ abstract class Component /// /// Functions /// - public abstract void Render(); + public abstract void Render(int32 soy); public virtual bool OnClick(int32 x, int32 y) => false; public abstract Component OnHover(int32 x, int32 y); diff --git a/src/Components/Container.bf b/src/Components/Container.bf index 17db09e..dde7cef 100644 --- a/src/Components/Container.bf +++ b/src/Components/Container.bf @@ -70,7 +70,7 @@ class Container : Component if(rowHeight < e.Height+e.MarginTop+e.MarginBottom) rowHeight = e.Height+e.MarginTop+e.MarginBottom; } - + Width = maxWidth + MarginLeft + MarginRight; Height = y + rowHeight + MarginTop + MarginBottom; } @@ -130,12 +130,10 @@ class Container : Component ///Forcefully terminates the current row public void EndRow() => _LayoutData.Add(null); - public override void Render() + public override void Render(int32 soy) { for(var i in Children) - { - i.Render(); - } + i.Render(soy); } public override bool OnClick(int32 x, int32 y) diff --git a/src/Components/IconButton.bf b/src/Components/IconButton.bf index 9d24c5d..ad7b08e 100644 --- a/src/Components/IconButton.bf +++ b/src/Components/IconButton.bf @@ -16,14 +16,14 @@ abstract class IconButton : Button - public override void Render() + public override void Render(int32 soy) { - Sprite.Render(X,Y, Tint); - Icon.Render(X+Width/2-Icon.Width/2+2,Y+Height/2-Icon.Height/2+2, .(0,0,0,125)); - Icon.Render(X+Width/2-Icon.Width/2,Y+Height/2-Icon.Height/2); + Sprite.Render(X,Y + soy, Tint); + Icon.Render(X+Width/2-Icon.Width/2+2,Y+Height/2-Icon.Height/2+2 + soy, .(0,0,0,125)); + Icon.Render(X+Width/2-Icon.Width/2,Y+Height/2-Icon.Height/2 + soy); if(_IsHovered) - Sprite.Render(X,Y, HoverTint); + Sprite.Render(X,Y + soy, HoverTint); _IsHovered = false; } diff --git a/src/Components/Label.bf b/src/Components/Label.bf index e6ae47d..59162b5 100644 --- a/src/Components/Label.bf +++ b/src/Components/Label.bf @@ -17,9 +17,9 @@ class Label : Component public override Component OnHover(int32 x, int32 y) => null; - public override void Render() + public override void Render(int32 soy) { - Raylib.DrawTextEx(Theme.FontLarge, Label.Ptr, .(X,Y), Theme.FontSizeLarge, 0, Theme.Text); - Raylib.DrawLine(X,Y + (.)_Measure.y,X + (.)_Measure.x, Y + (.)_Measure.y, Theme.Text); + Raylib.DrawTextEx(Theme.FontLarge, Label.Ptr, .(X,Y + soy), Theme.FontSizeLarge, 0, Theme.Text); + Raylib.DrawLine(X,Y + (.)_Measure.y + soy,X + (.)_Measure.x, Y + (.)_Measure.y + soy, Theme.Text); } } \ No newline at end of file diff --git a/src/Components/LargeButton.bf b/src/Components/LargeButton.bf index f63a8a0..01dc06f 100644 --- a/src/Components/LargeButton.bf +++ b/src/Components/LargeButton.bf @@ -12,13 +12,13 @@ abstract class LargeButton : Button Height = Sprite.Height; } - public override void Render() + public override void Render(int32 soy) { - Sprite.Render(X,Y, Tint); + Sprite.Render(X,Y + soy, Tint); var measure = Raylib.MeasureTextEx(Theme.Font, Label.Ptr, Theme.FontSize, 0); - Raylib.DrawTextEx(Theme.Font, Label.Ptr, .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2), Theme.FontSize, 0, Theme.Text); + Raylib.DrawTextEx(Theme.Font, Label.Ptr, .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text); if(_IsHovered) - Sprite.Render(X,Y, HoverTint); + Sprite.Render(X,Y + soy, HoverTint); _IsHovered = false; } } \ No newline at end of file diff --git a/src/Components/NButton.bf b/src/Components/NButton.bf index baa5b75..145f192 100644 --- a/src/Components/NButton.bf +++ b/src/Components/NButton.bf @@ -17,25 +17,25 @@ abstract class NButton : Button } - public override void Render() + public override void Render(int32 soy) { Raylib.DrawTextureNPatch( *Sprite.Source, PatchInfo, - .(X, Y, Width, Height), + .(X, Y + soy, Width, Height), .(0,0), 0, Tint); var measure = Raylib.MeasureTextEx(Theme.Font, Label.ToScopeCStr!(), Theme.FontSize, 0); - Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2), Theme.FontSize, 0, Theme.Text); + Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text); if(!Enabled) { Raylib.DrawTextureNPatch( *Sprite.Source, PatchInfo, - .(X, Y, Width, Height), + .(X, Y + soy, Width, Height), .(0,0), 0, Theme.DisabledTint); @@ -46,7 +46,7 @@ abstract class NButton : Button Raylib.DrawTextureNPatch( *Sprite.Source, PatchInfo, - .(X, Y, Width, Height), + .(X, Y + soy, Width, Height), .(0,0), 0, HoverTint); diff --git a/src/Components/Placeholder.bf b/src/Components/Placeholder.bf index bd85351..c635b3a 100644 --- a/src/Components/Placeholder.bf +++ b/src/Components/Placeholder.bf @@ -9,5 +9,5 @@ class Placeholder : Component } public override Component OnHover(int32 x, int32 y) => null; - public override void Render() {} + public override void Render(int32 soy) {} } \ No newline at end of file diff --git a/src/Components/PopupComponent.bf b/src/Components/PopupComponent.bf new file mode 100644 index 0000000..ea55bff --- /dev/null +++ b/src/Components/PopupComponent.bf @@ -0,0 +1,12 @@ +namespace TheaterGui.Components; + +abstract class PopupComponent : Component +{ + public this(System.StringView pComponentName, System.StringView pLabel) : base(pComponentName, pLabel) + { + + } + + ///When something force closes the popup + public abstract void OnClose(); +} \ No newline at end of file diff --git a/src/Components/Toolbar.bf b/src/Components/Toolbar.bf index 95301c4..3648bfd 100644 --- a/src/Components/Toolbar.bf +++ b/src/Components/Toolbar.bf @@ -9,7 +9,7 @@ class Toolbar : Component public NPatchInfo PatchInfo; public List Categories = new .() ~ DeleteContainerAndItems!(_); private ToolbarPopup _CurrentPopup = null; - private ToolbarCategory _HoveredPopup = null; + private ToolbarCategory _SelectedPopup = null; @@ -19,31 +19,31 @@ class Toolbar : Component Sprite = App.Textures.GetAsset("horizontal_patch"); PatchInfo =.(Sprite.SourceRect, 2,2,2,2,(.)NPatchLayout.NPATCH_NINE_PATCH); - Categories.Add(new .("File", new .("Load file",null), new .("Save file",null), new .("Recent Files",null))); + Categories.Add(new .("File", new .("Load file", new () => { Raylib.MinimizeWindow();}), new .("Save file",null), new .("Recent Files",null))); Categories.Add(new .("Edit", new .("Revert",null), new .("Really long thing goes here",null))); Categories.Add(new .("Secret third thing", new .("Load file",null), new .("Save file",null), new .("Recent Files",null))); } - public override void Render() + public override void Render(int32 soy) { Raylib.DrawTextureNPatch( *Sprite.Source, PatchInfo, - .(X, Y, Width, Height), + .(X, Y + soy, Width, Height), .(0,0), 0, Tint); int32 x = 5; for(var i in Categories) { - Raylib.DrawTextEx(Theme.Font, scope String(scope $"{i.Name}"), .(X + x, Y + Height/2 - i.NameMeasurement.y/2), Theme.FontSize, 0, Theme.Text); - if(i == _HoveredPopup) + Raylib.DrawTextEx(Theme.Font, scope String(scope $"{i.Name}"), .(X + x, Y + Height/2 - i.NameMeasurement.y/2 + soy), Theme.FontSize, 0, Theme.Text); + if(i == _SelectedPopup) { //5 padding in every direction Raylib.DrawTextureNPatch( *Sprite.Source, PatchInfo, - .(X + x-5, Y, i.NameMeasurement.x+10, Height), + .(X + x-5, Y + soy, i.NameMeasurement.x+10, Height), .(0,0), 0, HoverTint); @@ -61,6 +61,7 @@ class Toolbar : Component if(x >= hor && x <= hor + i.NameMeasurement.x) { var popup = new ToolbarPopup(hor-10,Height, i); + popup.Owner = this; App.OpenPopup(popup); _CurrentPopup = popup; return true; @@ -77,7 +78,7 @@ class Toolbar : Component { if(x >= hor && x <= hor + i.NameMeasurement.x) { - _HoveredPopup = i; + _SelectedPopup = i; if(_CurrentPopup != null && _CurrentPopup.Category != i) { @@ -88,7 +89,7 @@ class Toolbar : Component } hor += (.)i.NameMeasurement.x + 10; } - _HoveredPopup = null; + _SelectedPopup = null; return null; } diff --git a/src/Components/ToolbarPopup.bf b/src/Components/ToolbarPopup.bf index 3b453f1..9c5410e 100644 --- a/src/Components/ToolbarPopup.bf +++ b/src/Components/ToolbarPopup.bf @@ -3,9 +3,11 @@ namespace TheaterGui.Components; using System; using RaylibBeef; -class ToolbarPopup : Component +class ToolbarPopup : PopupComponent { public NPatchInfo PatchInfo; + public Toolbar Owner = null; + public Toolbar.ToolbarCategory.ToolbarItem SelectedItem = null; private Toolbar.ToolbarCategory _Category = null; public Toolbar.ToolbarCategory Category @@ -33,25 +35,82 @@ class ToolbarPopup : Component Category = category; } - public override void Render() + public override void Render(int32 soy) { Raylib.DrawTextureNPatch( *Sprite.Source, PatchInfo, - .(X, Y, Width, Height), + .(X, Y + soy, Width, Height), .(0,0), 0, Tint); int32 y = 5; for(var i in Category.Items) { - Raylib.DrawTextEx(Theme.Font, scope String(i.Name), .(X + 5 + 32, Y + y), Theme.FontSize, 0, Theme.Text); + Raylib.DrawTextEx(Theme.Font, scope String(i.Name), .(X + 5 + 32, Y + y + soy), Theme.FontSize, 0, Theme.Text); + if(SelectedItem == i) + { + Raylib.DrawTextureNPatch( + *Sprite.Source, + PatchInfo, + .(X, Y + y - 5 + soy, Width, i.NameMeasurement.y+10), + .(0,0), + 0, + HoverTint); + } + y += (.)i.NameMeasurement.y+5; } } public override Component OnHover(int32 x, int32 y) { - return default; + if(!(x >= X && x <= X + Width)) + { + SelectedItem = null; + return null; + } + + int32 pos = 5 + Y; + for(var i in Category.Items) + { + if(y >= pos && y <= pos + (.)i.NameMeasurement.y+5) + { + SelectedItem = i; + return this; + } + pos += (.)i.NameMeasurement.y+5; + } + SelectedItem = null; + return null; + } + + public override bool OnClick(int32 x, int32 y) + { + if(!(x >= X && x <= X + Width)) + return false; + + int32 pos = 5 + Y; + for(var i in Category.Items) + { + if(y >= pos && y <= pos + (.)i.NameMeasurement.y+5) + { + if(i.ClickAction != null) + i.ClickAction(); + return false; + } + pos += (.)i.NameMeasurement.y+5; + } + + return false; + } + + public override void OnClose() + { + if(Owner != null) + { + Owner.[Friend]_CurrentPopup = null; + Owner.[Friend]_SelectedPopup = null; + } } } \ No newline at end of file