ZAB909 / ChapterMaster

13 stars 29 forks source link

UI rework #224

Closed AtlaStar closed 12 months ago

AtlaStar commented 1 year ago

This starts the process of revamping how all user interfaces are interacted with, who owns each ui element, etc.

Currently has the most basic of behaviors for creating a graph of nodes so that rendering the root renders all children elements, runtime swapping of nodes in the graph, as well as dynamically adding and removing event or render components from a leaf in the graph.

The structure is that a UINode type can have multiple children UINodes. Each UINode can have multiple components that control events like global keypresses, mouse buttons being pressed within the node or globally, or components that render text or sprites.

Creating the graph and adding components to a node follows a builder-esque paradigm, in that there is a fluent interface provided so that functions chain to allow things like the following


//This emulates the logic used in the drawing of the star system name. Some extra things exist here due to timings of alarms 
//versus when the component is made, which is something to eventually fix.
var text_component_name = name + "_TextRenderer"
var on_hover_name = name +  "_OnHover"
star_ui_node.add_component(UITextRendererComponent, text_component_name)
        .set_text(name)
        .set_callback(method(NUIComponent(text_component_name), function() {
            static colors = [
                c_white,
                c_gray,
                c_red,
                c_red,
                c_white,
                33023,
                38144,
                117758,
                7492269,
                c_purple,
                65408
            ]
            creator_inst = owner.creator
            static gradient_color =  make_color_rgb(10,10,10)
            if obj_controller.zoomed {
                set_xscale(2)
                set_yscale(2)
            } else {
                set_xscale(1.3)
                set_yscale(1.3)
            }
            text = creator_inst.name
            var idx = clamp(creator_inst.owner - 1, 0, array_length(colors))
            set_vertical_gradient(colors[idx], gradient_color)

            if creator_inst.owner == 1 {
                set_color_solid(colors[idx])
                font_enable_effects(font,true, {
                    glowEnable: true,
                    glowEnd: 3,
                    glowColor: c_blue
                })
            } else {
                font_enable_effects(font, false)
                set_vertical_gradient(colors[idx], gradient_color)
            }
        }))
        .set_font(fnt_menu)
        .set_valign(fa_bottom)
        .set_halign(fa_center)
        .finalize()

The above is an example of creating a UITextRendererComponent and providing it a non-default name. Then the text to render is set to the name variable of the calling context (in this case obj_star) Next a callback function is added that is bound to the text component we added previously rather than the where we declared this anon function, so that what is in scope will be that text component rather than an obj_star instance. Lastly it sets some properties like the font to use, and alignment, and call finalize with returns the UINode that we just added the component to, allowing you to add further components or call other methods of that UINode

Work to be done; currently this doesn't solve the original issue of needing hard coded parameters to define the bounding rect of a UI node, but the intent is to wrap UINode in some other builder to provide flexbox functionality and provide further ease of use.

AtlaStar commented 1 year ago

Also, still need to add feather jsdoc style stuff for the methods to assist with type checking, etc.

AtlaStar commented 12 months ago

Closing as omnibus PR that contained this was merged