Page 9 of 15
Re: ProGUI V3 Alpha 2.1 Ready for testing!
Posted: Fri Dec 13, 2024 5:34 am
by idle
It appears to be working very well. congrats, and the color changes very in keeping with the festive season.
Re: ProGUI V3 Alpha 2.1 Ready for testing!
Posted: Fri Dec 13, 2024 7:54 pm
by PrincieD
idle wrote: Fri Dec 13, 2024 5:34 am
It appears to be working very well. congrats, and the color changes very in keeping with the festive season.
Haha yes I didn't realise that, very Christmas tree lights
There are actually 2 modes now for the widget caching, the first mode as shown (with funky xmas lights in debug mode

) when a widget doesn't have a border or the border is 'simple' i.e. a rectangle (without a mask or corner radius - which requires a mask). In the first mode the border can be baked directly into the cache. If the border needs a mask then the second mode is used where the widget is always rendered to an itermediate buffer (never rendered directly to the window surface) - if the the widget has changed size or redrawn within the previous 2 frames then the intermediate buffer is composited with the border mask onto the window surface (or parent cache), if the widget has settled for 2 frames then the widget is baked complete with border mask onto a secondary cache which is then used.
Re: ProGUI V3 Alpha 2.1 Ready for testing!
Posted: Fri Dec 13, 2024 11:10 pm
by PrincieD
Full steam ahead! (debug disabled)
https://www.youtube.com/watch?v=MsfHNiBFiHY
So this is using the new widget caching system (debug disabled). Every widget inside the window has a double border with a 10 pixel radius (so alpha masked), including the 2 webview2 widgets and Win32 button (The Electron framework can only handle one Chrome per window btw), CPU usage is around 4% to 6% peak when resizing (QT is 10% to 12%, Mozilla Thunderbird is also around 10% to 12%) - this is running on an Alienware 2014 laptop using Intel integrated GFX (11 year old hardware). I've also spanned the window across 2 monitors and resized (the poor old intel chipset is struggling with fill rate) however there are no graphical artifacts or glitching, everything is rock-steady and it's a DirectX 11 window with a Direct2D fully GPU driven back-end. The top monitor is a Samsung TV btw with DPI scaling set 125% - so DPI scaling is also rock solid.
Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Fri Dec 20, 2024 6:10 pm
by PrincieD
Alpha 3 released! see top of thread

Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Sat Dec 21, 2024 12:09 am
by idle
That's looking really good and that's great performance your getting.

Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Sun Dec 29, 2024 3:31 am
by PrincieD
idle wrote: Sat Dec 21, 2024 12:09 am
That's looking really good and that's great performance your getting.
Thanks mate!

bit more work to do on the memory management side and then on to the skinning engine
P.S. Hope everyone had a good Christmas / holidays!
Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Sun Dec 29, 2024 5:04 am
by idle
just gave it a run and it's fantastic.

Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Sun Dec 29, 2024 5:17 am
by PrincieD
Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Sun Dec 29, 2024 6:15 am
by electrochrisso
Super Cool Stuff Chris, have a Happy New Year

Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Sun Dec 29, 2024 6:32 am
by PrincieD
electrochrisso wrote: Sun Dec 29, 2024 6:15 am
Super Cool Stuff Chris, have a Happy New Year
Thanks mate! you too!

Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Sun Dec 29, 2024 2:18 pm
by Mijikai
Looks really great

Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Sun Dec 29, 2024 8:34 pm
by PrincieD
Mijikai wrote: Sun Dec 29, 2024 2:18 pm
Looks really great
Thanks Mijikai!

Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Wed Jan 08, 2025 2:04 am
by PrincieD
Hi guys,
Proper memory management is now working for widget caching (replacing the previous placeholder code). The system uses a 2D array (15x15) bucket structure, where each bucket contains a list of cached images. The indices of the array represent the width and height of the image, rounded to the nearest power of 2, allowing for a maximum image cache size of 65,536 x 65,536 pixels (since all cached images are created with dimensions as powers of 2).
Each bucket maintains a list of caches where the active (in-use) caches are always kept at the top and free caches at the bottom. When a cache is needed, the requested width and height are rounded up to the next power of 2, and the array index is calculated using bit shifting. The corresponding bucket is then accessed, and the last element of the list is checked to see if it’s free. If it’s not, a new cache is created. This provides O(1) access time without needing to search for a matching cache size.
When widgets resize, the power-of-2 sizing allows some tolerance for growth or shrinkage before requiring a different cache size. Additionally, a cacheCleanup thread runs every 30 seconds. If a cache hasn't been used for 5 minutes, its resources are freed.
Now onto the skinning engine! This is the final piece of the puzzle before the beta (and documentation). It's going to take a few days of solid thinking and planning before I start coding, as I want widgets to support state transition animations (like cross-fading). The challenge is figuring out how to make this both powerful and easy for custom widget skin components and properties.
Any ideas / suggestions welcome!

Cheers!
Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Wed Jan 08, 2025 7:34 pm
by PrincieD
Okay so I'm thinking of something like this for the internal structure:
Code: Select all
Structure SkinPropertyValue
value.s
valueData.i
EndStructure
Structure SkinStatePath
Map statePath.SkinPropertyValue()
EndStructure
Structure Skin
Map classPath.SkinStatePath()
EndStructure
mySkin.Skin
mySkin\classPath("dark:listview.header.text")\statePath("normal.background")\value = "rgb(255,255,255)"
mySkin\classPath("dark:listview.header.text")\statePath("hover.background")\value = "rgb(255,0,0)"
mySkin\classPath("dark:listview.header.text")\statePath("active.background")\value = "rgb(0,255,0)"
mySkin\classPath("dark:button")\statePath("normal.background")\value = "rgb(240,240,240)"
mySkin\classPath("dark:button")\statePath("hover.background")\value = "rgb(250,250,250)"
mySkin\classPath("dark:button")\statePath("normal.foreground")\value = "rgb(0,0,0)"
mySkin\classPath("dark:button.primary")\statePath("normal.background")\value = "rgb(0,122,255)"
What do you think guys?
Re: ProGUI V3 Alpha 3 Ready for testing!
Posted: Fri Jan 10, 2025 1:55 am
by PrincieD
Hi guys, the skinning engine is coming along nicely.
So this is an example where there's a widget created that has it's class set to "testContainer" (new WidgetSetClass() command) and there's another widget created with it's class set to "testWidget", Skin mark-up looks like this (setting the default skin, there's an optional Skin handle parameter on the end):
Code: Select all
SkinSetValue("testContainer", "background-color", "orange")
SkinSetValue("dark:testContainer", "background-color", "gray")
SkinSetValue("testContainer.testWidget", "background-color", "red")
SkinSetValue("testContainer.testWidget", "hover.background-color", "purple")
SkinSetValue("testWidget", "background-color", "green")
So when a testWidget is nested inside a testContainer it's rendered red and if not then rendered green.
And a basic widget DrawEvent handler supporting skins now looks like this:
Code: Select all
Procedure drawTestWidget(Widget, EventType, *eventData.PG_EventDraw)
WidgetGetSkinColor(Widget, "background-color", @color.l, @opacity.f)
DrawBox(0, 0, *eventData\width, *eventData\height, color, opacity)
EndProcedure
A widget will use the default skin unless set explicitly.
Current new commands:
Code: Select all
CreateSkin(Name.s)
SkinSetDefault(Skin)
SkinGetDefault()
SkinSetTheme(ThemeName.s, Skin = #Null)
SkinGetTheme(Skin = #Null)
SkinSetValue(Path.s, StateProperty.s, Value.s, Skin = #Null)
SkinGetValue(Path.s, StateProperty.s, Skin = #Null)
SkinGetData(Path.s, StateProperty.s, *ValueData.Integer, *ValueType.Integer = #Null, Skin = #Null)
SkinGetColor(Path.s, StateProperty.s, *Color.Long, *Opacity.Float, Skin = #Null)
WidgetSetClass(Widget, ClassName.s)
WidgetGetClass(Widget)
WidgetSetSkin(Widget, Skin)
WidgetGetSkin(Widget)
WidgetSetSkinState(Widget, State.s = "")
WidgetGetSkinData(Widget, Property.s, *ValueData.Integer, *ValueType.Integer = #Null)
WidgetGetSkinColor(Widget, Property.s, *Color.Long, *Opacity.Float)