🎨Styling and Appearance

Paper uses a fluent, chainable API that makes it easy to apply everything from simple colors to complex gradients and interactive effects. All styling is applied in the order you call it.

Basic Styling

These are the foundational methods you'll use most often to define the basic look of your elements.

Colors and Borders

You can control the background color, border color, and border width with dedicated methods.

paper.Box("StyledBox")
    .Size(200, 100)
    .BackgroundColor(Color.CornflowerBlue)
    .BorderColor(Color.White)
    .BorderWidth(4);

Rounding Corners

The .Rounded() method allows you to soften the corners of an element. Like margins, it's highly flexible:

  • .Rounded(10): Applies a 10px radius to all four corners.

  • .Rounded(10, 0, 10, 0): Applies a 10px radius to the top-left and bottom-right corners, creating a unique shape. (Order is Top-Left, Top-Right, Bottom-Right, Bottom-Left).

paper.Box("RoundedBox")
    .Size(150)
    .BackgroundColor(Color.ForestGreen)
    .Rounded(20);

Advanced Drawing

Paper's rendering engine is capable of much more than solid colors. You can create depth and richness with gradients and shadows.

Gradients

Instead of a solid background color, you can apply a Gradient. The gradient will automatically fill the shape of the element. There are three types:

  • Linear Gradient: Blends colors along a straight line.

  • Radial Gradient: Blends colors outwards from a central point.

  • Box Gradient: A specialized gradient that creates a soft, shadowed box effect.

// A vertical linear gradient
paper.Box("LinearGradient")
    .BackgroundGradient(Gradient.Linear(0, 0, 0, 1, Color.Blue, Color.Aqua));

// A radial gradient from the center
paper.Box("RadialGradient")
    .BackgroundGradient(Gradient.Radial(0.5, 0.5, 10, 80, Color.Yellow, Color.Red));

Box Shadows

To make elements pop off the page, you can apply a .BoxShadow(). This adds a blurred, colored shadow behind the element, giving it a sense of depth.

paper.Box("ShadowBox")
    .Size(150)
    .Rounded(10)
    .BackgroundColor(Color.White)
    //         OffsetX, OffsetY, Blur, Spread, Color
    .BoxShadow(5, 5, 15, 0, Color.FromArgb(100, 0, 0, 0));

Conditional Styling: Making UIs Interactive

This is where Paper's immediate-mode nature truly shines. You can change an element's style based on its interaction state or any custom condition you define.

The pattern is simple: you start a conditional block (.Hovered, .Active, .If()), define the styles that should apply when the condition is true, and then close the block with .End().

Hover and Active States

Paper has built-in helpers for the most common interaction states.

  • .Focused: Applies styles only when the element is currently active and the focused element.

  • .Hovered: Applies styles only when the mouse cursor is over the element.

  • .Active: Applies styles only when the mouse button is being pressed down on the element.

paper.Box("InteractiveButton")
    .BackgroundColor(Color.Gray) // Default state
    .Focused
        .BackgroundColor(Color.Blue) // Focused state
        .End()
    .Hovered
        .BackgroundColor(Color.LightGray) // Hover state
        .End()
    .Active
        .BackgroundColor(Color.DarkGray) // Active/Pressed state
        .End();

Custom Conditions with .If()

For any other condition, you can use the .If(your_condition) method. The styles inside will only be applied if the boolean condition you pass is true.

bool isToggled = true; // Your application's state

paper.Box("ToggleButton")
    .BackgroundColor(Color.Red)
    .If(isToggled)
        .BackgroundColor(Color.Green) // This overrides the red color if toggled
        .End();

Execution Order Matters! Styles are applied in the order they are written. A later style will override an earlier one.

// This button will be LightGray when hovered, even if 'isToggled' is true,
// because .Hovered comes after .If().
paper.Box("OrderMatters")
    .BackgroundColor(Color.Gray)
    .If(isToggled)
        .BackgroundColor(Color.Green)
        .End()
    .Hovered
        .BackgroundColor(Color.LightGray)
        .End();

Transformations

You can translate, scale, and rotate any element. These transformations are applied from the element's center and do not affect the layout of other elements.

paper.Box("TransformedBox")
    .Size(100)
    .BackgroundColor(Color.Purple)
    .Translate(50, 0)   // Move 50px to the right
    .Scale(1.5)         // Make it 50% larger
    .Rotate(45);        // Rotate 45 degrees

Custom Vector Drawing with AddActionElement

For ultimate flexibility, Paper allows you to inject your own drawing commands directly into the render pipeline using AddActionElement. This gives you access to a low-level vector graphics API (Canvas) where you can draw custom shapes, lines, and curves inside any element's bounds.

This is perfect for creating custom visualizations, charts, or unique UI components.

using (paper.Box("ChartCanvas").Size(300, 150).Enter())
{
    // The lambda function receives the canvas and the element's rectangle
    paper.AddActionElement((canvas, rect) =>
    {
        // Draw a red diagonal line across the element
        canvas.BeginPath();
        canvas.MoveTo(rect.x, rect.y);
        canvas.LineTo(rect.x + rect.width, rect.y + rect.height);
        canvas.SetStrokeColor(Color.Red);
        canvas.SetStrokeWidth(3);
        canvas.Stroke();
    });
}

Mastering these styling tools will allow you to move beyond simple boxes and create visually engaging and interactive user experiences. Next up, we'll see how to make reusable Style Definitions!

Last updated