BevelEffectLib — 3D Bevel & Emboss Effect
Creates a GPU-accelerated 3D bevel/emboss effect on any visual control, making elements appear raised above or sunken into the surface. The effect simulates a directional light source casting highlights and shadows along the edges of the control. Wraps FireMonkey’s TBevelEffect. Perfect for classic UI button styles, panel borders, picture frames, and retro 3D interface elements. 14 functions.
| Category | Count | Description |
|---|---|---|
| Error Handling | 4 | bevel_error, errormsg$, strerror$, clearerror |
| Creation & Destruction | 2 | bevel# (create), bevel_free (destroy) |
| Bevel Properties | 4 | direction, size (get/set) |
| Effect Control | 4 | enabled, trigger (get/set) |
bevel_free only to remove the effect while keeping the parent alive.Cross-Platform Support
| Platform | Status | Notes |
|---|---|---|
| Windows | ✅ Full Support | GPU-accelerated via Direct2D |
| Linux | ✅ Full Support | Software rendering fallback |
| Android | ✅ Full Support | GPU-accelerated |
Error Handling
All functions set an error code on failure. Check with bevel_error() after operations. Error code 0 means success.
| Function | Signature | Description |
|---|---|---|
bevel_error() | bevel_error@ | Returns last error code (0 = no error) |
bevel_errormsg$() | bevel_errormsg$@ | Returns last error message as string |
bevel_strerror$(code) | bevel_strerror$@n | Converts an error code to descriptive text |
bevel_clearerror() | bevel_clearerror@ | Clears the error state |
Error Codes
| Code | Constant | Meaning |
|---|---|---|
| 0 | ERR_NONE | No error |
| 1 | ERR_NIL_EFFECT | Effect pointer is nil |
| 2 | ERR_INVALID_EFFECT | Pointer is not a valid TBevelEffect |
| 3 | ERR_INVALID_VALUE | Property value out of range |
| 4 | ERR_NIL_PARENT | Parent control pointer is nil |
| 5 | ERR_INVALID_PARENT | Pointer is not a valid TFmxObject |
Creation & Destruction
| Function | Signature | Description |
|---|---|---|
bevel#(parent#) | bevel#@# | Creates a bevel effect attached to the given control. Returns the effect pointer. |
bevel_free(effect#) | bevel_free@# | Destroys the effect and removes it from the parent control. |
The parent# can be any visual control. The effect is applied immediately with default values (direction 45°, size 1).
' Create bevel effect on a rectangle let bvl# = bevel#(rect#) ' Later, remove the effect bevel_free(bvl#)
Direction (Light Angle)
The direction property sets the angle of the simulated light source in degrees (0–360). This determines which edges appear highlighted (lit) and which appear shadowed, creating the 3D raised or sunken illusion. Default is 45° (light from top-right).
| Function | Signature | Description |
|---|---|---|
bevel_direction#(effect#, degrees) | bevel_direction#@#n | Sets light source angle (0–360) |
bevel_direction(effect#) | bevel_direction@# | Gets current direction |
Light Direction Reference
| Angle | Light Position | Visual Effect | Classic Use |
|---|---|---|---|
| 0° | Right | Left edge lit, right shadowed | — |
| 45° | Top-right | Top & left edges lit — raised | Default button, toolbar |
| 90° | Top | Top edge lit, bottom shadowed | Horizontal divider |
| 135° | Top-left | Top & right edges lit | Alternate raised style |
| 180° | Left | Right edge lit, left shadowed | — |
| 225° | Bottom-left | Bottom & right edges lit — sunken | Pressed button, inset panel |
| 270° | Bottom | Bottom edge lit, top shadowed | Horizontal groove |
| 315° | Bottom-right | Bottom & left edges lit | Alternate sunken style |
' Raised look (default) bevel_direction#(bvl#, 45) ' Sunken/pressed look bevel_direction#(bvl#, 225) ' Light from directly above bevel_direction#(bvl#, 90) let dir = bevel_direction(bvl#) print "Light angle: " + str$(dir)
Bevel Size
Controls the thickness of the bevel edge in pixels. Larger values create a wider highlight/shadow band. Default is 1. Range is 0–10.
| Function | Signature | Description |
|---|---|---|
bevel_size#(effect#, pixels) | bevel_size#@#n | Sets bevel edge thickness (0–10) |
bevel_size(effect#) | bevel_size@# | Gets current size |
| Size | Visual Effect | Use Case |
|---|---|---|
| 0 | No bevel visible | Effectively disabled |
| 1–2 | Subtle, thin edge | Elegant UI elements, small buttons |
| 3–4 | Clearly visible 3D edge | Classic toolbar buttons, panel borders |
| 5–7 | Prominent bevel | Decorative frames, emphasized panels |
| 8–10 | Very thick, dramatic edge | Stylized borders, retro UI chrome |
' Subtle bevel bevel_size#(bvl#, 1) ' Classic 3D button look bevel_size#(bvl#, 3) ' Dramatic picture frame bevel_size#(bvl#, 8)
Effect Control
Enabled
Toggles the effect on or off without destroying it.
| Function | Signature | Description |
|---|---|---|
bevel_enabled#(effect#, value) | bevel_enabled#@#n | Enables (1) or disables (0) the effect |
bevel_enabled(effect#) | bevel_enabled@# | Gets enabled state (1 = on, 0 = off) |
Trigger
The trigger property is a string used by FireMonkey’s animation system.
| Function | Signature | Description |
|---|---|---|
bevel_trigger#(effect#, trigger$) | bevel_trigger#@#$ | Sets trigger string |
bevel_trigger$(effect#) | bevel_trigger$@# | Gets current trigger string |
Complete Examples
Basic Bevel on a Rectangle
Applies a raised 3D bevel to a gray rectangle.
let frm# = Pointer#(0) let rect# = Pointer#(0) let bvl# = Pointer#(0) frm# = form#("Bevel Demo", 400, 300) rect# = rectangle#(frm#) rectangle_bounds#(rect#, 100, 80, 200, 120) rectangle_fill#(rect#, "Gray") bvl# = bevel#(rect#) bevel_direction#(bvl#, 45) bevel_size#(bvl#, 3) form_show(frm#)
Raised vs Sunken Comparison
Side-by-side rectangles showing the raised (45°) and sunken (225°) bevel look.
let frm# = Pointer#(0) let rect1# = Pointer#(0) let rect2# = Pointer#(0) let bvl1# = Pointer#(0) let bvl2# = Pointer#(0) frm# = form#("Raised vs Sunken", 450, 250) ' Raised (light from top-right) rect1# = rectangle#(frm#) rectangle_bounds#(rect1#, 50, 70, 150, 100) rectangle_fill#(rect1#, "Silver") bvl1# = bevel#(rect1#) bevel_direction#(bvl1#, 45) bevel_size#(bvl1#, 3) let lbl1# = label#(frm#, "Raised (45)", 85, 180) ' Sunken (light from bottom-left) rect2# = rectangle#(frm#) rectangle_bounds#(rect2#, 250, 70, 150, 100) rectangle_fill#(rect2#, "Silver") bvl2# = bevel#(rect2#) bevel_direction#(bvl2#, 225) bevel_size#(bvl2#, 3) let lbl2# = label#(frm#, "Sunken (225)", 280, 180) form_show(frm#)
Interactive Direction Control
Four buttons to switch the bevel light direction in real time.
let frm# = Pointer#(0) let rect# = Pointer#(0) let bvl# = Pointer#(0) let lbl# = Pointer#(0) frm# = form#("Bevel Direction", 450, 320) rect# = rectangle#(frm#) rectangle_bounds#(rect#, 125, 40, 200, 100) rectangle_fill#(rect#, "Silver") bvl# = bevel#(rect#) bevel_direction#(bvl#, 45) bevel_size#(bvl#, 4) lbl# = label#(frm#, "Direction: 45", 170, 160) let btn1# = button#(frm#, "45 (TR)") button_bounds#(btn1#, 40, 200, 80, 30) button_onclick#(btn1#, "SetDir45") let btn2# = button#(frm#, "135 (TL)") button_bounds#(btn2#, 130, 200, 80, 30) button_onclick#(btn2#, "SetDir135") let btn3# = button#(frm#, "225 (BL)") button_bounds#(btn3#, 220, 200, 80, 30) button_onclick#(btn3#, "SetDir225") let btn4# = button#(frm#, "315 (BR)") button_bounds#(btn4#, 310, 200, 80, 30) button_onclick#(btn4#, "SetDir315") form_show(frm#) function SetDir45(sender#) bevel_direction#(bvl#, 45) label_text#(lbl#, "Direction: 45 (Raised)") endfunction function SetDir135(sender#) bevel_direction#(bvl#, 135) label_text#(lbl#, "Direction: 135") endfunction function SetDir225(sender#) bevel_direction#(bvl#, 225) label_text#(lbl#, "Direction: 225 (Sunken)") endfunction function SetDir315(sender#) bevel_direction#(bvl#, 315) label_text#(lbl#, "Direction: 315") endfunction
Best Practices
| Practice | Why |
|---|---|
| Use direction 45° for raised, 225° for sunken | The classic pairing — 180° apart creates the most natural raised/pressed illusion |
| Keep size between 1–4 for subtle effects | Large bevel sizes can look exaggerated on small controls |
| Use gray or neutral-colored parent controls | Bevel highlights and shadows are most visible on mid-tone backgrounds |
| Swap direction on click for button press effect | Toggle 45° ↔ 225° on mousedown/mouseup for interactive 3D buttons |
Combine with ShadowEffectLib for depth | Bevel for edge definition + shadow for floating depth = convincing 3D |
| Use on rectangles and panels for classic UI | Recreates the Windows 95 / classic Mac OS toolbar aesthetic |
Use bevel_enabled# to toggle instead of bevel_free | Faster than destroying and recreating for on/off scenarios |
| Keep all bevels in a UI with the same direction | Consistent light direction across all elements looks more natural |
Quick Reference
| Function | Signature | Description |
|---|---|---|
| ERROR HANDLING | ||
bevel_error() | bevel_error@ | Last error code |
bevel_errormsg$() | bevel_errormsg$@ | Last error message |
bevel_strerror$(code) | bevel_strerror$@n | Error code to text |
bevel_clearerror() | bevel_clearerror@ | Clear error state |
| CREATION & DESTRUCTION | ||
bevel#(parent#) | bevel#@# | Create effect on control |
bevel_free(effect#) | bevel_free@# | Destroy effect |
| BEVEL PROPERTIES | ||
bevel_direction#(effect#, deg) | bevel_direction#@#n | Set light angle (0–360) |
bevel_direction(effect#) | bevel_direction@# | Get light angle |
bevel_size#(effect#, px) | bevel_size#@#n | Set edge thickness (0–10) |
bevel_size(effect#) | bevel_size@# | Get edge thickness |
| EFFECT CONTROL | ||
bevel_enabled#(effect#, val) | bevel_enabled#@#n | Enable (1) / disable (0) |
bevel_enabled(effect#) | bevel_enabled@# | Get enabled state |
bevel_trigger#(effect#, str$) | bevel_trigger#@#$ | Set trigger string |
bevel_trigger$(effect#) | bevel_trigger$@# | Get trigger string |
14 functions. Part of the Plan9Basic visual effects library system.
See Also
- ShadowEffectLib — Drop shadow for floating depth
- GlowEffectLib — Outer glow around controls
- InnerGlowEffectLib — Inner glow for inset lighting
- EmbossEffectLib — Image-based emboss/relief filter
- ReflectionEffectLib — Mirror reflection beneath controls