static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUSED(arg)) { /* callback when opening texture user selection menu, to create buttons. */ SpaceButs *sbuts = CTX_wm_space_buts(C); ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; ButsTextureUser *user; uiBlock *block = uiLayoutGetBlock(layout); const char *last_category = NULL; for(user=ct->users.first; user; user=user->next) { uiBut *but; char name[UI_MAX_NAME_STR]; /* add label per category */ if(!last_category || strcmp(last_category, user->category) != 0) { uiItemL(layout, user->category, ICON_NONE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; } /* create button */ BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, ""); uiButSetNFunc(but, template_texture_select, MEM_dupallocN(user), NULL); last_category = user->category; } }
static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_p) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); uiBlock *block = uiLayoutGetBlock(layout); uiBut *but = (uiBut *)but_p; uiLayout *split, *column; NodeLinkArg *arg = (NodeLinkArg *)but->func_argN; bNodeSocket *sock = arg->sock; bNodeTreeType *ntreetype = arg->ntree->typeinfo; uiBlockSetFlag(block, UI_BLOCK_NO_FLIP); uiBlockSetCurLayout(block, layout); split = uiLayoutSplit(layout, 0.0f, false); arg->bmain = bmain; arg->scene = scene; arg->layout = split; if (ntreetype && ntreetype->foreach_nodeclass) ntreetype->foreach_nodeclass(scene, arg, node_menu_column_foreach_cb); column = uiLayoutColumn(split, false); uiBlockSetCurLayout(block, column); if (sock->link) { uiItemL(column, IFACE_("Link"), ICON_NONE); but = block->buttons.last; but->drawflag = UI_BUT_TEXT_LEFT; but = uiDefBut(block, BUT, 0, IFACE_("Remove"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Remove nodes connected to the input")); uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE)); but = uiDefBut(block, BUT, 0, IFACE_("Disconnect"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Disconnect nodes connected to the input")); uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT)); } ui_node_menu_column(arg, NODE_CLASS_GROUP, N_("Group")); }
/* 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? uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL); /* general actions - management */ col = uiLayoutColumn(pa->layout, FALSE); block = uiLayoutGetBlock(col); but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Update Dependencies"), 0, 0, 10 * UI_UNIT_X, 22, NULL, 0.0, 0.0, 0, 0, TIP_("Force updates of dependencies")); uiButSetFunc(but, driver_update_flags_cb, fcu, NULL); but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Remove Driver"), 0, 0, 10 * UI_UNIT_X, 18, NULL, 0.0, 0.0, 0, 0, TIP_("Remove this driver")); uiButSetNFunc(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) { /* expression */ uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE); /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) uiItemL(col, IFACE_("ERROR: invalid Python expression"), ICON_ERROR); } else { /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) uiItemL(col, IFACE_("ERROR: invalid target channel(s)"), ICON_ERROR); } col = uiLayoutColumn(pa->layout, TRUE); /* 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 driver variables */ col = uiLayoutColumn(pa->layout, FALSE); block = uiLayoutGetBlock(col); but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Add Variable"), 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Add a new target variable for this Driver")); uiButSetFunc(but, driver_add_var_cb, driver, NULL); /* loop over targets, drawing them */ for (dvar = driver->variables.first; dvar; dvar = dvar->next) { PointerRNA dvar_ptr; uiLayout *box, *row; /* sub-layout column for this variable's settings */ col = uiLayoutColumn(pa->layout, TRUE); /* header panel */ box = uiLayoutBox(col); /* first row context info for driver */ RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr); row = uiLayoutRow(box, FALSE); block = uiLayoutGetBlock(row); /* variable name */ uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE); /* remove button */ uiBlockSetEmboss(block, UI_EMBOSSN); but = uiDefIconBut(block, 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")); uiButSetFunc(but, driver_delete_var_cb, driver, dvar); uiBlockSetEmboss(block, UI_EMBOSS); /* variable type */ row = uiLayoutRow(box, FALSE); uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NONE); /* 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; } /* 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); BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval); uiItemL(row, valBuf, ICON_NONE); } } /* cleanup */ MEM_freeN(ale); }
/* 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? uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL); /* general actions - management */ col = uiLayoutColumn(pa->layout, false); block = uiLayoutGetBlock(col); but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"), 0, 0, 10 * UI_UNIT_X, 22, NULL, 0.0, 0.0, 0, 0, TIP_("Force updates of dependencies")); uiButSetFunc(but, driver_update_flags_cb, fcu, NULL); but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"), 0, 0, 10 * UI_UNIT_X, 18, NULL, 0.0, 0.0, 0, 0, TIP_("Remove this driver")); uiButSetNFunc(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); /* 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 driver variables */ col = uiLayoutColumn(pa->layout, false); block = uiLayoutGetBlock(col); but = uiDefIconTextBut(block, 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")); uiButSetFunc(but, driver_add_var_cb, driver, NULL); /* loop over targets, drawing them */ for (dvar = driver->variables.first; dvar; dvar = dvar->next) { PointerRNA dvar_ptr; uiLayout *box, *row; /* sub-layout column for this variable's settings */ col = uiLayoutColumn(pa->layout, true); /* header panel */ box = uiLayoutBox(col); /* first row context info for driver */ RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr); row = uiLayoutRow(box, false); block = uiLayoutGetBlock(row); /* variable name */ uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE); /* remove button */ uiBlockSetEmboss(block, UI_EMBOSSN); but = uiDefIconBut(block, 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")); uiButSetFunc(but, driver_delete_var_cb, driver, dvar); uiBlockSetEmboss(block, UI_EMBOSS); /* variable type */ row = uiLayoutRow(box, false); uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NONE); /* 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; } /* 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); }
void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *userptr, PointerRNA *trackptr, int compact) { PropertyRNA *prop; uiBlock *block; uiBut *bt; PointerRNA clipptr; MovieClip *clip; MovieClipUser *user; MovieTrackingTrack *track; MovieTrackingMarker *marker; MarkerUpdateCb *cb; const char *tip; float pat_min[2], pat_max[2]; if (!ptr->data) return; prop = RNA_struct_find_property(ptr, propname); if (!prop) { printf("%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } if (RNA_property_type(prop) != PROP_POINTER) { printf("%s: expected pointer property for %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } clipptr = RNA_property_pointer_get(ptr, prop); clip = (MovieClip *)clipptr.data; user = userptr->data; track = trackptr->data; marker = BKE_tracking_marker_get(track, user->framenr); cb = MEM_callocN(sizeof(MarkerUpdateCb), "uiTemplateMarker update_cb"); cb->compact = compact; cb->clip = clip; cb->user = user; cb->track = track; cb->marker = marker; cb->marker_flag = marker->flag; cb->framenr = user->framenr; if (compact) { block = uiLayoutGetBlock(layout); if (cb->marker_flag & MARKER_DISABLED) tip = "Marker is disabled at current frame"; else tip = "Marker is enabled at current frame"; bt = uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, 20, 20, &cb->marker_flag, 0, 0, 1, 0, tip); uiButSetNFunc(bt, marker_update_cb, cb, NULL); } else { int width, height, step, digits; float pat_dim[2], search_dim[2], search_pos[2]; uiLayout *col; BKE_movieclip_get_size(clip, user, &width, &height); if (track->flag & TRACK_LOCKED) { uiLayoutSetActive(layout, FALSE); block = uiLayoutAbsoluteBlock(layout); uiDefBut(block, LABEL, 0, "Track is locked", 0, 0, 300, 19, NULL, 0, 0, 0, 0, ""); return; } step = 100; digits = 2; BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); sub_v2_v2v2(pat_dim, pat_max, pat_min); sub_v2_v2v2(search_dim, marker->search_max, marker->search_min); add_v2_v2v2(search_pos, marker->search_max, marker->search_min); mul_v2_fl(search_pos, 0.5); to_pixel_space(cb->marker_pos, marker->pos, width, height); to_pixel_space(cb->marker_pat, pat_dim, width, height); to_pixel_space(cb->marker_search, search_dim, width, height); to_pixel_space(cb->marker_search_pos, search_pos, width, height); to_pixel_space(cb->track_offset, track->offset, width, height); cb->marker_flag = marker->flag; block = uiLayoutAbsoluteBlock(layout); uiBlockSetHandleFunc(block, marker_block_handler, cb); uiBlockSetNFunc(block, marker_update_cb, cb, NULL); if (cb->marker_flag & MARKER_DISABLED) tip = "Marker is disabled at current frame"; else tip = "Marker is enabled at current frame"; uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, "Enabled", 10, 190, 145, 19, &cb->marker_flag, 0, 0, 0, 0, tip); col = uiLayoutColumn(layout, TRUE); uiLayoutSetActive(col, (cb->marker_flag & MARKER_DISABLED) == 0); block = uiLayoutAbsoluteBlock(col); uiBlockBeginAlign(block); uiDefBut(block, LABEL, 0, "Position:", 0, 190, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_POS, "X:", 10, 171, 145, 19, &cb->marker_pos[0], -10 * width, 10.0 * width, step, digits, "X-position of marker at frame in screen coordinates"); uiDefButF(block, NUM, B_MARKER_POS, "Y:", 165, 171, 145, 19, &cb->marker_pos[1], -10 * height, 10.0 * height, step, digits, "Y-position of marker at frame in screen coordinates"); uiDefBut(block, LABEL, 0, "Offset:", 0, 152, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_OFFSET, "X:", 10, 133, 145, 19, &cb->track_offset[0], -10 * width, 10.0 * width, step, digits, "X-offset to parenting point"); uiDefButF(block, NUM, B_MARKER_OFFSET, "Y:", 165, 133, 145, 19, &cb->track_offset[1], -10 * height, 10.0 * height, step, digits, "Y-offset to parenting point"); uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->marker_pat[0], 3.0f, 10.0 * width, step, digits, "Width of marker's pattern in screen coordinates"); uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->marker_pat[1], 3.0f, 10.0 * height, step, digits, "Height of marker's pattern in screen coordinates"); uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->marker_search_pos[0], -width, width, step, digits, "X-position of search at frame relative to marker's position"); uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->marker_search_pos[1], -height, height, step, digits, "X-position of search at frame relative to marker's position"); uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->marker_search[0], 3.0f, 10.0 * width, step, digits, "Width of marker's search in screen soordinates"); uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->marker_search[1], 3.0f, 10.0 * height, step, digits, "Height of marker's search in screen soordinates"); uiBlockEndAlign(block); } }
/* Note: This function uses pixelspace (0, 0, winx, winy), not view2d. * The controls are laid out as follows: * * ------------------------------------------- * | Directory input | execute | * ------------------------------------------- * | Filename input | + | - | cancel | * ------------------------------------------- * * The input widgets will stretch to fill any excess space. * When there isn't enough space for all controls to be shown, they are * hidden in this order: x/-, execute/cancel, input widgets. */ void file_draw_buttons(const bContext *C, ARegion *ar) { /* Button layout. */ const int max_x = ar->winx - 10; const int line1_y = ar->winy - (IMASEL_BUTTONS_HEIGHT / 2 + IMASEL_BUTTONS_MARGIN); const int line2_y = line1_y - (IMASEL_BUTTONS_HEIGHT / 2 + IMASEL_BUTTONS_MARGIN); const int input_minw = 20; const int btn_h = UI_UNIT_Y; const int btn_fn_w = UI_UNIT_X; const int btn_minw = 80; const int btn_margin = 20; const int separator = 4; /* Additional locals. */ char uiblockstr[32]; int loadbutton; int fnumbuttons; int min_x = 10; int chan_offs = 0; int available_w = max_x - min_x; int line1_w = available_w; int line2_w = available_w; uiBut *but; uiBlock *block; SpaceFile *sfile = CTX_wm_space_file(C); FileSelectParams *params = ED_fileselect_get_params(sfile); ARegion *artmp; /* Initialize UI block. */ BLI_snprintf(uiblockstr, sizeof(uiblockstr), "win %p", (void *)ar); block = uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS); /* exception to make space for collapsed region icon */ for (artmp = CTX_wm_area(C)->regionbase.first; artmp; artmp = artmp->next) { if (artmp->regiontype == RGN_TYPE_CHANNELS && artmp->flag & RGN_FLAG_HIDDEN) { chan_offs = 16; min_x += chan_offs; available_w -= chan_offs; } } /* Is there enough space for the execute / cancel buttons? */ loadbutton = UI_GetStringWidth(sfile->params->title) + btn_margin; if (loadbutton < btn_minw) { loadbutton = MAX2(btn_minw, btn_margin + UI_GetStringWidth(params->title)); } if (available_w <= loadbutton + separator + input_minw || params->title[0] == 0) { loadbutton = 0; } else { line1_w -= (loadbutton + separator); line2_w = line1_w; } /* Is there enough space for file number increment/decrement buttons? */ fnumbuttons = 2 * btn_fn_w; if (!loadbutton || line2_w <= fnumbuttons + separator + input_minw) { fnumbuttons = 0; } else { line2_w -= (fnumbuttons + separator); } /* Text input fields for directory and file. */ if (available_w > 0) { int overwrite_alert = file_draw_check_exists(sfile); /* callbacks for operator check functions */ uiBlockSetFunc(block, file_draw_check_cb, NULL, NULL); but = uiDefBut(block, TEX, -1, "", min_x, line1_y, line1_w - chan_offs, btn_h, params->dir, 0.0, (float)FILE_MAX, 0, 0, TIP_("File path")); uiButSetCompleteFunc(but, autocomplete_directory, NULL); uiButSetFlag(but, UI_BUT_NO_UTF8); uiButClearFlag(but, UI_BUT_UNDO); uiButSetNFunc(but, file_directory_enter_handle, NULL, but); /* TODO, directory editing is non-functional while a library is loaded * until this is properly supported just disable it. */ if (sfile->files && filelist_lib(sfile->files)) uiButSetFlag(but, UI_BUT_DISABLED); if ((params->flag & FILE_DIRSEL_ONLY) == 0) { but = uiDefBut(block, TEX, -1, "", min_x, line2_y, line2_w - chan_offs, btn_h, params->file, 0.0, (float)FILE_MAXFILE, 0, 0, TIP_(overwrite_alert ? N_("File name, overwrite existing") : N_("File name"))); uiButSetCompleteFunc(but, autocomplete_file, NULL); uiButSetFlag(but, UI_BUT_NO_UTF8); uiButClearFlag(but, UI_BUT_UNDO); /* silly workaround calling NFunc to ensure this does not get called * immediate ui_apply_but_func but only after button deactivates */ uiButSetNFunc(but, file_filename_enter_handle, NULL, but); /* check if this overrides a file and if the operator option is used */ if (overwrite_alert) { uiButSetFlag(but, UI_BUT_REDALERT); } } /* clear func */ uiBlockSetFunc(block, NULL, NULL, NULL); } /* Filename number increment / decrement buttons. */ if (fnumbuttons && (params->flag & FILE_DIRSEL_ONLY) == 0) { uiBlockBeginAlign(block); but = uiDefIconButO(block, BUT, "FILE_OT_filenum", 0, ICON_ZOOMOUT, min_x + line2_w + separator - chan_offs, line2_y, btn_fn_w, btn_h, TIP_("Decrement the filename number")); RNA_int_set(uiButGetOperatorPtrRNA(but), "increment", -1); but = uiDefIconButO(block, BUT, "FILE_OT_filenum", 0, ICON_ZOOMIN, min_x + line2_w + separator + btn_fn_w - chan_offs, line2_y, btn_fn_w, btn_h, TIP_("Increment the filename number")); RNA_int_set(uiButGetOperatorPtrRNA(but), "increment", 1); uiBlockEndAlign(block); } /* Execute / cancel buttons. */ if (loadbutton) { /* params->title is already translated! */ uiDefButO(block, BUT, "FILE_OT_execute", WM_OP_EXEC_REGION_WIN, params->title, max_x - loadbutton, line1_y, loadbutton, btn_h, ""); uiDefButO(block, BUT, "FILE_OT_cancel", WM_OP_EXEC_REGION_WIN, IFACE_("Cancel"), max_x - loadbutton, line2_y, loadbutton, btn_h, ""); } uiEndBlock(C, block); uiDrawBlock(C, block); }
static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) { bNodeTree *ntree = arg->ntree; bNodeSocket *sock = arg->sock; uiLayout *layout = arg->layout; uiLayout *column = NULL; uiBlock *block = uiLayoutGetBlock(layout); uiBut *but; NodeLinkArg *argN; int first = 1; int compatibility = 0; if (ntree->type == NTREE_SHADER) { if (BKE_scene_use_new_shading_nodes(arg->scene)) compatibility = NODE_NEW_SHADING; else compatibility = NODE_OLD_SHADING; } NODE_TYPES_BEGIN(ntype) { NodeLinkItem *items; int totitems; char name[UI_MAX_NAME_STR]; const char *cur_node_name = NULL; int i, num = 0; int icon = ICON_NONE; if (compatibility && !(ntype->compatibility & compatibility)) continue; if (ntype->nclass != nclass) continue; arg->node_type = ntype; ui_node_link_items(arg, SOCK_OUT, &items, &totitems); for (i = 0; i < totitems; ++i) if (ui_compatible_sockets(items[i].socket_type, sock->type)) num++; for (i = 0; i < totitems; ++i) { if (!ui_compatible_sockets(items[i].socket_type, sock->type)) continue; if (first) { column = uiLayoutColumn(layout, 0); uiBlockSetCurLayout(block, column); uiItemL(column, IFACE_(cname), ICON_NODE); but = block->buttons.last; first = 0; } if (num > 1) { if (!cur_node_name || !STREQ(cur_node_name, items[i].node_name)) { cur_node_name = items[i].node_name; /* XXX Do not use uiItemL here, it would add an empty icon as we are in a menu! */ uiDefBut(block, LABEL, 0, IFACE_(cur_node_name), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, ""); } BLI_snprintf(name, UI_MAX_NAME_STR, "%s", IFACE_(items[i].socket_name)); icon = ICON_BLANK1; } else { BLI_strncpy(name, IFACE_(items[i].node_name), UI_MAX_NAME_STR); icon = ICON_NONE; } but = uiDefIconTextBut(block, BUT, 0, icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input")); argN = MEM_dupallocN(arg); argN->item = items[i]; uiButSetNFunc(but, ui_node_link, argN, NULL); } if (items) MEM_freeN(items); } NODE_TYPES_END }
static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) { Main *bmain = arg->bmain; bNodeTree *ntree = arg->ntree; bNodeSocket *sock = arg->sock; uiLayout *layout = arg->layout; uiLayout *column = NULL; uiBlock *block = uiLayoutGetBlock(layout); uiBut *but; bNodeType *ntype; bNodeTree *ngroup; NodeLinkArg *argN; int first = 1; int compatibility= 0; if (ntree->type == NTREE_SHADER) { if (BKE_scene_use_new_shading_nodes(arg->scene)) compatibility= NODE_NEW_SHADING; else compatibility= NODE_OLD_SHADING; } if (nclass == NODE_CLASS_GROUP) { for (ngroup=bmain->nodetree.first; ngroup; ngroup=ngroup->id.next) { bNodeSocket *gsock; char name[UI_MAX_NAME_STR]; int i, j, num = 0; if (ngroup->type != ntree->type) continue; for (gsock=ngroup->inputs.first; gsock; gsock=gsock->next) if (ui_compatible_sockets(gsock->type, sock->type)) num++; for (i=0, j=0, gsock=ngroup->outputs.first; gsock; gsock=gsock->next, i++) { if (!ui_compatible_sockets(gsock->type, sock->type)) continue; if (first) { column= uiLayoutColumn(layout, 0); uiBlockSetCurLayout(block, column); uiItemL(column, cname, ICON_NODE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; first = 0; } if (num > 1) { if (j == 0) { uiItemL(column, ngroup->id.name+2, ICON_NODE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; } BLI_snprintf(name, UI_MAX_NAME_STR, " %s", gsock->name); j++; } else BLI_strncpy(name, ngroup->id.name+2, UI_MAX_NAME_STR); but = uiDefBut(block, BUT, 0, ngroup->id.name+2, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input"); argN = MEM_dupallocN(arg); argN->type = NODE_GROUP; argN->ngroup = ngroup; argN->output = i; uiButSetNFunc(but, ui_node_link, argN, NULL); } } } else { bNodeTreeType *ttype= ntreeGetType(ntree->type); for (ntype=ttype->node_types.first; ntype; ntype=ntype->next) { bNodeSocketTemplate *stemp; char name[UI_MAX_NAME_STR]; int i, j, num = 0; if (compatibility && !(ntype->compatibility & compatibility)) continue; if (ntype->nclass != nclass) continue; for (i=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++) if (ui_compatible_sockets(stemp->type, sock->type)) num++; for (i=0, j=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++) { if (!ui_compatible_sockets(stemp->type, sock->type)) continue; if (first) { column= uiLayoutColumn(layout, 0); uiBlockSetCurLayout(block, column); uiItemL(column, cname, ICON_NODE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; first = 0; } if (num > 1) { if (j == 0) { uiItemL(column, ntype->name, ICON_NODE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; } BLI_snprintf(name, UI_MAX_NAME_STR, " %s", stemp->name); j++; } else BLI_strncpy(name, ntype->name, UI_MAX_NAME_STR); but = uiDefBut(block, BUT, 0, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input"); argN = MEM_dupallocN(arg); argN->type = ntype->type; argN->output = i; uiButSetNFunc(but, ui_node_link, argN, NULL); } } } }