Skip to content

Releases: MasterBel2/Master-GUI-Framework

Version 44-rev1: Fix `TextEntry` sending `wrappingText:DisplayIndexToRawIndex` invalid index

15 Apr 04:50

Choose a tag to compare

Version 44: Coordinate Update, Optimisation & Simplification; Text Highlight API

08 Apr 09:10

Choose a tag to compare

DrawingGroup resets coordinates to avoid unnecessarily calling Position when portions of the UI move uniformly. To support this:

  • DrawingGroup provides drawingGroup:AbsolutePosition() to move local coordinates to a global context. E.g., comparing bounds v.s. interaction in Responder.
  • (Internal detail: To performantly propagate changes to a DrawingGroup's position, DrawingGroup will call drawingGroup:SetParentGroupPosition(x, y) on its children, to inform of the new result that would be returned by drawingGroup:AbsolutePosition())
  • (Internal detail: GeometryTargets will now also register with their parent DrawingGroup (drawingGroup.childGeometryTargets) to receive geometryTarget:SetParentGroupPosition(x, y), again as a performance optimisation)
  • GeometryTarget no longer provides CachedPosition. Instead, this functionality is split out into the following API:
  • geometryTarget:CachedPositionRemainingInLocalContext()
  • geometryTarget:CachedPositionTranslatedToGlobalContext()
  • geometryTarget:CachedPositionTranslatedToContext(callerDrawingGroup)
  • geometryTarget:ContainsAbsolutePoint(x, y)
  • geometryTarget:ContainsPoint(x, y, callerDrawingGroup)
    (see Layout/GeometryTarget.lua for further details.)
  • _debug_mouseOver is now a separate event listed in framework.events.

Other architectural changes:

  • Responder, PrimaryFrame, WrappingText, and Background now inherit from GeometryTarget. See GeometryTarget for expanded interface.
  • Tooltip now inherits from Responder, and tooltip is now listed in framework.events.
  • Component now has a single associated drawing group. Let me stress, then the importance of making sure reusable tools inherit from Drawer, not Component! (Component must necessarily be contained in one single drawing group for reasons I can't remember. Maybe convenience, then.)
  • DrawingGroup advertises CachedSize now to go with AbsolutePosition - but do not be fooled, this is NOT a full implementation of GeometryTarget.
  • Remove framework.viewportDidChange. It was unused, and other, more robust methods can be used to respond to updates (e.g. AutoScalingDimension).
  • drawingGroup.needsRedraw is not set in drawingGroup:UpdateLayout(calledByParent), since it's already set in drawingGroup:UpdatePosition()
  • (Internal detail: drawingGroup.groupsNeedingLayout and drawingGroup.groupsNeedingPosition will not remove any groups until directly before drawingGroup:UpdatePosition() is called, to allow drawingGroup:Position(x, y) to trigger drawingGroup:UpdatePosition() if necessary.)

Text Highlight API:

  • WrappingText now handles the selection highlight drawing for TextEntry with a public API! See documentation in WrappingText.lua:
    • wrappingText:HighlightRange(color, startIndex, endIndex, reuseLast)
    • wrappingText:UpdateHighlight(id, color, startIndex, endIndex, reuseLast)
    • wrappingText:RemoveHighlight(id)
  • TextGroup now calls wrappingText:DrawText(glFont) rather than wrappingText:Draw(glFont) to avoid collision when DrawingGroup calls wrappingText:Draw()

Additions:

  • Dialog and ConfirmationDialog
  • Selected mode for Button. See button:SetSelected(newSelected), button:GetSelected()

Visual changes:

  • Squared-off corners at the edge of the screen have been disabled, due to drawing no longer knowing whether it's actually at the edge of the screen.
  • Round fonts to the nearest pixel size (to prevent blurry text).
  • Swap color.selectedColor and color.pressColor

Debug changes:

  • Add component._debugIdentifier for easier logging
  • Remove redundant Internal._debug_currentElementKey in favour of Internal.activeElement.key.
  • Add argument & return value validation for Position & Layout.
  • Include stacktrace for framework error messages (debug mode must be enabled, because this comes with a significant performance cost).
  • Add some tests matched to some solved dimension:Update(...) bugs.
  • Inject some profiling only when debug mode is enabled. Other profiling has been removed.
  • Some error catching has been made less fine-grained for performance reasons. With stacktraces enabled, this should not tangibly hamper debugging.
  • Drawing will terminate completely after an error, rather than completing the other passes in the element's final frame.

Bug fixes:

  • Hide MovableFrame handle when releasing outside bounds)
  • Fix over-cropping for OffsettedViewport. (I suspect this happens with height too, but so far I haven't been able to verify. There's chance the error's something else, idk.)
  • Fix bug where, when a font stopped being used in a TextGroup, it would cancel drawing for all following fonts.
  • Fix continuous updating being incompatible with calling drawingGroup:DrawerUpdated(drawer)
  • Fixed invalid declaration of Blending

Performance improvements:

  • DrawingGroup cancels drawing when it knows it will not be visible (e.g. outside of current viewport or scissor).

  • Improved caching for wrappingText:CoordinateToCharacterDisplayIndex(x, y)

  • wrappingText:DisplayIndexToRawIndex(displayIndex, addedCharactersIndex, removedSpacesIndex, computedOffset) makes use of an index cache, when a partial result isn't returned. Even when not using the cache, other optimisations have sped it up around 3x.

  • wrappingText:RawIndexToDisplayIndex(rawIndex, addedCharactersIndex, removedSpacesIndex, computedOffset) makes use of an index cache generated for trivial cost during wrappingText:Layout, when a partial result isn't returned. Likely, even for small intervals (above 4), this caching is faster than the existing partial-result mechanism in place. In the committed test, this speeds up from 0.11s @ 100 executions, to 0.061s @ 100000 executions. That's 1800x faster!

  • MouseMove is now buffered to receive only one call per draw frame. If you need more frequent updates, set dragListener.doNotBufferMouseMove to true.

Tests:

  • Introduced a test for benchmarking WrappingText methods.

Also includes further non-breaking (hopefully) optimisations and fixes.

Version 43: Limit unnecessary layout / position / draw passes

27 Jul 04:41

Choose a tag to compare

Agressive changes have been made to how updates are made to reduce the necessary fequency of calculations:

  • Rasterizer has been merged into DrawingGroup.
  • DrawingGroup now uses draw lists by default. See documentation for how to disable this, for cases where it harms performance.
  • Position can now be expected to be called more than once for some Layout calls, where sizing hasn't changed but positioning has (e.g. )
  • Even if rasterization isn't involved, Draw can be called more than once per Position/Layout call.
  • To specifically request an update to any of Layout/Position/Draw, the corresponding property may be set on the relevant DrawingGroup. See Drawer and Component for more detail and example implementations.

To facilitate this:

  • Most components that allow specifying a child no longer make their child editable; instead, when you wish to mutate a child view hierarchy, set the parent's initial child to Box, which allows its child to be changed (via Box:SetChild(newChild)).
  • Rect, MarginAroundRect, and Cell no longer draw decorations. Use Background instead to attach a background.
    (Note that Background doesn't have the rasterizing optimisation that MarginAroundRect did; instead, use nested DrawingGroups to separate the re-drawing profile of different parts of the interface hierarchy.)
  • HorizontalStack, VerticalStack, and StackInPlace no longer make their members public; instead, they must be set/get through methods that copy to/from the internal member array.
  • Other mutable properties for other component types must be changed through methods, similar to above.
  • Some properties are simply no longer mutable.
  • Dimension now has a base constructor that registers for updates with the drawing group; the previous functionality of the Dimension function has moved to AutoScalingDimension.
  • OffsettedViewport is now an overriding extension of DrawingGroup.

Changes to Menu:

  • MenuAnchor now provides menuAnchor:GetMenu() to allow accessing its menu.
  • Menu provides menu:IsMouseOver() which returns whether the user's cursor is over the menu or one of its submenus.
  • Menu's submenu menu items are now a MenuAnchor at the top level, rather than a MarginAroundRect at the top level. (This probably shouldn't be of practical concern to users of the framework.)

Misc other changes:

  • Remove elements with incomplete PrimaryFrame geometry, to prevent log spam and allow interaction
  • Various bugfixes
  • TextEntry & Button store their colours in constants, providing potential to override & set custom styles
  • PrimaryFrame no longer attempts recovery if Layout hasn't been called yet
  • Elements are removed if no PrimaryFrame is present in the view hierarchy
  • HorizontalScrollContainer and VerticalScrollContainer now use the customisable framework.dimension.scrollMultiplier to configure their scroll speed. This should provide the same scrolling experience on a 1080p display, and scale better to larger resolutions.

Version 42.1 - debugDescriptionString: fix infinite recursion avoidance, add documentation

21 Jul 01:03

Choose a tag to compare

v42.1

debugDescriptionString: fix infinite recursion avoidance, add documen…

Version 42: Misc - kill funcs.lua, separate out constants, change WG access

21 Jul 01:00

Choose a tag to compare

Extensions are now declared in MasterFramework $VERSION/Utils, and pre-loaded before the rest of the framework. These are provided the same global environment as the rest of the framework. string extensions now all have _MasterFramework at the end of their name, while the table extension overrides the Include.table table for the framework, and provides access to the customised version as framework.table. The definition of Include.clear has been moved to Utils/table.lua, and table.joinStrings() has been removed, since it was a slower reimplementation of table.concat()

Constants have been moved out of gui_master_framework.lua into separate files in the Constants/ directory. Subfiles are not automatically loaded to allow for dependencies, other than the entry point Constants/constants.lua.

The main framework files which would have been loaded in previous versions are now contained in the Framework/ directory.

The new major directories are loaded in this order: Utils/, Framework/, then Constants/.

Framework access is no longer provided as WG.MasterFramework[compatabilityVersion], instead as WG["MasterFramework " .. compatabilityVersion]. Removing the intermediate table technically simplifies this?