Fixed scrollable container issues and refactor
This commit is contained in:
parent
cfefe7db2b
commit
6d06a13d64
18 changed files with 322 additions and 187 deletions
|
@ -7,5 +7,20 @@ StartupProject = "ExampleGui"
|
|||
[Configs.Debug.Win64]
|
||||
ConfigSelections = {raylib-beef = {Config = "StaticDebug"}}
|
||||
|
||||
[Configs.Debug.wasm32]
|
||||
AllocType = "CRT"
|
||||
EnableObjectDebugFlags = false
|
||||
EmitObjectAccessCheck = false
|
||||
|
||||
[Configs.Release.Win64]
|
||||
ConfigSelections = {raylib-beef = {Config = "StaticRelease"}}
|
||||
|
||||
[Configs.Paranoid.wasm32]
|
||||
AllocType = "CRT"
|
||||
EnableObjectDebugFlags = false
|
||||
EmitObjectAccessCheck = false
|
||||
|
||||
[Configs.Test.wasm32]
|
||||
AllocType = "CRT"
|
||||
EnableObjectDebugFlags = false
|
||||
EmitObjectAccessCheck = false
|
||||
|
|
347
src/App.bf
347
src/App.bf
|
@ -1,37 +1,51 @@
|
|||
namespace TheaterGui;
|
||||
using TheaterGui.Components;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
using RaylibBeef;
|
||||
|
||||
using internal TheaterGui;
|
||||
using TheaterGui.Components;
|
||||
|
||||
class App
|
||||
{
|
||||
/*
|
||||
There are two ways to run TheaterGui.
|
||||
Either full, by using the Run function or by manually calling the functions in Run.
|
||||
This way you can integrate TheaterGui into other raylib applications of your choice.
|
||||
|
||||
//All loaded textures
|
||||
private static List<Popup> Popups = new .() ~ DeleteContainerAndItems!(_);
|
||||
Components are supposed to be created via inheritance for each individual component, except some very simple exeptions (Labels, Placeholders)
|
||||
*/
|
||||
|
||||
|
||||
#region Fields
|
||||
//For hover items
|
||||
private static Vector2 oldPos = .(0,0);
|
||||
private static double movTime = 0;
|
||||
private static String hoverText = new .() ~ delete _;
|
||||
private static List<Popup> _Popups = new .() ~ DeleteContainerAndItems!(_);
|
||||
private static Vector2 _OldPos = .(0, 0);
|
||||
private static double _MovTime = 0;
|
||||
private static String _HoverText = new .() ~ delete _;
|
||||
private static Vector2 _OldSize = .(0, 0);
|
||||
|
||||
public static Textures Textures ~ delete _;
|
||||
|
||||
public static Textures Textures ~ delete _; //All loaded textures
|
||||
public static Component Selected; //Currently selected component
|
||||
public static bool AllowReorder = true;
|
||||
|
||||
private static Screen _CurrentScreen = null;
|
||||
|
||||
private static Screen _CurrentScreen = null ~ delete _;
|
||||
public static Screen CurrentScreen
|
||||
{
|
||||
get => _CurrentScreen;
|
||||
set
|
||||
{
|
||||
if(_CurrentScreen != null)
|
||||
if (_CurrentScreen != null)
|
||||
delete _CurrentScreen;
|
||||
_CurrentScreen = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///Window width
|
||||
public static int32 Width
|
||||
{
|
||||
|
@ -39,6 +53,7 @@ class App
|
|||
set => Raylib.SetWindowSize(value, Raylib.GetRenderHeight());
|
||||
}
|
||||
|
||||
|
||||
///Window height
|
||||
public static int32 Height
|
||||
{
|
||||
|
@ -46,12 +61,14 @@ class App
|
|||
set => Raylib.SetWindowSize(Raylib.GetRenderWidth(), value);
|
||||
}
|
||||
|
||||
|
||||
///Mouse position
|
||||
public static Vector2 Mouse
|
||||
{
|
||||
get => Raylib.GetMousePosition();
|
||||
}
|
||||
|
||||
|
||||
//Mouse wheel offset
|
||||
public static float Wheel
|
||||
{
|
||||
|
@ -59,223 +76,285 @@ class App
|
|||
set;
|
||||
}
|
||||
|
||||
public static void ForceReorder()
|
||||
{
|
||||
if(AllowReorder && CurrentScreen != null)
|
||||
CurrentScreen.Reorder(Width);
|
||||
}
|
||||
|
||||
public static void OpenPopup(Popup popup)
|
||||
private static bool _ShouldClose;
|
||||
public static bool ShouldClose
|
||||
{
|
||||
Popups.Add(popup);
|
||||
public get
|
||||
{
|
||||
return _ShouldClose || Raylib.WindowShouldClose();
|
||||
}
|
||||
public set => _ShouldClose = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///Run TheaterGui (Use for fully independent programs)
|
||||
///@param pName Name of the window
|
||||
///@param pWidth Width of the window
|
||||
///@param pHeight Height of the window
|
||||
///@param pStartScreen The starting Screen of the application
|
||||
public static void Run<T>(StringView pName, int32 pWidth, int32 pHeight) where T : Screen
|
||||
{
|
||||
InitializeRaylib(pName, pWidth, pHeight);
|
||||
InitializeGui<T>();
|
||||
|
||||
#if BF_PLATFORM_WASM
|
||||
WebAssembly.emscripten_set_main_loop(=> ProcessDrawFrame, 40, 1);
|
||||
///Afaik the infinite loop means, that the deinitialization functionality will not be called,
|
||||
///but that should be fine for wasm since it fully cleans up when you exit the page.
|
||||
///If we dont do it calls the deinitialization directly afterwards
|
||||
#else
|
||||
while (!App.ShouldClose)
|
||||
ProcessDrawFrame();
|
||||
#endif
|
||||
|
||||
DeinitializeGui();
|
||||
DeinitializeRaylib();
|
||||
}
|
||||
|
||||
|
||||
|
||||
///Initialize the TheaterGui app
|
||||
public static void Initialize(StringView pAppTitle = "TheaterApp")
|
||||
///Initializes the raylib enviroment
|
||||
///@param pName Name of the window
|
||||
///@param pWidth Width of the window
|
||||
///@param pHeight Height of the window
|
||||
public static void InitializeRaylib(StringView pName, int32 pWidth, int32 pHeight)
|
||||
{
|
||||
//Default raylib settings
|
||||
Raylib.SetConfigFlags((.)(ConfigFlags.FLAG_WINDOW_RESIZABLE | ConfigFlags.FLAG_WINDOW_HIGHDPI));
|
||||
Raylib.InitWindow(1280, 720, scope String(pAppTitle));
|
||||
Raylib.InitWindow(pWidth, pHeight, scope String(pName));
|
||||
Raylib.SetExitKey(0);
|
||||
Raylib.SetTargetFPS(40);
|
||||
Raylib.SetWindowMinSize(640,360);
|
||||
#if !BF_PLATFORM_WASM ///Otherwise raylib sleeps and delays browser responsiveness
|
||||
Raylib.SetTargetFPS(40); //Should be a resonable framerate for gui apps
|
||||
#endif
|
||||
Raylib.SetWindowMinSize(640, 360);
|
||||
|
||||
///Set the default window icon
|
||||
var icon = Raylib.LoadImageFromMemory(".png", (.)&Theme.Texture_WindowIcon, Theme.Texture_WindowIcon.Count);
|
||||
Raylib.SetWindowIcon(icon);
|
||||
Raylib.UnloadImage(icon);
|
||||
}
|
||||
|
||||
//Load textures
|
||||
|
||||
///Initialize the gui enviroment
|
||||
public static void InitializeGui<T>() where T : Screen
|
||||
{
|
||||
Textures = new .();
|
||||
Theme.Font = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSize, null, 256);
|
||||
Theme.FontSmall = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSizeSmall, null, 256);
|
||||
Theme.FontLarge = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSizeLarge, null, 256);
|
||||
|
||||
CurrentScreen = new T();
|
||||
}
|
||||
|
||||
///Deinitialize the TheaterGui app
|
||||
public static void Deinitialize()
|
||||
{
|
||||
|
||||
///Cleanup the gui enviroment
|
||||
public static void DeinitializeGui() => void();
|
||||
|
||||
|
||||
///Cleanup the raylib enviroment
|
||||
public static void DeinitializeRaylib() => void();
|
||||
|
||||
|
||||
///To be called by emscripten
|
||||
private static void ProcessDrawFrame()
|
||||
{
|
||||
ProcessFrame();
|
||||
Raylib.BeginDrawing();
|
||||
Raylib.ClearBackground(Theme.Background);
|
||||
DrawFrame();
|
||||
Raylib.EndDrawing();
|
||||
}
|
||||
|
||||
///Start the application on the input stream
|
||||
public static void Start(Screen pScreen)
|
||||
{
|
||||
CurrentScreen = pScreen;
|
||||
Vector2 oldSize = .(0,0);
|
||||
|
||||
while(!Raylib.WindowShouldClose())
|
||||
///Process the logic for a single frame of the application
|
||||
public static void ProcessFrame()
|
||||
{
|
||||
|
||||
Vector2 newSize = .(Width, Height);
|
||||
if (_OldSize != newSize)
|
||||
{
|
||||
if(oldSize != .(Width,Height))
|
||||
{
|
||||
CurrentScreen.Reorder(Width);
|
||||
oldSize = .(Width,Math.Min(Height, CurrentScreen.Height));
|
||||
}
|
||||
CurrentScreen.Reorder((.)newSize.x);
|
||||
_OldSize = newSize;
|
||||
}
|
||||
|
||||
//This could probably be solved better
|
||||
var wh = Raylib.GetMouseWheelMove();
|
||||
if(!CurrentScreen.HandleScrollEvent(wh*wh*wh, (.)Mouse.x, (.)Mouse.y) && CurrentScreen.Height - Height > 0)
|
||||
{
|
||||
var w = Raylib.GetMouseWheelMove();
|
||||
Wheel += w * w * w;
|
||||
Wheel = Math.Clamp(Wheel, -1*(CurrentScreen.Height - Height), 0);
|
||||
}
|
||||
else
|
||||
Wheel = 0;
|
||||
Input.HandleScrolling(Raylib.GetMouseWheelMove());
|
||||
|
||||
if(Raylib.IsMouseButtonPressed(0))
|
||||
HandleLeftClick();
|
||||
else if(Raylib.IsMouseButtonDown(0))
|
||||
HandleButtonDown();
|
||||
else if(Raylib.IsMouseButtonPressed(1))
|
||||
|
||||
|
||||
if (Raylib.IsMouseButtonPressed(0))
|
||||
HandleLeftClick();
|
||||
else if (Raylib.IsMouseButtonDown(0))
|
||||
HandleButtonDown();
|
||||
else if (Raylib.IsMouseButtonPressed(1))
|
||||
{
|
||||
if (_Popups.Count > 0)
|
||||
{
|
||||
if(Popups.Count > 0)
|
||||
var top = _Popups[_Popups.Count - 1];
|
||||
if (top is RightClickPopup)
|
||||
{
|
||||
var top = Popups[Popups.Count-1];
|
||||
if(top is RightClickPopup)
|
||||
{
|
||||
Popups.Remove(top);
|
||||
delete top;
|
||||
}
|
||||
_Popups.Remove(top);
|
||||
delete top;
|
||||
}
|
||||
Toolbar.ToolbarCategory popupCat = new .("Items");
|
||||
CurrentScreen.OnRightClick((.)Mouse.x, (.)Mouse.y, popupCat);
|
||||
if(popupCat.Items.Count > 0)
|
||||
Popups.Add(new RightClickPopup((.)Mouse.x, (.)Mouse.y, popupCat));
|
||||
else
|
||||
delete popupCat;
|
||||
}
|
||||
Toolbar.ToolbarCategory popupCat = new .("Items");
|
||||
CurrentScreen.OnRightClick((.)Mouse.x, (.)Mouse.y, popupCat);
|
||||
if (popupCat.Items.Count > 0)
|
||||
_Popups.Add(new RightClickPopup((.)Mouse.x, (.)Mouse.y, popupCat));
|
||||
else
|
||||
HandleHover();
|
||||
|
||||
//Drawing logic
|
||||
Raylib.BeginDrawing();
|
||||
Raylib.ClearBackground(Theme.Background);
|
||||
|
||||
CurrentScreen.Render((.)Wheel);
|
||||
|
||||
for(var i in Popups)
|
||||
i.Render((.)Wheel);
|
||||
|
||||
if(hoverText != String.Empty)
|
||||
{ //TODO: When you move outside of the window, the hover fucks up
|
||||
int32 yOffset = 0;
|
||||
int32 xOffset = 0;
|
||||
var measure = Raylib.MeasureTextEx(Theme.FontSmall, hoverText, Theme.FontSizeSmall, 0);
|
||||
if(Raylib.GetMouseX() < Width/2)
|
||||
xOffset = 15;
|
||||
else
|
||||
xOffset = (.)(-1 * measure.x)-15;
|
||||
if(Raylib.GetMouseY() < Height/2)
|
||||
yOffset = 0;
|
||||
else
|
||||
yOffset = (.)(-1 * measure.y);
|
||||
Raylib.DrawRectangle((.)Mouse.x-3+xOffset+3, (.)Mouse.y-3+yOffset+3, (.)measure.x+6, (.)measure.y+3, .(0, 0, 0, 70));
|
||||
Raylib.DrawRectangle((.)Mouse.x-3+xOffset, (.)Mouse.y-3+yOffset, (.)measure.x+6, (.)measure.y+3, .(218, 211, 176, 255));
|
||||
Raylib.DrawRectangleLines((.)Mouse.x-3+xOffset, (.)Mouse.y-3+yOffset, (.)measure.x+6, (.)measure.y+3, Raylib.BLACK);
|
||||
Raylib.DrawTextEx(Theme.FontSmall, hoverText, Raymath.Vector2Add(Mouse, .(xOffset,yOffset)), Theme.FontSizeSmall, 0, Raylib.BLACK);
|
||||
}
|
||||
|
||||
Raylib.EndTextureMode();
|
||||
delete popupCat;
|
||||
}
|
||||
else
|
||||
HandleHover();
|
||||
}
|
||||
|
||||
|
||||
///Draw the current state of the application
|
||||
public static void DrawFrame()
|
||||
{
|
||||
//Drawing logic
|
||||
CurrentScreen.Render((.)Wheel);
|
||||
|
||||
Raylib.EndDrawing();
|
||||
for (var i in _Popups)
|
||||
i.Render((.)Wheel);
|
||||
|
||||
if(hoverText != String.Empty)
|
||||
hoverText.Clear();
|
||||
if (!_HoverText.IsEmpty)
|
||||
{
|
||||
RenderHoverText();
|
||||
_HoverText.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static void RenderHoverText()
|
||||
{
|
||||
int32 yOffset = 0;
|
||||
int32 xOffset = 0;
|
||||
|
||||
var measure = Raylib.MeasureTextEx(Theme.FontSmall, _HoverText, Theme.FontSizeSmall, 0);
|
||||
|
||||
if (Mouse.x < Width / 2) //Render the textbox to the right of the cursor
|
||||
xOffset = 15;
|
||||
else //Render the textbox to the left of the cursor
|
||||
xOffset = (.)(-1 * measure.x) - 15;
|
||||
if (Mouse.y < Height / 2) //Render the textbox at the y location of the cursor
|
||||
yOffset = 0;
|
||||
else //Render the textbox offset so, that the textbox y ends at the y location of the cursor
|
||||
yOffset = (.)(-1 * measure.y);
|
||||
|
||||
//BoxShadow
|
||||
//Box
|
||||
//BoxBorder
|
||||
//BoxContent
|
||||
Raylib.DrawRectangle((.)Mouse.x - 3 + xOffset + 3, (.)Mouse.y - 3 + yOffset + 3, (.)measure.x + 6, (.)measure.y + 3, Color(0, 0, 0, 70));
|
||||
Raylib.DrawRectangle((.)Mouse.x - 3 + xOffset, (.)Mouse.y - 3 + yOffset, (.)measure.x + 6, (.)measure.y + 3, Color(218, 211, 176, 255));
|
||||
Raylib.DrawRectangleLines((.)Mouse.x - 3 + xOffset, (.)Mouse.y - 3 + yOffset, (.)measure.x + 6, (.)measure.y + 3, Raylib.BLACK);
|
||||
Raylib.DrawTextEx(Theme.FontSmall, _HoverText, Raymath.Vector2Add(Mouse, Vector2(xOffset, yOffset)), Theme.FontSizeSmall, 0, Raylib.BLACK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void ForceReorder()
|
||||
{
|
||||
if (AllowReorder && CurrentScreen != null)
|
||||
CurrentScreen.Reorder(Width);
|
||||
}
|
||||
|
||||
|
||||
public static void OpenPopup(Popup popup)
|
||||
{
|
||||
_Popups.Add(popup);
|
||||
}
|
||||
|
||||
|
||||
///Handles the leftclick action
|
||||
private static void HandleLeftClick()
|
||||
{
|
||||
if(Popups.Count > 0)
|
||||
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)))
|
||||
var top = _Popups[_Popups.Count - 1];
|
||||
if (Rectangle(top.X, top.Y, top.Width, top.Height).Overlaps(Raylib.GetMouseX(), (.)(Raylib.GetMouseY() - Wheel)))
|
||||
{
|
||||
if(!top.OnClick(Raylib.GetMouseX(), Raylib.GetMouseY()))
|
||||
if (!top.OnClick(Raylib.GetMouseX(), Raylib.GetMouseY()))
|
||||
{
|
||||
Popups.Remove(top);
|
||||
_Popups.Remove(top);
|
||||
top.OnClose(); //Any last words ?
|
||||
delete top;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
bool a = top is DropdownPopup; //TODO: Make this less horrible
|
||||
|
||||
Popups.Remove(top);
|
||||
_Popups.Remove(top);
|
||||
top.OnClose(); //Any last words ?
|
||||
delete top;
|
||||
if(!a)
|
||||
CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()-App.Wheel)); //So that we dont eat any inputs
|
||||
if (!a)
|
||||
CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY() - App.Wheel)); //So that we dont eat any inputs
|
||||
}
|
||||
}
|
||||
else
|
||||
CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()-App.Wheel));
|
||||
CurrentScreen.OnClick(Raylib.GetMouseX(), (.)(Raylib.GetMouseY() - App.Wheel));
|
||||
}
|
||||
|
||||
|
||||
private static bool HandleButtonDown()
|
||||
{
|
||||
//Topmost first
|
||||
for(var i in Popups.Reversed)
|
||||
for (var i in _Popups.Reversed)
|
||||
{
|
||||
var hoverResult = i.OnDown(Raylib.GetMouseX(), Raylib.GetMouseY()-(.)Wheel);
|
||||
if(hoverResult == false)
|
||||
continue;
|
||||
return hoverResult;
|
||||
var hoverResult = i.OnDown(Raylib.GetMouseX(), Raylib.GetMouseY() - (.)Wheel);
|
||||
if (hoverResult == false)
|
||||
continue;
|
||||
return hoverResult;
|
||||
}
|
||||
return CurrentScreen.OnDown(Raylib.GetMouseX(), (.)(Raylib.GetMouseY()-App.Wheel));
|
||||
return CurrentScreen.OnDown(Raylib.GetMouseX(), (.)(Raylib.GetMouseY() - App.Wheel));
|
||||
}
|
||||
|
||||
|
||||
///Handles the hovering effect
|
||||
private static void HandleHover()
|
||||
{
|
||||
Component hoverRes = HandleHoverPopups();
|
||||
if(hoverRes == null)
|
||||
if (hoverRes == null)
|
||||
hoverRes = HandleHoverScreen();
|
||||
|
||||
if(hoverRes == null)
|
||||
if (hoverRes == null)
|
||||
Raylib.SetMouseCursor((.)MouseCursor.MOUSE_CURSOR_DEFAULT);
|
||||
else
|
||||
{
|
||||
if(hoverRes.Enabled)
|
||||
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;
|
||||
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));
|
||||
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)
|
||||
for (var i in _Popups.Reversed)
|
||||
{
|
||||
var hoverResult = i.OnHover(Raylib.GetMouseX(), Raylib.GetMouseY()-(.)Wheel);
|
||||
if(hoverResult == null)
|
||||
continue;
|
||||
return hoverResult;
|
||||
var hoverResult = i.OnHover(Raylib.GetMouseX(), Raylib.GetMouseY() - (.)Wheel);
|
||||
if (hoverResult == null)
|
||||
continue;
|
||||
return hoverResult;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ abstract class Button : Component
|
|||
{
|
||||
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 + soy), Theme.FontSize, 0, Theme.Text);
|
||||
Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), Vector2(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
||||
if(!Enabled)
|
||||
{
|
||||
Sprite.Render(X,Y + soy, Theme.DisabledTint);
|
||||
|
|
|
@ -41,7 +41,7 @@ abstract class Checkbox : Component
|
|||
else
|
||||
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) + soy), Theme.FontSize, 0, Theme.Text);
|
||||
Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), Vector2(X + Sprite.Width + 2, (.)(Y + Sprite.Height/2 - 0.5*measure.y) + soy), Theme.FontSize, 0, Theme.Text);
|
||||
if(_IsHovered)
|
||||
Sprite.Render(X,Y + soy, HoverTint);
|
||||
_IsHovered = false;
|
||||
|
|
|
@ -103,4 +103,5 @@ abstract class Component
|
|||
public abstract Component OnHover(int32 x, int32 y);
|
||||
|
||||
public virtual void WhileSelected() { }
|
||||
|
||||
}
|
|
@ -48,9 +48,16 @@ class Container : Component
|
|||
if(e is Container)
|
||||
{
|
||||
((Container)e).Reorder(w);
|
||||
if(x+e.Width+e.MarginLeft > w-MarginLeft) //Change both instances of padding to 2*Padding to ensure proper padding on the leftmost side of the screen
|
||||
{ //Automatic row break
|
||||
x = 0;
|
||||
y = y + rowHeight;
|
||||
rowHeight = 0;
|
||||
}
|
||||
MoveChildrenRecursive((Container)e, x, y);
|
||||
}
|
||||
|
||||
|
||||
if(e is Toolbar)
|
||||
e.Width = App.Width;
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ abstract class Dropdown : Component
|
|||
public override void Render(int32 soy)
|
||||
{
|
||||
Sprite.Render(X,Y + soy, Tint);
|
||||
var measure = Raylib.MeasureTextEx(Theme.Font, Entries[SelectedEntry], Theme.FontSize, 0);
|
||||
Raylib.DrawTextEx(Theme.Font, Entries[SelectedEntry], .(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
||||
var measure = Raylib.MeasureTextEx(Theme.Font, Entries[(.)SelectedEntry], Theme.FontSize, 0);
|
||||
Raylib.DrawTextEx(Theme.Font, Entries[(.)SelectedEntry], Vector2(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
||||
if(!Enabled)
|
||||
{
|
||||
Sprite.Render(X,Y + soy, Theme.DisabledTint);
|
||||
|
|
|
@ -40,21 +40,21 @@ class DropdownPopup : Popup
|
|||
Raylib.DrawTextureNPatch(
|
||||
*Sprite.Source,
|
||||
PatchInfo,
|
||||
.(X, Y + soy, Width, Height),
|
||||
.(0,0),
|
||||
Rectangle(X, Y + soy, Width, Height),
|
||||
Vector2(0,0),
|
||||
0,
|
||||
Tint);
|
||||
int32 y = 5;
|
||||
for(var i in Options)
|
||||
{
|
||||
Raylib.DrawTextEx(Theme.Font, scope String(i), .(X + 5, Y + y + soy), Theme.FontSize, 0, Theme.Text);
|
||||
Raylib.DrawTextEx(Theme.Font, scope String(i), Vector2(X + 5, Y + y + soy), Theme.FontSize, 0, Theme.Text);
|
||||
if(@i.Index == SelectedItem)
|
||||
{
|
||||
Raylib.DrawTextureNPatch(
|
||||
*Sprite.Source,
|
||||
PatchInfo,
|
||||
.(X, Y + y - 4 + soy, Width, Theme.FontSize+10),
|
||||
.(0,0),
|
||||
Rectangle(X, Y + y - 4 + soy, Width, Theme.FontSize+10),
|
||||
Vector2(0,0),
|
||||
0,
|
||||
HoverTint);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class Label : Component
|
|||
|
||||
public override void Render(int32 soy)
|
||||
{
|
||||
Raylib.DrawTextEx(Theme.FontLarge, Label.Ptr, .(X,Y + soy), Theme.FontSizeLarge, 0, Theme.Text);
|
||||
Raylib.DrawTextEx(Theme.FontLarge, Label.Ptr, Vector2(X,Y + soy), Theme.FontSizeLarge, 0, Theme.Text);
|
||||
Raylib.DrawLine(X,Y + (.)_Measure.y + soy,X + (.)_Measure.x, Y + (.)_Measure.y + soy, Theme.Text);
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ abstract class LargeButton : Button
|
|||
{
|
||||
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 + soy), Theme.FontSize, 0, Theme.Text);
|
||||
Raylib.DrawTextEx(Theme.Font, Label.Ptr, Vector2(X+Width/2-measure.x/2,Y+Height/2-measure.y/2 + soy), Theme.FontSize, 0, Theme.Text);
|
||||
if(_IsHovered)
|
||||
Sprite.Render(X,Y + soy, HoverTint);
|
||||
_IsHovered = false;
|
||||
|
|
|
@ -22,21 +22,21 @@ abstract class NButton : Button
|
|||
Raylib.DrawTextureNPatch(
|
||||
*Sprite.Source,
|
||||
PatchInfo,
|
||||
.(X, Y + soy, Width, Height),
|
||||
.(0,0),
|
||||
Rectangle(X, Y + soy, Width, Height),
|
||||
Vector2(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 + soy), Theme.FontSize, 0, Theme.Text);
|
||||
Raylib.DrawTextEx(Theme.Font, Label.ToScopeCStr!(), Vector2(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 + soy, Width, Height),
|
||||
.(0,0),
|
||||
Rectangle(X, Y + soy, Width, Height),
|
||||
Vector2(0,0),
|
||||
0,
|
||||
Theme.DisabledTint);
|
||||
}
|
||||
|
@ -46,8 +46,8 @@ abstract class NButton : Button
|
|||
Raylib.DrawTextureNPatch(
|
||||
*Sprite.Source,
|
||||
PatchInfo,
|
||||
.(X, Y + soy, Width, Height),
|
||||
.(0,0),
|
||||
Rectangle(X, Y + soy, Width, Height),
|
||||
Vector2(0,0),
|
||||
0,
|
||||
HoverTint);
|
||||
}
|
||||
|
|
|
@ -44,21 +44,21 @@ class RightClickPopup : Popup
|
|||
Raylib.DrawTextureNPatch(
|
||||
*Sprite.Source,
|
||||
PatchInfo,
|
||||
.(X, Y + soy, Width, Height),
|
||||
.(0,0),
|
||||
Rectangle(X, Y + soy, Width, Height),
|
||||
Vector2(0,0),
|
||||
0,
|
||||
Tint);
|
||||
int32 y = 5;
|
||||
for(var i in Category.Items)
|
||||
{
|
||||
Raylib.DrawTextEx(Theme.Font, scope String(i.Name), .(X + 5, Y + y + soy), Theme.FontSize, 0, Theme.Text);
|
||||
Raylib.DrawTextEx(Theme.Font, scope String(i.Name), Vector2(X + 5, 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),
|
||||
Rectangle(X, Y + y - 5 + soy, Width, i.NameMeasurement.y+10),
|
||||
Vector2(0,0),
|
||||
0,
|
||||
HoverTint);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,6 @@ class ScrollableContainer : Container
|
|||
}
|
||||
|
||||
private List<Component> _LayoutData = new .() ~ delete _;
|
||||
|
||||
|
||||
|
||||
///Recalculate the layout of all entries
|
||||
public override void Reorder(int32 w)
|
||||
{
|
||||
|
@ -63,7 +60,6 @@ class ScrollableContainer : Container
|
|||
y = y + rowHeight;
|
||||
rowHeight = 0;
|
||||
}
|
||||
|
||||
e.[Friend]X = x + e.MarginLeft;
|
||||
x = x + e.Width + e.MarginLeft + e.MarginRight;
|
||||
e.[Friend]Y = y + e.MarginTop;
|
||||
|
@ -72,6 +68,7 @@ class ScrollableContainer : Container
|
|||
|
||||
if(rowHeight < e.Height+e.MarginTop+e.MarginBottom)
|
||||
rowHeight = e.Height+e.MarginTop+e.MarginBottom;
|
||||
|
||||
}
|
||||
|
||||
Width = maxWidth + MarginLeft + MarginRight;
|
||||
|
@ -135,7 +132,7 @@ class ScrollableContainer : Container
|
|||
|
||||
public override void Render(int32 soy)
|
||||
{
|
||||
Raylib.BeginScissorMode(X, Y + soy, Width, ContainerHeight);
|
||||
Raylib.BeginScissorMode(X, Y + soy, Width, Height);
|
||||
for(var i in Children)
|
||||
i.Render((.)(soy + Scroll));
|
||||
Raylib.EndScissorMode();
|
||||
|
@ -145,7 +142,7 @@ class ScrollableContainer : Container
|
|||
{
|
||||
for(var e in Children)
|
||||
{
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y - Scroll, e.Width, e.Height).Overlaps(x, y))
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
||||
return e.OnClick(x, (.)(y - Scroll));
|
||||
}
|
||||
return false;
|
||||
|
@ -155,8 +152,8 @@ class ScrollableContainer : Container
|
|||
{
|
||||
for(var e in Children)
|
||||
{
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
||||
return e.OnDown(x, y);
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
||||
return e.OnDown(x, (.)(y - Scroll));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -165,7 +162,7 @@ class ScrollableContainer : Container
|
|||
{
|
||||
for(var e in Children)
|
||||
{
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y - Scroll, e.Width, e.Height).Overlaps(x, y))
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
||||
return e.OnHover(x, (.)(y - Scroll));
|
||||
}
|
||||
return null;
|
||||
|
@ -175,8 +172,8 @@ class ScrollableContainer : Container
|
|||
{
|
||||
for(var e in Children)
|
||||
{
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
||||
e.OnRightClick(x, y, items);
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
||||
e.OnRightClick(x, (.)(y - Scroll), items);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,11 +181,11 @@ class ScrollableContainer : Container
|
|||
{
|
||||
for(var e in Children)
|
||||
{
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, y))
|
||||
if(e.HandleScrollEvent(scroll, x, y))
|
||||
if(RaylibBeef.Rectangle(e.X, e.Y, e.Width, e.Height).Overlaps(x, (.)(y - Scroll)))
|
||||
if(e.HandleScrollEvent(scroll, x, (.)(y - Scroll)))
|
||||
return true;
|
||||
}
|
||||
//Do our own rendering
|
||||
|
||||
Scroll += scroll;
|
||||
Scroll = Math.Clamp(Scroll,-(Height-ContainerHeight),0);
|
||||
return true;
|
||||
|
|
|
@ -23,22 +23,22 @@ abstract class Toolbar : Component
|
|||
Raylib.DrawTextureNPatch(
|
||||
*Sprite.Source,
|
||||
PatchInfo,
|
||||
.(X, Y + soy, Width, Height),
|
||||
.(0,0),
|
||||
Rectangle(X, Y + soy, Width, Height),
|
||||
Vector2(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 + soy), Theme.FontSize, 0, Theme.Text);
|
||||
Raylib.DrawTextEx(Theme.Font, scope String(scope $"{i.Name}"), Vector2(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 + soy, i.NameMeasurement.x+10, Height),
|
||||
.(0,0),
|
||||
Rectangle(X + x-5, Y + soy, i.NameMeasurement.x+10, Height),
|
||||
Vector2(0,0),
|
||||
0,
|
||||
HoverTint);
|
||||
}
|
||||
|
|
|
@ -40,21 +40,21 @@ class ToolbarPopup : Popup
|
|||
Raylib.DrawTextureNPatch(
|
||||
*Sprite.Source,
|
||||
PatchInfo,
|
||||
.(X, Y + soy, Width, Height),
|
||||
.(0,0),
|
||||
Rectangle(X, Y + soy, Width, Height),
|
||||
Vector2(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 + soy), Theme.FontSize, 0, Theme.Text);
|
||||
Raylib.DrawTextEx(Theme.Font, scope String(i.Name), Vector2(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),
|
||||
Rectangle(X, Y + y - 5 + soy, Width, i.NameMeasurement.y+10),
|
||||
Vector2(0,0),
|
||||
0,
|
||||
HoverTint);
|
||||
}
|
||||
|
|
|
@ -32,3 +32,14 @@ namespace System
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace System
|
||||
{
|
||||
#if BF_PLATFORM_WASM
|
||||
extension WebAssembly
|
||||
{
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
public static extern void emscripten_set_main_loop(function void() func, int32 fps, int32 simulateInfinteLoop);
|
||||
}
|
||||
#endif
|
||||
}
|
17
src/Input.bf
Normal file
17
src/Input.bf
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace TheaterGui;
|
||||
|
||||
using System;
|
||||
|
||||
class Input
|
||||
{
|
||||
internal static void HandleScrolling(float pWheelMove)
|
||||
{
|
||||
var w = pWheelMove * pWheelMove * pWheelMove;
|
||||
|
||||
if (!App.CurrentScreen.HandleScrollEvent(w, (.)App.Mouse.x, (.)(App.Mouse.y - App.Wheel)) && App.CurrentScreen.Height - App.Height > 0)
|
||||
{
|
||||
App.Wheel += w;
|
||||
App.Wheel = Math.Clamp(App.Wheel, -1 * (App.CurrentScreen.Height - App.Height), 0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,10 @@ class Textures
|
|||
|
||||
public this()
|
||||
{
|
||||
Theme.Font = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSize, null, 256);
|
||||
Theme.FontSmall = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSizeSmall, null, 256);
|
||||
Theme.FontLarge = Raylib.LoadFontFromMemory(".ttf", (.)&Theme.Din, Theme.Din.Count, Theme.FontSizeLarge, null, 256);
|
||||
|
||||
LoadAsset(Theme.Texture_Button, "button");
|
||||
LoadAsset(Theme.Texture_NButton, "n_button");
|
||||
LoadAsset(Theme.Texture_SquareButton, "square_button");
|
||||
|
@ -58,8 +62,12 @@ class Textures
|
|||
{
|
||||
Raylib.BeginDrawing();
|
||||
Raylib.BeginTextureMode(_Textures[@i.Index]);
|
||||
#if BF_PLATFORM_WINDOWS || BF_PLATFORM_LINUX
|
||||
var img = Raylib.LoadTextureFromImage((.)res.id);
|
||||
Raylib.DrawTexturePro(img, .(0, 0, img.width, -img.height), .((.)res.rc[0], 2048 - res.rc[1] - (.)res.rc[3], img.width, img.height), .(0, 0), 0, Raylib.WHITE);
|
||||
#elif BF_PLATFORM_WASM
|
||||
var img = Raylib.LoadTextureFromImage((Image)res.id);
|
||||
#endif
|
||||
Raylib.DrawTexturePro(img, Rectangle(0, 0, img.width, -img.height), Rectangle((.)res.rc[0], 2048 - res.rc[1] - (.)res.rc[3], img.width, img.height), Vector2(0, 0), 0, Raylib.WHITE);
|
||||
Raylib.EndTextureMode();
|
||||
Raylib.EndDrawing();
|
||||
Raylib.UnloadTexture(img);
|
||||
|
@ -86,7 +94,7 @@ class Textures
|
|||
{
|
||||
public Node[2] childs = .(null, null);
|
||||
public uint64[4] rc = .(0, 0, 2048, 2048); //x,y, width, height
|
||||
public Image? id = null;
|
||||
public Image? id;
|
||||
|
||||
public Node Insert(Image toInsert)
|
||||
{
|
||||
|
@ -162,6 +170,6 @@ struct sprite
|
|||
|
||||
public void Render(float x, float y, Color color = Raylib.WHITE)
|
||||
{
|
||||
Raylib.DrawTexturePro(*Source, SourceRect, .(x + Width / 2, y + Height / 2, Width, Height), .(Width / 2, Height / 2), Rotation, color);
|
||||
Raylib.DrawTexturePro(*Source, SourceRect, Rectangle(x + Width / 2, y + Height / 2, Width, Height), Vector2(Width / 2, Height / 2), Rotation, color);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue