Makepad Reference logo

Makepad Reference

Visit

Reference materials for Makepad development including troubleshooting common errors, code quality guidelines, and responsive layout patterns for cross-platform apps.

Share:

Makepad Reference

Reference materials for debugging, code quality, and advanced layout patterns.

Quick Navigation

Topic Description
Troubleshooting Common errors and fixes
Code Quality Makepad-aware refactoring
Adaptive Layout Desktop/mobile responsive design

Common Issues Quick Reference

Error Quick Fix
no matching field: font Use text_style: <THEME_FONT_*>{}
Color parse error (ends in e) Change last digit (e.g., #14141e#14141f)
set_text missing argument Add cx as first argument
UI not updating Call redraw(cx) after changes
Widget not found Check ID spelling, use ids!() for paths

Common Build Errors

Error: "no matching field: font"

// ❌ Wrong
<Label> { font: "Bold" }

// ✅ Correct
<Label> { text_style: <THEME_FONT_BOLD>{} }

Error: Color parsing fails

// ❌ Wrong - ends with 'e'
draw_bg: { color: #14141e }

// ✅ Correct - change last digit
draw_bg: { color: #14141f }

Error: Widget not redrawing

// ❌ Wrong - changes not visible
self.label.set_text(&mut cx, "New Text");

// ✅ Correct - trigger redraw
self.label.set_text(&mut cx, "New Text");
self.redraw(cx);

Code Quality Guidelines

Widget Extension Pattern

// Good: Create extension trait for reusable operations
pub trait LabelExt {
    fn set_text_and_color(&mut self, cx: &mut Cx, text: &str, color: Vec4);
}

impl LabelExt for Label {
    fn set_text_and_color(&mut self, cx: &mut Cx, text: &str, color: Vec4) {
        self.label(id!(text)).set_text(cx, text);
        self.draw_text.color = color;
        self.redraw(cx);
    }
}

Avoid Repetitive Patterns

// ❌ Bad: Repetitive code
match action {
    Action1 => { self.widget1.redraw(cx); }
    Action2 => { self.widget2.redraw(cx); }
    Action3 => { self.widget3.redraw(cx); }
}

// ✅ Good: Extract common logic
fn redraw_widget(&mut self, cx: &mut Cx, widget_id: WidgetId) {
    self.widget(widget_id).redraw(cx);
}

Adaptive Layout Patterns

Responsive Sizing

live_design! {
    <View> {
        // Desktop: fixed width, Mobile: fill
        width: { desktop: 800, mobile: Fill }
        height: Fit

        flow: { desktop: Right, mobile: Down }
    }
}

Breakpoint-Based Layout

impl Widget for MyView {
    fn draw(&mut self, cx: &mut Cx2d) {
        let width = cx.turtle().rect().size.x;

        if width > 800.0 {
            // Desktop layout
        } else {
            // Mobile layout
        }
    }
}

Platform-Specific Styling

live_design! {
    <Button> {
        // Platform-specific properties
        padding: {
            desktop: {left: 20, right: 20, top: 10, bottom: 10}
            mobile: {left: 15, right: 15, top: 8, bottom: 8}
        }

        draw_text: {
            text_style: {
                font_size: { desktop: 14.0, mobile: 16.0 }
            }
        }
    }
}

Debug Tips

Enable Line Info

# Run with line info for better error messages
MAKEPAD=lines cargo +nightly run

Logging

// Add logging for debugging
log!("Value: {:?}", my_value);
log!("State: {} / {}", self.counter, self.is_loading);
log!("Event: {:?}", event);

Widget Inspector

// Print widget tree
fn debug_widget_tree(&self, cx: &Cx, depth: usize) {
    let indent = "  ".repeat(depth);
    log!("{}Widget: {:?}", indent, self.widget_uid());

    for child in self.children() {
        child.debug_widget_tree(cx, depth + 1);
    }
}

Performance Tips

  1. Use PortalList for large lists - Virtual scrolling improves performance
  2. Avoid unnecessary redraws - Only call redraw(cx) when state changes
  3. Cache heavy computations - Store results in widget state
  4. Use GPU shaders - Offload visual effects to GPU

Resources

Comments

No comments yet. Be the first to comment!