Template: FontIconBlock

This subsection will describe an OrbTk UI element called FontIconBlock.

The complete source that demonstrates this template element is presented in Listing 7-1. After a successful compile run, it should produce a window analog to the attached screen-shot:

We did compile for a desktop target (Linux). And if you did clone the book source to your development system, the corresponding source-code examples can be found inside the listings sub-directory. To compile it yourself, first change into this directory

src/listings/ch03-07-widget-font-icon-block/listing-07-01

Next, use cargo to pipeline the compile and linking process. In the end the target binary will be executed. If you like to get a rendered output, that annotates the tree structure with respect to their bounds, please make use of the feature debug. This feature will draw blue boxes around any involved entities.

$ cargo run --features debug --bin orbtk_widget_font_icon_block

Recap and annotation

The anatomy of this template

Let’s review the relevant parts of the orbtk_widget_font_icon_block application.

OrbTk code framing the app

As a first step, We put the needed OrbTk parts into scope.

use orbtk::{
    prelude::*,
    widgets::themes::theme_orbtk::{
        {colors, material_icons_font},
        theme_default_dark,
    },
};

Next we do declare "str" constants to any involved id’s. This isn’t strictly necessary, but helps to identify the entities by meaningful names.

pub static ID_FONT_ICON_BLOCK_CONTAINER: &str = "FontIconBlockContainer";
pub static ID_FONT_ICON_BLOCK_VIEW: &str = "FontIconBlockView";
pub static ID_FONT_ICON_BLOCK_STACK: &str = "FontIconBlockStack";
pub static ID_FONT_ICON_BLOCK_TEXT_BLOCK_HEADER: &str = "FontIconBlockTextBlockHeader";
pub static ID_FONT_ICON_BLOCK_STYLED: &str = "FontIconBlockStyled";
pub static ID_WINDOW: &str = "FontIconBlock_Window";

The main function instantiates a new application, that makes use of the theme_default_dark and a re-sizable Window as its first children. For a deeper insight into this UI elements, please consult the relevant part in this book.

We will now focus our interest on the next part, where we do create a FontIconBlockView as a child inside the Window entity.

                .child(
                    FontIconBlockView::new()
                        .id(ID_FONT_ICON_BLOCK_VIEW)
                        .name(ID_FONT_ICON_BLOCK_VIEW)
                        .min_width(120.0)
                        .build(ctx),
                )

The syntax advises the compiler, to implement a FontIconBlockView for the Template trait. The widget!() macro relieves us to type out all the boiler plate stuff and takes care to create the needed code sugar.

// Represents a FontIconBlock widgets.
widget!(FontIconBlockView {});

We do use a Container widget as a first child inside the template method. It allows us, to place a padding around the included children. Please refer to its documentation section for a deeper dive.

            .child(
                Container::new()
                    .id(ID_FONT_ICON_BLOCK_CONTAINER)
                    .name(ID_FONT_ICON_BLOCK_CONTAINER)
                    //.background(colors::BOMBAY_COLOR)
                    .background("lightgray")
                    .border_brush(colors::BOMBAY_COLOR)
                    .border_width(2)
                    // padding definition:
                    // as touple clockwise (left, top, right, bottom)
                    .padding((36, 16, 36, 16))
                    .min_width(140.0)

The container will have a Stack child, that we do consume to attach multiple children in a vertical direction. A TextBlock is used to render a header text above the FontIconBlock child. This is the part of the code, that we are finally interested in.

OrbTk widget specific: FontIconBlock

We are going to consume a font_icon_block widget.

As any other template inside the widget tree of OrbTk, the template is rendered with a preset of sane property values. If you choose not to explicitly declare any property values inside the view code, the defaults coded in the template definition will be evaluated.

The following Class-Diagram presents the font_icon_block internal widget tree, including its default property values:

classDiagram

Parent --o FontIconBlock

FontIconBlock

FontIconBlock : style("font-icon-block")
FontIconBlock : icon("")
FontIconBlock : icon_brush(colors->LINK_WATER_COLOR)
FontIconBlock : icon_font("MaterialIcons-Regular")
FontIconBlock : icon_size(orbtk_fonts->Icon_FONT_SIZE_12)

Workflow 7-1: FontIconBlock tree

If you uncomment the “.style()” property, all explicitly defined properties inside the view are rendered useless. The properties assingned via a theme definition take precedence over property definitons inside the view code.

                            .child(
                                FontIconBlock::new()
                                    .id(ID_FONT_ICON_BLOCK_STYLED)
                                    .name(ID_FONT_ICON_BLOCK_STYLED)
                                    //.style("font-icon-block")
                                    .h_align("center")
                                    .icon(material_icons_font::MD_360)
                                    .icon_brush("repeating-linear-gradient(0.25turn, rgba(255, 255, 0, 0.6), dodgerblue, deepskyblue)")
                                    .icon_font("MaterialIcons-Regular")
                                    .icon_size(128.0)
                                    .build(ctx),
                            )
                            .build(ctx),

Complete example source

Find attached the complete source code for our orbtk_widget_button example.

use orbtk::{
    prelude::*,
    widgets::themes::theme_orbtk::{
        {colors, material_icons_font},
        theme_default_dark,
    },
};

pub static ID_FONT_ICON_BLOCK_CONTAINER: &str = "FontIconBlockContainer";
pub static ID_FONT_ICON_BLOCK_VIEW: &str = "FontIconBlockView";
pub static ID_FONT_ICON_BLOCK_STACK: &str = "FontIconBlockStack";
pub static ID_FONT_ICON_BLOCK_TEXT_BLOCK_HEADER: &str = "FontIconBlockTextBlockHeader";
pub static ID_FONT_ICON_BLOCK_STYLED: &str = "FontIconBlockStyled";
pub static ID_WINDOW: &str = "FontIconBlock_Window";

fn main() {
    // Asure correct initialization, if compiling as a web application
    orbtk::initialize();

    Application::new()
        .theme(
            theme_default_dark()
        )
        .window(|ctx| {
            Window::new()
                .id(ID_WINDOW)
                .name(ID_WINDOW)
                .title("OrbTk-Book - Widget FontIconBlock")
                .position((100.0, 100.0))
                .size(290.0, 200.0)
                .resizable(true)
                .child(
                    FontIconBlockView::new()
                        .id(ID_FONT_ICON_BLOCK_VIEW)
                        .name(ID_FONT_ICON_BLOCK_VIEW)
                        .min_width(120.0)
                        .build(ctx),
                )
                .build(ctx)
        })
        .run()
}

// Represents a FontIconBlock widgets.
widget!(FontIconBlockView {});

impl Template for FontIconBlockView {
    fn template(self, _id: Entity, ctx: &mut BuildContext) -> Self {
        self.id(ID_FONT_ICON_BLOCK_VIEW)
            .name(ID_FONT_ICON_BLOCK_VIEW)
            .child(
                Container::new()
                    .id(ID_FONT_ICON_BLOCK_CONTAINER)
                    .name(ID_FONT_ICON_BLOCK_CONTAINER)
                    //.background(colors::BOMBAY_COLOR)
                    .background("lightgray")
                    .border_brush(colors::BOMBAY_COLOR)
                    .border_width(2)
                    // padding definition:
                    // as touple clockwise (left, top, right, bottom)
                    .padding((36, 16, 36, 16))
                    .min_width(140.0)
                    .child(
                        Stack::new()
                            .id(ID_FONT_ICON_BLOCK_STACK)
                            .name(ID_FONT_ICON_BLOCK_STACK)
                            .spacing(8)
                            .child(
                                TextBlock::new()
                                    .id(ID_FONT_ICON_BLOCK_TEXT_BLOCK_HEADER)
                                    .name(ID_FONT_ICON_BLOCK_TEXT_BLOCK_HEADER)
                                    .font_size(18)
                                    // generic color names:
                                    // constants from crate `utils` -> colors.txt
                                    .foreground("black")
                                    .text("Font icon block")
                                    .build(ctx),
                            )
                            .child(
                                FontIconBlock::new()
                                    .id(ID_FONT_ICON_BLOCK_STYLED)
                                    .name(ID_FONT_ICON_BLOCK_STYLED)
                                    //.style("font-icon-block")
                                    .h_align("center")
                                    .icon(material_icons_font::MD_360)
                                    .icon_brush("repeating-linear-gradient(0.25turn, rgba(255, 255, 0, 0.6), dodgerblue, deepskyblue)")
                                    .icon_font("MaterialIcons-Regular")
                                    .icon_size(128.0)
                                    .build(ctx),
                            )
                            .build(ctx),
                    )
                    .build(ctx),
            )
    }
}

Listing 7-2: orbtk_widget_button - Available button styles.

Compiling and Running Are Separate Steps

The cargo compiled orbtk_widget_font_icon_block binary will be placed in the target subfolder of the project.

$ cargo build --release --bin orbtk_widget_font_icon_block
$ ../target/release/orbtk_widget_font_icon_block

On Windows, you need to use backslash as a path delimiter:

> cargo build --release --bin orbtk_widget_font_icon_block
> ..\target\release\orbtk_widget_font_icon_block.exe