User Interfaces

This topic discusses the creation of graphical user interfaces in OPENRNDR applications.

The Panel library

The Panel library provides an HTML/CSS like user interface toolkit and is written using OPENRNDR.

Basic Usage

The easiest way to use Panel is to use it as a Program extension. When used as an extension all mouse and keyboard events are automatically handled and drawing of the user interface will take place after your program’s draw() has been invoked.

To create a very simple user interface that consists of just a single button one would do the following:

../media/ui-001.jpg

fun main() = application {
    program {
        var color = ColorRGBa.GRAY.shade(0.250)
        extend(ControlManager()) {
            layout {
                button {
                    label = "click me"
                    // -- listen to the click event
                    clicked {
                        color = ColorRGBa(Math.random(), Math.random(), Math.random())
                    }
                }
            }
        }
        extend {
            drawer.clear(color)
        }
    }
}

Link to the full example

Style sheets

The Panel library borrows a lot of ideas from HTML/CSS based layouting systems, one of those ideas is style sheets.

Style sheets can be used as shown in the following example in which a style sheet is used to color a button pink.

../media/ui-002.jpg

fun main() = application {
    program {
        extend(ControlManager()) {
            styleSheet(has type "button") {
                background = Color.RGBa(ColorRGBa.PINK)
                color = Color.RGBa(ColorRGBa.BLACK)
            }
            
            layout {
                button {
                    label = "click me"
                }
            }
        }
    }
}

Link to the full example

Selectors

The following example shows how to build and use complex selectors

fun main() = application {
    program {
        styleSheet(has class_ "control-bar") {
            descendant(has type "button") {
                width = 100.percent
            }
            
            child(has type "slider") {
                width = 100.percent
                
                and(has state "hover") {
                    background = Color.RGBa(ColorRGBa.RED)
                }
            }
        }
    }
}

Elements

The Panel library comes with a built-in set of elements with which user interfaces can be composed.

Element

Element is the base class from which all other elements derive. Element can be used directly but it is advised to use Div instead.

Div

The Div represents a rectangular area in which other elements can be placed. The Div element is the main ingredient in the creation of layouts. Divs are best created using the div {} builder.

fun main() = application {
    program {
        controlManager {
            layout {
                div("some-class-here", "another-class-here") {// -- children here
                }
            }
        }
    }
}

Button

An ordinary labelled button. The default width of buttons is set to Auto such that the width is determined by the label contents.

../media/ui-006.jpg

fun main() = application {
    program {
        extend(ControlManager()) {
            layout {
                button {
                    label = "Click me "
                    events.clicked.listen {// -- do something with the clicked event
                    }
                }
            }
        }
        extend {
            drawer.clear(ColorRGBa.GRAY.shade(0.250))
        }
    }
}

Link to the full example

Slider

A horizontal labelled slider control.

Properties
  • label : String - the slider label
  • precision : Int - the number of digits behind the point, set to 0 for an integer slider
  • range: Range - the slider range, default is Range(0.0, 10.0)
  • value : Double - the slider value
Events
  • valueChanged - emitted when the slider value has changed

../media/ui-007.jpg

fun main() = application {
    program {
        extend(ControlManager()) {
            layout {
                slider {
                    label = "Slide me"
                    range = Range(0.0, 1.0)
                    value = 0.50
                    precision = 2
                    events.valueChanged.listen {
                        println("the new value is ${it.newValue}")
                    }
                }
            }
        }
    }
}

Link to the full example

Since the value is clamped to the current range, it is better to set the range before the value to avoid unexpected results.

ColorPickerButton

A button like control that slides out a HSV color picker when clicked

Properties
  • label : String - the label on the button
  • value : ColorRGBa - the currently picked color
Events
  • valueChanged - emitted when a color is picked

../media/ui-008.jpg

fun main() = application {
    program {
        extend(ControlManager()) {
            layout {
            
                colorpickerButton {
                    label = "Pick a color"
                    color = ColorRGBa.PINK
                    events.valueChanged.listen {
                        println("the new color is ${it.color}")
                    }
                }
            }
        }
    }
}

Link to the full example

A button like control that slides out a list of items when clicked.

Properties
  • label : String - the label on the button
  • value : Item - the currently picked item
Events
  • valueChanged - emitted when an option is picked

../media/ui-009.jpg

fun main() = application {
    program {
        extend(ControlManager()) {
            layout {
                dropdownButton {
                    label = "Option"
                    
                    item {
                        label = "Item 1"
                        events.picked.listen {
                            println("you picked item 1")
                        }
                    }
                    
                    item {
                        label = "Item 2"
                        events.picked.listen {
                            println("you picked item 2")
                        }
                    }
                }
            }
        }
    }
}

Link to the full example

edit on GitHub