/* evaluation settings for active NLA-Strip */ static void nla_panel_evaluation(const bContext *C, Panel *pa) { PointerRNA strip_ptr; uiLayout *layout = pa->layout; uiLayout *col, *sub; uiBlock *block; /* check context and also validity of pointer */ if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) return; block = uiLayoutGetBlock(layout); UI_block_func_handle_set(block, do_nla_region_buttons, NULL); col = uiLayoutColumn(layout, true); uiItemR(col, &strip_ptr, "use_animated_influence", 0, NULL, ICON_NONE); sub = uiLayoutColumn(col, true); uiLayoutSetEnabled(sub, RNA_boolean_get(&strip_ptr, "use_animated_influence")); uiItemR(sub, &strip_ptr, "influence", 0, NULL, ICON_NONE); col = uiLayoutColumn(layout, true); sub = uiLayoutRow(col, false); uiItemR(sub, &strip_ptr, "use_animated_time", 0, NULL, ICON_NONE); uiItemR(sub, &strip_ptr, "use_animated_time_cyclic", 0, NULL, ICON_NONE); sub = uiLayoutRow(col, false); uiLayoutSetEnabled(sub, RNA_boolean_get(&strip_ptr, "use_animated_time")); uiItemR(sub, &strip_ptr, "strip_time", 0, NULL, ICON_NONE); }
/* TODO de-duplicate redo panel functions - campbell */ static void view3d_panel_operator_redo(const bContext *C, Panel *pa) { wmOperator *op = WM_operator_last_redo(C); ARegion *ar; ARegion *ar1; if (op == NULL) { return; } /* keep in sync with logic in ED_undo_operator_repeat() */ ar = CTX_wm_region(C); ar1 = BKE_area_find_region_active_win(CTX_wm_area(C)); if (ar1) CTX_wm_region_set((bContext *)C, ar1); if (WM_operator_poll((bContext *)C, op->type)) { uiBlock *block = uiLayoutGetBlock(pa->layout); if (!WM_operator_check_ui_enabled(C, op->type->name)) uiLayoutSetEnabled(pa->layout, false); /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */ UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op); view3d_panel_operator_redo_operator(C, pa, op); } /* set region back */ CTX_wm_region_set((bContext *)C, ar); }
/* active AnimData */ static void nla_panel_animdata(const bContext *C, Panel *pa) { PointerRNA adt_ptr; /* AnimData *adt; */ uiLayout *layout = pa->layout; uiLayout *row; uiBlock *block; /* check context and also validity of pointer */ if (!nla_panel_context(C, &adt_ptr, NULL, NULL)) return; /* adt = adt_ptr.data; */ block = uiLayoutGetBlock(layout); UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* AnimData Source Properties ----------------------------------- */ /* icon + id-block name of block where AnimData came from to prevent * accidentally changing the properties of the wrong action */ if (adt_ptr.id.data) { ID *id = adt_ptr.id.data; PointerRNA id_ptr; RNA_id_pointer_create(id, &id_ptr); /* ID-block name > AnimData */ row = uiLayoutRow(layout, true); uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT); uiItemL(row, id->name + 2, RNA_struct_ui_icon(id_ptr.type)); /* id-block (src) */ uiItemL(row, "", VICO_SMALL_TRI_RIGHT_VEC); /* expander */ uiItemL(row, IFACE_("Animation Data"), ICON_ANIM_DATA); /* animdata */ uiItemS(layout); } /* Active Action Properties ------------------------------------- */ /* action */ row = uiLayoutRow(layout, true); uiTemplateID( row, (bContext *)C, &adt_ptr, "action", "ACTION_OT_new", NULL, "NLA_OT_action_unlink", UI_TEMPLATE_ID_FILTER_ALL); /* extrapolation */ row = uiLayoutRow(layout, true); uiItemR(row, &adt_ptr, "action_extrapolation", 0, NULL, ICON_NONE); /* blending */ row = uiLayoutRow(layout, true); uiItemR(row, &adt_ptr, "action_blend_type", 0, NULL, ICON_NONE); /* influence */ row = uiLayoutRow(layout, true); uiItemR(row, &adt_ptr, "action_influence", 0, NULL, ICON_NONE); }
/* active NLA-Track */ static void nla_panel_track(const bContext *C, Panel *pa) { PointerRNA nlt_ptr; uiLayout *layout = pa->layout; uiLayout *row; uiBlock *block; /* check context and also validity of pointer */ if (!nla_panel_context(C, NULL, &nlt_ptr, NULL)) return; block = uiLayoutGetBlock(layout); UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* Info - Active NLA-Context:Track ---------------------- */ row = uiLayoutRow(layout, true); uiItemR(row, &nlt_ptr, "name", 0, NULL, ICON_NLA); }
static void graph_panel_modifiers(const bContext *C, Panel *pa) { bAnimListElem *ale; FCurve *fcu; FModifier *fcm; uiLayout *col, *row; uiBlock *block; bool active; if (!graph_panel_context(C, &ale, &fcu)) return; block = uiLayoutGetBlock(pa->layout); UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL); /* 'add modifier' button at top of panel */ { row = uiLayoutRow(pa->layout, false); /* this is an operator button which calls a 'add modifier' operator... * a menu might be nicer but would be tricky as we need some custom filtering */ uiItemMenuEnumO(row, (bContext *)C, "GRAPH_OT_fmodifier_add", "type", IFACE_("Add Modifier"), ICON_NONE); /* copy/paste (as sub-row) */ row = uiLayoutRow(row, true); uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy"); uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste"); } active = !(fcu->flag & FCURVE_MOD_OFF); /* draw each modifier */ for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) { col = uiLayoutColumn(pa->layout, true); uiLayoutSetActive(col, active); ANIM_uiTemplate_fmodifier_draw(col, ale->id, &fcu->modifiers, fcm); } MEM_freeN(ale); }
/* action-clip only settings for active NLA-Strip */ static void nla_panel_actclip(const bContext *C, Panel *pa) { PointerRNA strip_ptr; uiLayout *layout = pa->layout; uiLayout *column, *row; uiBlock *block; /* check context and also validity of pointer */ if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) return; block = uiLayoutGetBlock(layout); UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* Strip Properties ------------------------------------- */ /* action pointer */ row = uiLayoutRow(layout, true); uiItemR(row, &strip_ptr, "action", 0, NULL, ICON_ACTION); /* action extents */ // XXX custom names were used here (to avoid the prefixes)... probably not necessary in future? column = uiLayoutColumn(layout, true); uiItemL(column, IFACE_("Action Extents:"), ICON_NONE); uiItemR(column, &strip_ptr, "action_frame_start", 0, IFACE_("Start Frame"), ICON_NONE); uiItemR(column, &strip_ptr, "action_frame_end", 0, IFACE_("End Frame"), ICON_NONE); // XXX: this layout may actually be too abstract and confusing, and may be better using standard column layout row = uiLayoutRow(layout, false); uiItemR(row, &strip_ptr, "use_sync_length", 0, IFACE_("Sync Length"), ICON_NONE); uiItemO(row, IFACE_("Now"), ICON_FILE_REFRESH, "NLA_OT_action_sync_length"); /* action usage */ column = uiLayoutColumn(layout, true); uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_time") == false); uiItemL(column, IFACE_("Playback Settings:"), ICON_NONE); uiItemR(column, &strip_ptr, "scale", 0, NULL, ICON_NONE); uiItemR(column, &strip_ptr, "repeat", 0, NULL, ICON_NONE); }
/* F-Modifiers for active NLA-Strip */ static void nla_panel_modifiers(const bContext *C, Panel *pa) { PointerRNA strip_ptr; NlaStrip *strip; FModifier *fcm; uiLayout *col, *row; uiBlock *block; /* check context and also validity of pointer */ if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) return; strip = strip_ptr.data; block = uiLayoutGetBlock(pa->layout); UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* 'add modifier' button at top of panel */ { row = uiLayoutRow(pa->layout, false); block = uiLayoutGetBlock(row); // FIXME: we need to set the only-active property so that this will only add modifiers for the active strip (not all selected) uiItemMenuEnumO(row, (bContext *)C, "NLA_OT_fmodifier_add", "type", IFACE_("Add Modifier"), ICON_NONE); /* copy/paste (as sub-row) */ row = uiLayoutRow(row, true); uiItemO(row, "", ICON_COPYDOWN, "NLA_OT_fmodifier_copy"); uiItemO(row, "", ICON_PASTEDOWN, "NLA_OT_fmodifier_paste"); } /* draw each modifier */ for (fcm = strip->modifiers.first; fcm; fcm = fcm->next) { col = uiLayoutColumn(pa->layout, true); ANIM_uiTemplate_fmodifier_draw(col, strip_ptr.id.data, &strip->modifiers, fcm); } }
void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C) { Object *obedit = CTX_data_edit_object(C); uiBlock *block = uiLayoutGetBlock(layout); UI_block_func_handle_set(block, do_view3d_header_buttons, NULL); if (obedit && (obedit->type == OB_MESH)) { BMEditMesh *em = BKE_editmesh_from_object(obedit); uiLayout *row; row = uiLayoutRow(layout, true); block = uiLayoutGetBlock(row); uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection")); uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands/contracts selection")); uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection")); } }
/* generic settings for active NLA-Strip */ static void nla_panel_properties(const bContext *C, Panel *pa) { PointerRNA strip_ptr; uiLayout *layout = pa->layout; uiLayout *column, *row, *sub; uiBlock *block; short showEvalProps = 1; if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) return; block = uiLayoutGetBlock(layout); UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* Strip Properties ------------------------------------- */ /* strip type */ row = uiLayoutColumn(layout, true); uiItemR(row, &strip_ptr, "name", 0, NULL, ICON_NLA); // XXX icon? uiItemR(row, &strip_ptr, "type", 0, NULL, ICON_NONE); /* strip extents */ column = uiLayoutColumn(layout, true); uiItemL(column, IFACE_("Strip Extents:"), ICON_NONE); uiItemR(column, &strip_ptr, "frame_start", 0, NULL, ICON_NONE); uiItemR(column, &strip_ptr, "frame_end", 0, NULL, ICON_NONE); /* Evaluation-Related Strip Properties ------------------ */ /* sound properties strips don't have these settings */ if (RNA_enum_get(&strip_ptr, "type") == NLASTRIP_TYPE_SOUND) showEvalProps = 0; /* only show if allowed to... */ if (showEvalProps) { /* extrapolation */ row = uiLayoutRow(layout, true); uiItemR(row, &strip_ptr, "extrapolation", 0, NULL, ICON_NONE); /* blending */ row = uiLayoutRow(layout, true); uiItemR(row, &strip_ptr, "blend_type", 0, NULL, ICON_NONE); /* blend in/out + autoblending * - blend in/out can only be set when autoblending is off */ column = uiLayoutColumn(layout, true); uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_influence") == false); uiItemR(column, &strip_ptr, "use_auto_blend", 0, NULL, ICON_NONE); // XXX as toggle? sub = uiLayoutColumn(column, true); uiLayoutSetActive(sub, RNA_boolean_get(&strip_ptr, "use_auto_blend") == false); uiItemR(sub, &strip_ptr, "blend_in", 0, NULL, ICON_NONE); uiItemR(sub, &strip_ptr, "blend_out", 0, NULL, ICON_NONE); /* settings */ column = uiLayoutColumn(layout, true); uiLayoutSetActive(column, !(RNA_boolean_get(&strip_ptr, "use_animated_influence") || RNA_boolean_get(&strip_ptr, "use_animated_time"))); uiItemL(column, IFACE_("Playback Settings:"), ICON_NONE); uiItemR(column, &strip_ptr, "mute", 0, NULL, ICON_NONE); uiItemR(column, &strip_ptr, "use_reverse", 0, NULL, ICON_NONE); } }
void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) { bScreen *screen = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; Scene *scene = CTX_data_scene(C); ToolSettings *ts = CTX_data_tool_settings(C); PointerRNA v3dptr, toolsptr, sceneptr; Object *ob = OBACT; Object *obedit = CTX_data_edit_object(C); uiBlock *block; uiLayout *row; bool is_paint = false; int modeselect; RNA_pointer_create(&screen->id, &RNA_SpaceView3D, v3d, &v3dptr); RNA_pointer_create(&scene->id, &RNA_ToolSettings, ts, &toolsptr); RNA_pointer_create(&scene->id, &RNA_Scene, scene, &sceneptr); block = uiLayoutGetBlock(layout); UI_block_func_handle_set(block, do_view3d_header_buttons, NULL); /* other buttons: */ UI_block_emboss_set(block, UI_EMBOSS); /* mode */ if (ob) { modeselect = ob->mode; is_paint = ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT); } else { modeselect = OB_MODE_OBJECT; } row = uiLayoutRow(layout, false); { EnumPropertyItem *item = object_mode_items; const char *name = ""; int icon = ICON_OBJECT_DATAMODE; while (item->identifier) { if (item->value == modeselect && item->identifier[0]) { name = IFACE_(item->name); icon = item->icon; break; } item++; } uiItemMenuEnumO(row, C, "OBJECT_OT_mode_set", "mode", name, icon); } /* Draw type */ uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); if (obedit == NULL && is_paint) { if (ob->mode & OB_MODE_ALL_PAINT) { /* Only for Weight Paint. makes no sense in other paint modes. */ row = uiLayoutRow(layout, true); uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } /* Manipulators aren't used in paint modes */ if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) { /* masks aren't used for sculpt and particle painting */ PointerRNA meshptr; RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr); if (ob->mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT)) { uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } else { row = uiLayoutRow(layout, true); uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } } } else { row = uiLayoutRow(layout, true); uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); /* pose/object only however we want to allow in weight paint mode too * so don't be totally strict and just check not-editmode for now * XXX We never get here when we are in Weight Paint mode */ if (obedit == NULL) { uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } /* Transform widget / manipulators */ row = uiLayoutRow(layout, true); uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); if (v3d->twflag & V3D_USE_MANIPULATOR) { uiItemR(row, &v3dptr, "transform_manipulators", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } uiItemR(row, &v3dptr, "transform_orientation", 0, "", ICON_NONE); } if (obedit == NULL && v3d->localvd == NULL) { unsigned int ob_lay = ob ? ob->lay : 0; /* Layers */ uiTemplateLayers(layout, v3d->scenelock ? &sceneptr : &v3dptr, "layers", &v3dptr, "layers_used", ob_lay); /* Scene lock */ uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } uiTemplateEditModeSelection(layout, C); }
/* driver settings for active F-Curve (only for 'Drivers' mode) */ static void graph_panel_drivers(const bContext *C, Panel *pa) { bAnimListElem *ale; FCurve *fcu; ChannelDriver *driver; DriverVar *dvar; PointerRNA driver_ptr; uiLayout *col; uiBlock *block; uiBut *but; /* Get settings from context */ if (!graph_panel_context(C, &ale, &fcu)) return; driver = fcu->driver; /* set event handler for panel */ block = uiLayoutGetBlock(pa->layout); // xxx? UI_block_func_handle_set(block, do_graph_region_driver_buttons, NULL); /* general actions - management */ col = uiLayoutColumn(pa->layout, false); block = uiLayoutGetBlock(col); but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"), 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Force updates of dependencies")); UI_but_func_set(but, driver_update_flags_cb, fcu, NULL); but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"), 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Remove this driver")); UI_but_funcN_set(but, driver_remove_cb, MEM_dupallocN(ale), NULL); /* driver-level settings - type, expressions, and errors */ RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr); col = uiLayoutColumn(pa->layout, true); block = uiLayoutGetBlock(col); uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE); /* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */ if (driver->type == DRIVER_TYPE_PYTHON) { bool bpy_data_expr_error = (strstr(driver->expression, "bpy.data.") != NULL); bool bpy_ctx_expr_error = (strstr(driver->expression, "bpy.context.") != NULL); /* expression */ uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE); /* errors? */ if ((G.f & G_SCRIPT_AUTOEXEC) == 0) { uiItemL(col, IFACE_("ERROR: Python auto-execution disabled"), ICON_CANCEL); } else if (driver->flag & DRIVER_FLAG_INVALID) { uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_CANCEL); } /* Explicit bpy-references are evil. Warn about these to prevent errors */ /* TODO: put these in a box? */ if (bpy_data_expr_error || bpy_ctx_expr_error) { uiItemL(col, IFACE_("WARNING: Driver expression may not work correctly"), ICON_HELP); if (bpy_data_expr_error) { uiItemL(col, IFACE_("TIP: Use variables instead of bpy.data paths (see below)"), ICON_ERROR); } if (bpy_ctx_expr_error) { uiItemL(col, IFACE_("TIP: bpy.context is not safe for renderfarm usage"), ICON_ERROR); } } } else { /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR); /* Warnings about a lack of variables * NOTE: The lack of variables is generally a bad thing, since it indicates * that the driver doesn't work at all. This particular scenario arises * primarily when users mistakenly try to use drivers for procedural * property animation */ if (BLI_listbase_is_empty(&driver->variables)) { uiItemL(col, IFACE_("ERROR: Driver is useless without any inputs"), ICON_ERROR); if (!BLI_listbase_is_empty(&fcu->modifiers)) { uiItemL(col, IFACE_("TIP: Use F-Curves for procedural animation instead"), ICON_INFO); uiItemL(col, IFACE_("F-Modifiers can generate curves for those too"), ICON_INFO); } } } col = uiLayoutColumn(pa->layout, true); if (driver->type == DRIVER_TYPE_PYTHON) { uiItemR(col, &driver_ptr, "use_self", 0, NULL, ICON_NONE); } /* debug setting */ uiItemR(col, &driver_ptr, "show_debug_info", 0, NULL, ICON_NONE); /* value of driver */ if (driver->flag & DRIVER_FLAG_SHOWDEBUG) { uiLayout *row = uiLayoutRow(col, true); char valBuf[32]; uiItemL(row, IFACE_("Driver Value:"), ICON_NONE); BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval); uiItemL(row, valBuf, ICON_NONE); } /* add/copy/paste driver variables */ { uiLayout *row; /* add driver variable */ row = uiLayoutRow(pa->layout, false); block = uiLayoutGetBlock(row); but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"), 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Driver variables ensure that all dependencies will be accounted for and that drivers will update correctly")); UI_but_func_set(but, driver_add_var_cb, driver, NULL); /* copy/paste (as sub-row) */ row = uiLayoutRow(row, true); block = uiLayoutGetBlock(row); uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_driver_variables_copy"); uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_driver_variables_paste"); } /* loop over targets, drawing them */ for (dvar = driver->variables.first; dvar; dvar = dvar->next) { PointerRNA dvar_ptr; uiLayout *box, *row; uiLayout *subrow, *sub; /* sub-layout column for this variable's settings */ col = uiLayoutColumn(pa->layout, true); /* 1) header panel */ box = uiLayoutBox(col); RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr); row = uiLayoutRow(box, false); block = uiLayoutGetBlock(row); /* 1.1) variable type and name */ subrow = uiLayoutRow(row, true); /* 1.1.1) variable type */ sub = uiLayoutRow(subrow, true); /* HACK: special group just for the enum, otherwise we */ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); /* we get ugly layout with text included too... */ uiItemR(sub, &dvar_ptr, "type", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); /* 1.1.2) variable name */ sub = uiLayoutRow(subrow, true); /* HACK: special group to counteract the effects of the previous */ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND); /* enum, which now pushes everything too far right */ uiItemR(sub, &dvar_ptr, "name", 0, "", ICON_NONE); /* 1.2) invalid name? */ UI_block_emboss_set(block, UI_EMBOSS_NONE); if (dvar->flag & DVAR_FLAG_INVALID_NAME) { but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ERROR, 290, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Invalid variable name, click here for details")); UI_but_func_set(but, driver_dvar_invalid_name_query_cb, dvar, NULL); // XXX: reports? } /* 1.3) remove button */ but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable")); UI_but_func_set(but, driver_delete_var_cb, driver, dvar); UI_block_emboss_set(block, UI_EMBOSS); /* 2) variable type settings */ box = uiLayoutBox(col); /* controls to draw depends on the type of variable */ switch (dvar->type) { case DVAR_TYPE_SINGLE_PROP: /* single property */ graph_panel_driverVar__singleProp(box, ale->id, dvar); break; case DVAR_TYPE_ROT_DIFF: /* rotational difference */ graph_panel_driverVar__rotDiff(box, ale->id, dvar); break; case DVAR_TYPE_LOC_DIFF: /* location difference */ graph_panel_driverVar__locDiff(box, ale->id, dvar); break; case DVAR_TYPE_TRANSFORM_CHAN: /* transform channel */ graph_panel_driverVar__transChan(box, ale->id, dvar); break; } /* 3) value of variable */ if (driver->flag & DRIVER_FLAG_SHOWDEBUG) { char valBuf[32]; box = uiLayoutBox(col); row = uiLayoutRow(box, true); uiItemL(row, IFACE_("Value:"), ICON_NONE); if ((dvar->type == DVAR_TYPE_ROT_DIFF) || (dvar->type == DVAR_TYPE_TRANSFORM_CHAN && dvar->targets[0].transChan >= DTAR_TRANSCHAN_ROTX && dvar->targets[0].transChan < DTAR_TRANSCHAN_SCALEX)) { BLI_snprintf(valBuf, sizeof(valBuf), "%.3f (%4.1f°)", dvar->curval, RAD2DEGF(dvar->curval)); } else { BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval); } uiItemL(row, valBuf, ICON_NONE); } } /* cleanup */ MEM_freeN(ale); }