ZZYZX wrote:Hello so I made this https://github.com/jewalky/zgui
You can use it like so:What it does: it allows you to have a WM-style hierarchy of Elements with automatic scaling, clipping, text align and wrapping.Code: Select all
class Doom3Element : Element { TextureID mMouseCursor; override void OnCreate() { mRect = Rect.FromXYWH(0, 0, Screen.GetWidth(), Screen.GetHeight()); mScale = 2; mMouseCursor = TexMan.CheckForTexture("graphics/D3Mouse.png", TexMan.Type_Any); AddChild(new('Doom3Doom').Init()); } override void Draw() { Drawer d = GetDrawer(); vector2 mouse = GetMouseXY(); d.DrawTexture(mMouseCursor, false, mouse.x, mouse.y); } } class Doom3Menu : ListMenu { Element e; override void Init(Menu parent, ListMenuDescriptor desc) { Super.Init(parent, desc); DontDim = true; e = new('Doom3Element').Init(); e.OnCreate(); } override bool OnUIEvent(UiEvent ev) { if (e) return e.OnProcessUi(ev); return false; } override bool OnInputEvent(InputEvent ev) { if (e) return e.OnProcessInput(ev); return false; } override void Drawer() { if (e) e.OnDraw(); } override void Ticker() { if (e) e.OnTick(); } }
Each Element can have a position inside the parent Element (mRect field), and scale of child elements (mScale field). The scale also affects perceived width/height of the Element (the client rect).
Topmost Element has mParent=null which means that it's using the real screen coordinates and scale of 1.0.
Functions exposed to the user are these:The preferred way of constructing Elements is calling "new ('Element').Init()", for example. That automatically sets certain fields to the initial values, otherwise you might end up with a wild null pointer error.Code: Select all
virtual void OnCreate() { } virtual bool Process(ElementEvent ev) { return false; } virtual void Tick() { // } virtual void Draw() { // }
Unobviously enough, OnCreate is actually called when you add a child element, on the child. For a root element, you have to call OnCreate manually or it won't get a chance to initialize.
You can draw things by receiving an instance of Drawer class:And then using it's methods to draw things as opposed to directly using Screen.Code: Select all
Drawer d = GetDrawer();
Alternatively, you can instantiate a drawer by usingor evenCode: Select all
Drawer d = Drawer.Create(self);
The latter option is for custom Drawer classes if you want to do some fancy stuff.Code: Select all
Drawer d = Drawer.CreateMod('Drawer', self);
Also, the system doesn't care about your input/rendering backend — you can provide OnProcessUi/OnProcessInput/OnTick by an event handler, and OnDraw by DrawPowerup (I blame Graf for consistently removing any ways to draw anything while playing the game and providing no alternative), or you can do all this in a menu.
The system is able to receive mouse input both from UiEvent and InputEvent — the elements will receive an uniform ElementEvent anyway. This means that it transparently supports both enabled and disabled mouse in menus.
ElementEvent is the same as UiEvent, except there is no information about pressed modifier keys (yet?)
Also, you can receive the current mouse coordinates relative to the current element (including all scaling) by using GetMouseXY() — which returns a vector2, see the example.
What it doesn't have yet is setting arbitrary clipping values in a Drawer. That'll be added eventually.
Added, actually.
The system is kinda new and untested, pls report bugs if anyone is actually going to use this.
ZZYZX: That needs to be on its own thread, and a simple user-runnable example please! Sounds awesome.