QUICK REFERENCE: Button

Similar to the StandardMaterial reference tables I created, here’s a table that roughly groups Button properties by purpose. It helps me quickly find relevant properties on the Button GUI control.

Visual Position & Size & Layout Interactivity Programming
BASIC SIZE ACTION (c) constructor
(P) gradient (P) width (P) onFocusObservable (M) CreateImageButton
(P) color (P) widthInPixels (P) onBlurObservable (M) CreateImageOnlyButton
(P) alpha (P) horizontalAlignment (P) onEnabledStateChangedObservable (M) CreateImageWithCenterTextButton
(P) AllowAlphaInheritance (P) adaptWidthToChildren (P) onIsVisibleChangedObservable (M) CreateSimpleButton
(P) thickness (P) AddHeader
(P) background (P) height (P) isHighlighted
(P) backgroundGradient (P) heightInPixels (P) isVisible (P) metadata
(P) verticalAlignment (P) isEnabled (P) name?
ROUNDED (P) adaptHeightToChildren (P) uniqueId
(P) cornerRadius (M) focus (P) useBitmapCache
(P) cornerRadiusW (P) fixedRatio (M) blur (P) Accessors
(P) cornerRadiusX (P) fixedRatioMasterIsWidth (M) keepsFocusWith (P) renderToIntermediateTexture
(P) cornerRadiusY (P) isFocusInvisible (P) host
(P) cornerRadiusZ (M) getDimension (P) isHitTestVisible
(M) isDimensionFullyDefined (M) _flagDescendantsAsMatrixDirty
INTERACTION VISUALS POINTER (M) clone
(P) hoverCursor POSITION (P) onPointerClickObservable (M) dispose
(P) focusedColor (P) top (P) onPointerDownObservable
(P) disabledColor (P) topInPixels (P) onPointerEnterObservable (P) typeName
(P) disabledColorItem (P) left (P) onPointerMoveObservable (M) getAscendantOfClass
(P) highlightColor (P) leftInPixels (P) onPointerOutObservable (M) getClassName
(P) highlightLineWidth (M) moveToVector3 (P) onPointerUpObservable
(M) linkWithMesh (P) onWheelObservable (M) isReady
SHADOW (P) linkOffsetX (P) isPointerBlocker
(P) shadowBlur (P) linkOffsetXInPixels (P) delegatePickingToChildren (M) markAllAsDirty
(P) shadowColor (P) linkOffsetY (M) _onPointerPick (M) markAsDirty
(P) shadowOffsetX (P) linkOffsetYInPixels
(P) shadowOffsetY (P) linkedMesh (P) animations (M) serialize
(P) pointerDownAnimation (M) parse
TEXT (A) centerX (P) pointerEnterAnimation (M) Parse
(P) style (A) centerY (P) pointerOutAnimation
(P) fontFamily (P) pointerUpAnimation (P) onAfterDrawObservable
(P) fontOffset (M) getLocalCoordinates (P) onBeforeDrawObservable
(P) fontSize (M) getLocalCoordinatesToRef KEYBOARD (P) notRenderable
(P) fontSizeInPixels (M) getParentLocalCoordinates (P) tabIndex
(P) fontStyle (M) processKeyboard (P) onControlAddedObservable
(P) fontWeight PADDING (P) accessibilityTag (P) onControlRemovedObservable
(M) setPadding (P) onEnterPressedObservable (P) onDirtyObservable
CONTROLS HIERARCHY (M) setPaddingInPixels (P) onKeyboardEventProcessedObservable (P) onDisposeObservable
(P) textBlock (P) paddingBottom (P) onAccessibilityTagChangedObservable
(P) image (P) paddingBottomInPixels (P) isSerializable
(P) paddingLeft (P) isDirty
(M) addControl (P) paddingLeftInPixels (P) isReadOnly
(M) clearControls (P) paddingRight
(M) removeControl (P) paddingRightInPixels
(P) paddingTop
(P) children (P) paddingTopInPixels
(P) clipChildren (P) descendantsOnlyPadding
(P) clipContent
(M) contains ALIGNMENT
(M) containsControl (P) HORIZONTAL_ALIGNMENT_CENTER
(P) HORIZONTAL_ALIGNMENT_LEFT
(P) parent (P) HORIZONTAL_ALIGNMENT_RIGHT
(M) isAscendant (P) VERTICAL_ALIGNMENT_BOTTOM
(M) getChildByName (P) VERTICAL_ALIGNMENT_CENTER
(M) getChildByType (P) VERTICAL_ALIGNMENT_TOP
(M) getDescendants
(M) getDescendantsToRef OVERLAP
(P) overlapDeltaMultiplier?
POST-LAYOUT (P) overlapGroup?
(P) rotation (P) zIndex
(P) scaleX (P) maxLayoutCycle
(P) scaleY (P) logLayoutCycleErrors
(P) transformCenterX
(P) transformCenterY
(P) transformedMeasure
3 Likes

For future reference, I’ve categorized the Button properties above into possible “styles.” That is, these groupings might be suitable for a future expansion of the .style property to include more than fonts. The maintenance of the current style property seems pretty high, though.

I think it would be useful to capture and/or copy the following properties from one control to another to create visually-similar controls. I’ve tried to capture properties that are common across intances of the control, that are not composite, and are not setters of other exposed properties. I’m not sure of how styleCategories might best be used. Maybe if a user only wants to capture specific types of properties from a source control?

These are based on Button. Maybe these are also expandable to a few other control types.

Style Category Button Property
Visual
BASIC
styleVisual (P) gradient
styleVisual (P) color
styleVisual (P) alpha
styleVisual (P) AllowAlphaInheritance
styleVisual (P) thickness
styleVisual (P) background
styleVisual (P) backgroundGradient
styleVisual ROUNDED
styleVisual (P) cornerRadiusW
styleVisual (P) cornerRadiusX
styleVisual (P) cornerRadiusY
styleVisual (P) cornerRadiusZ
styleVisual INTERACTION VISUALS
styleVisual (P) hoverCursor
styleVisual (P) focusedColor
styleVisual (P) disabledColor
styleVisual (P) disabledColorItem
styleVisual (P) highlightColor
styleVisual (P) highlightLineWidth
styleVisual SHADOW
styleVisual (P) shadowBlur
styleVisual (P) shadowColor
styleVisual (P) shadowOffsetX
styleVisual (P) shadowOffsetY
TEXT
styleFont (P) fontFamily
styleFont (P) fontOffset
styleFont (P) fontSize
styleFont (P) fontStyle
styleFont (P) fontWeight
POST-LAYOUT
styleTransform (P) rotation
styleTransform (P) scaleX
styleTransform (P) scaleY
styleTransform (P) transformCenterX
styleTransform (P) transformCenterY
CONTROLS HIERARCHY
styleClip (P) clipChildren
styleClip (P) clipContent
Position & Size & Layout
SIZE
styleSize (P) width
styleSize (P) adaptWidthToChildren
styleSize (P) height
styleSize (P) adaptHeightToChildren
styleSize (P) fixedRatio
styleSize (P) fixedRatioMasterIsWidth
POSITION
styleAlignment (P) horizontalAlignment
styleAlignment (P) verticalAlignment
styleLinkOffset (P) linkOffsetX
styleLinkOffset (P) linkOffsetY
PADDING
stylePadding (P) paddingBottom
stylePadding (P) paddingLeft
stylePadding (P) paddingRight
stylePadding (P) paddingTop
stylePadding (P) descendantsOnlyPadding
OVERLAP
styleOverlap (P) overlapDeltaMultiplier?
styleOverlap (P) overlapGroup?
styleOverlap (P) maxLayoutCycle
styleOverlap (P) logLayoutCycleErrors
Interactivity
ACTION
styleInteract (P) isFocusInvisible
styleInteract (P) isHitTestVisible
POINTER
styleInteract (P) isPointerBlocker
styleInteract (P) delegatePickingToChildren
1 Like

Yes. That rings a bell for me. I quite well remember I made this suggestion of extending the common ‘styling’ properties, which at the moment, are still minimal. Although, of course, you can still create your own classes for styling. Let’s face it: It didn’t make it through (for some reason). It seems hard to find a compromise for certain things like this. Here, I have to also think about the ‘styled’ textBlock that never quite made it through as a standard. I’m not sure how much effort would be required and what better arguments than those already stated would help make this ‘nice to have’ go up in the agenda. I would support it. I do support it :grinning:

Sidenote: Nice tables you did there. Not always easy to find a match and organize. Must have taken you quite a bit of time :sweat_smile:. Respect :hugs:

Thank you! A few months ago, the class’ page format allowed me to copy/paste from the page into google sheets with newlines between properties. The current format doesn’t paste well at all and requires going through PDF to paste all the property names.

After that, I organize the Sheet by hand to categorize each property. And then convert to markdown.

For styles, I just wrote the following to apply all the named properties, not fully tested but seems to work. Doing it this way allows the function to be used on any control types (even different ones) as long as there are no listed properties that exist on the “toControl” that shouldn’t be set. So this probably works on Control, Rectangle, toggleButton, and maybe others.

function applyStyleToFrom(toControl, fromControl) {
    const styleProperties = Array.from([
    'gradient', 'color', 'alpha', 'AllowAlphaInheritance', 'thickness', 'background', 'backgroundGradient', 'cornerRadius', 'cornerRadius', 'cornerRadius', 'cornerRadiusZ', 'hoverCursor', 'focusedColor', 'disabledColor', 'disabledColorItem', 'highlightColor', 'highlightLineWidth', 'shadowBlur', 'shadowColor', 'shadowOffsetX', 'shadowOffsetY', 'fontFamily', 'fontOffset', 'fontSize', 'fontStyle', 'fontWeight', 'rotation', 'scaleX', 'scaleY', 'transformCenterX', 'transformCenterY', 'clipChildren', 'clipContent', 'width', 'adaptWidthToChildren', 'height', 'adaptHeightToChildren', 'fixedRatio', 'fixedRatioMasterIsWidth', 'horizontalAlignment', 'verticalAlignment', 'linkOffsetX', 'linkOffsetY', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'descendantsOnlyPadding', 'overlapDeltaMultiplier', 'overlapGroup', 'maxLayoutCycle', 'logLayoutCycleErrors', 'isFocusInvisible', 'isHitTestVisible', 'isPointerBlocker', 'delegatePickingToChildren',
    ])        
    
    styleProperties
        .filter(p=>p in toControl && p in fromControl)
        .forEach(p=>toControl[p] = fromControl[p])
}

Using (after physicsButton is set up):

const resetButton = BABYLON.GUI.Button.CreateSimpleButton("reset", "Reset Rotation")
applyStyleToFrom(resetButton,physicsButton)

In action:

1 Like

I would assume so. I would assume it would be possible (and fairly ez to create a ‘base’ of a class for styling both controls and containers. And as you demonstrate here, it is (still requires additional effort, though). And people don’t like efforts :sweat_smile: :joy:. They’d rather switch to their known standard of using html/css/dom than doing much more or different. Eventually, they’ll even call it ‘a hack’. Reason why I wanted to push for this sort of things… but somehow, it doesn’t seem to be something ‘critical’ so I didn’t harass the Team with it. But as I said, if others do, you have my full support for this. And may be we can find some other way to work it as a community project? @tricotou is already kind of leading the community towards pushing for the BJS GUI. May be together we can try improve some aspects (information, samples, tutorials, …etc). I’m pretty sure a number of people could make use of this. Or may be it’s just me? :face_with_hand_over_mouth: :grin:

Adding to the list of properties should make this function work for TextBlock and it will continue to work for the other controls:

  • adjustWordWrappingHTMLElement
  • reuseHTMLForWordWrapping
  • useBitmapCache (maybe?)
  • wordSplittingFunction
  • applyOutlineToUnderline
  • forceResizeWidth
  • lineSpacing
  • lineThrough
  • textHorizontalAlignment
  • textVerticalAlignment
  • textWrapping
  • underline
  • wordDivider

What other functions would you want for a styling class? Maybe snapshot a control’s “style” into a separate (and non-changing) Object, and be able to apply it to a control? This would also enable creating a style outside of a Control object to apply later. That said, it kind of works great as is.

1 Like

WoW. :smiling_face_with_three_hearts: I can see you already had some thoughts about it. It would take some time and more people and cases to answer your question: ‘What more’… But more is not always better. ‘More’ can actually kill a project. I assume this is what happened with the ‘styled textBlock’. Just like this and for just now, my two-cents would be ‘Let’s try make it a base’, a SOLID base - for a start with. Where ‘more’ can always come later. Of course, my opinion only :smiley:

Updated to class (with one static method) and added properties to also work with TextBlock.

class NewStyle {
    static ApplyStyleToFrom(toControl, fromControl) {
    //...
    }

Usage:

NewStyle.ApplyStyleToFrom(resetButton,physicsButton)

Edit: might be even better if it used decorators (@style added to properties in each Control’s source code), perhaps with a style type that allowed users to copy a particular subset of “styled” properties.

1 Like

Do you think you could push this to a PG non-related to physics and your other project?
Just a simple GUI PG so we can focus on this particular topic? I think that would be helpful.
As much as I’m eager to discuss this further, I cannot today. I need to leave, for I have a number of things to do and won’t be able to catch-up before tomorrow morning :cry:
I would also very much want to hear from some others. In particular tricotou but also @jamessimo and other BJS GUI advocates and specialists. I think we shouldn’t try to ‘rush it’. To me, there’s obviously space for improvement and together we should be able to make some good progress towards a more straight-forward and ‘normalized’ approach of ‘styling’ the BJS GUI (I think so) :thinking: :sweat_smile: Let’s may be try gather a few people and thoughts and see what come out of it… if that’s ok with you?

Edit: I believe before pushing this too much further, we should next also check with the Team, ie. @PatrickRyan, See what the plans are for v8 and for X. Better to try put our efforts where they will pay-off, integrate and keep with the overal consistency. Again, my opinion only :smiley:

I do like the idea of only having to style a button once than having the other buttons inherit the style. But for my use case I would rather create an agnostic buttonstyle then apply that to any buttons in or after they are created, rather have a daisy chain where all buttons need to call a copy paste function. Like css classes.

You can do that with NewStyle class by using a source Control that is not added to the GUI:

But it would be nice to extract/create an abstract Object that can contain properties for all Controls that can then be applied to any control. I think the “fromControl” function parameter can already be used on such an object. Let me add a function to “extract and add” properties to a given object and I think that might be a good start (finish?).

I’ve updated to include:

  • force - parameter when true will disregard whether destination object contains the parameter (forces creation of that parameter)
  • returns the toObject to allow chaining

Should be able to do something like this (note the last example):

// @example ApplyStyleToFrom(button2,button1)
// @example ApplyStyleToFrom(rectangle,button1)
// @example const savedStyle = ApplyStyleToFrom(Object(),button1,true)
// @example ApplyStyleToFrom(savedStyle,textBlock,true); // update saved style
// @example const styledButton = NewStyle.ApplyStyleToFrom(BABYLON.GUI.Button.CreateSimpleButton(name, text), firstButton)

Very close to an additional parameter to CreateSimpleButton().

Very untested:

(edit: added examples in playground comments above function)

And to address (a little bit) copy/paste on each button separately, the following function will copy to a multitude (untested, but will be in the next playground):

static ApplyStyleToArrayFrom(toArray, fromControl,force=false) {
    for (var toControl of toArray) {
        ApplyStyleToFrom(toControl,fromControl,force)
    }
    return toArray; // not sure if/how this return value is useful
}

Hopefully this update is a plateau, of sorts.

  • Needed to add the composite parameter cornerRadius. I think the order of properties in the list needs to have composite properties before specific properties “contained” within the composite. Hopefully this is all that is necessary to properly style a control.
  • List of style parameters elevated to class object. This might allow changing them for all subsequent function calls.
  • Testing ApplyStyleToArrayFrom(), tap “change” button after tapping a few color buttons and new cornerRounding is applied to all the text boxes/rectangles.
  • Tested plain object as a source of properties.

Still need to work out:

  • Does there also need to be an instance-based property list?
  • Does this need to be converted to allow an instance of NewStyle to carry, essentially, a set of properties and values? Properties and values can currently be carried by a standard JavaScript Object().
  • how this can be integrated with Control classes. I expect this would be a .newStyle setter.
  • how undefined parameters are treated (I think these should be ok)
  • how null parameters are treated (including when null is in source or destination or both)
  • (Edit to add:) this currently ignores top/left positioning because I originally thought users wouldn’t copy another object’s position and allowing for setting a position then copying the style. To extend this to handle applying CSS style objects requires also applying positioning properties. This only affects the case where a style includes top/left positioning and the control already contains properties needing to be retained. For top/left positioning, it’s probably sufficient to implement “last assigned is retained” such that order of style vs specific top/left is relevant. I think this is already how CSS styles work.

Here are links to posts discussing GUI styles (found with simple search, then search on tag:gui):