static void datadropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg) { DataDropper *ddr = arg; int width; const char *name = ddr->name; wmWindow *win = CTX_wm_window(C); int x = win->eventstate->x; int y = win->eventstate->y; if ((name[0] == '\0') || (BLI_rcti_isect_pt(&ar->winrct, x, y) == false)) { return; } width = UI_GetStringWidth(name); x = x - ar->winrct.xmin; y = y - ar->winrct.ymin; y += 20; glColor4ub(0, 0, 0, 50); uiSetRoundBox(UI_CNR_ALL | UI_RB_ALPHA); uiRoundBox(x, y, x + width + 8, y + 15, 4); glColor4ub(255, 255, 255, 255); UI_DrawString(x + 4, y + 4, name); }
int GetButStringLength(const char *str) { int rt; rt= UI_GetStringWidth(str); return rt + 15; }
static void wm_drop_operator_draw(char *name, int x, int y) { int width= UI_GetStringWidth(name); glColor4ub(0, 0, 0, 50); uiSetRoundBox(UI_CNR_ALL | UI_RB_ALPHA); uiRoundBox(x, y, x + width + 8, y + 15, 4); glColor4ub(255, 255, 255, 255); UI_DrawString(x+4, y+4, name); }
/* Draw current frame number in a little green box beside the current frame indicator */ static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const bool time) { float xscale, yscale, x, y; char numstr[32] = " t"; /* t is the character to start replacing from */ short slen; /* because the frame number text is subject to the same scaling as the contents of the view */ UI_view2d_scale_get(v2d, &xscale, &yscale); glScalef(1.0f / xscale, 1.0f, 1.0f); /* get timecode string * - padding on str-buf passed so that it doesn't sit on the frame indicator * - power = 0, gives 'standard' behavior for time * but power = 1 is required for frames (to get integer frames) */ if (time) { BLI_timecode_string_from_time(&numstr[4], sizeof(numstr) - 4, 0, FRA2TIME(cfra), FPS, U.timecode_style); } else { BLI_timecode_string_from_time_simple(&numstr[4], sizeof(numstr) - 4, 1, cfra); } slen = (short)UI_GetStringWidth(numstr) - 1; /* get starting coordinates for drawing */ x = cfra * xscale; y = 0.9f * U.widget_unit; /* draw green box around/behind text */ UI_ThemeColorShade(TH_CFRAME, 0); glRectf(x, y, x + slen, y + 0.75f * U.widget_unit); /* draw current frame number - black text */ UI_ThemeColor(TH_TEXT); UI_DrawString(x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr); /* restore view transform */ glScalef(xscale, 1.0, 1.0); }
/* Draw current frame number in a little green box beside the current frame indicator */ static void draw_cfra_number (Scene *scene, View2D *v2d, float cfra, short time) { float xscale, yscale, x, y; char str[32] = " t"; /* t is the character to start replacing from */ short slen; /* because the frame number text is subject to the same scaling as the contents of the view */ UI_view2d_getscale(v2d, &xscale, &yscale); glScalef(1.0f/xscale, 1.0f, 1.0f); /* get timecode string * - padding on str-buf passed so that it doesn't sit on the frame indicator * - power = 0, gives 'standard' behaviour for time * but power = 1 is required for frames (to get integer frames) */ if (time) ANIM_timecode_string_from_frame(&str[4], scene, 0, time, FRA2TIME(cfra)); else ANIM_timecode_string_from_frame(&str[4], scene, 1, time, cfra); slen= (short)UI_GetStringWidth(str) - 1; /* get starting coordinates for drawing */ x= cfra * xscale; y= 18; /* draw green box around/behind text */ UI_ThemeColorShade(TH_CFRAME, 0); glRectf(x, y, x+slen, y+15); /* draw current frame number - black text */ UI_ThemeColor(TH_TEXT); UI_DrawString(x-5, y+3, str); /* restore view transform */ glScalef(xscale, 1.0, 1.0); }
/* draw settings for generator modifier */ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, short width) { FMod_Generator *data = (FMod_Generator *)fcm->data; uiLayout /* *col, */ /* UNUSED */ *row; uiBlock *block; uiBut *but; PointerRNA ptr; short bwidth = width - 1.5 * UI_UNIT_X; /* max button width */ /* init the RNA-pointer */ RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr); /* basic settings (backdrop + mode selector + some padding) */ /* col = uiLayoutColumn(layout, TRUE); */ /* UNUSED */ block = uiLayoutGetBlock(layout); uiBlockBeginAlign(block); but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL); uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL); uiBlockEndAlign(block); /* now add settings for individual modes */ switch (data->mode) { case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */ { float *cp = NULL; char xval[32]; unsigned int i; int maxXWidth; /* draw polynomial order selector */ row = uiLayoutRow(layout, FALSE); block = uiLayoutGetBlock(row); but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0.5f * UI_UNIT_X, 0, bwidth, UI_UNIT_Y, &data->poly_order, 1, 100, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); /* calculate maximum width of label for "x^n" labels */ if (data->arraysize > 2) { BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize); maxXWidth = UI_GetStringWidth(xval) + 0.5 * UI_UNIT_X; /* XXX: UI_GetStringWidth is not accurate */ } else { /* basic size (just "x") */ maxXWidth = UI_GetStringWidth("x") + 0.5 * UI_UNIT_X; } /* draw controls for each coefficient and a + sign at end of row */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); cp = data->coefficients; for (i = 0; (i < data->arraysize) && (cp); i++, cp++) { /* To align with first line... */ if (i) uiDefBut(block, LABEL, 1, " ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); else uiDefBut(block, LABEL, 1, "y =", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* coefficient */ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Coefficient for polynomial")); /* 'x' param (and '+' if necessary) */ if (i == 0) BLI_strncpy(xval, "", sizeof(xval)); else if (i == 1) BLI_strncpy(xval, "x", sizeof(xval)); else BLI_snprintf(xval, sizeof(xval), "x^%u", i); uiDefBut(block, LABEL, 1, xval, 0, 0, maxXWidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x")); if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) { uiDefBut(block, LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* next coefficient on a new row */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); } else { /* For alignment in UI! */ uiDefBut(block, LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } } break; } case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial expression */ { float *cp = NULL; unsigned int i; /* draw polynomial order selector */ row = uiLayoutRow(layout, FALSE); block = uiLayoutGetBlock(row); but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0, 0, width - 1.5 * UI_UNIT_X, UI_UNIT_Y, &data->poly_order, 1, 100, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); /* draw controls for each pair of coefficients */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); cp = data->coefficients; for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) { /* To align with first line */ if (i) uiDefBut(block, LABEL, 1, " ", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); else uiDefBut(block, LABEL, 1, "y =", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* opening bracket */ uiDefBut(block, LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* coefficients */ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Coefficient of x")); uiDefBut(block, LABEL, 1, "x +", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp + 1, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Second coefficient")); /* closing bracket and multiplication sign */ if ( (i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2) ) { uiDefBut(block, LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* set up new row for the next pair of coefficients */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); } else uiDefBut(block, LABEL, 1, ") ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } break; } } }
/* if rect set, do not draw */ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) { wmWindowManager *wm= CTX_wm_manager(C); wmDrag *drag; int cursorx, cursory, x, y; cursorx= win->eventstate->x; cursory= win->eventstate->y; if(rect) { rect->xmin= rect->xmax= cursorx; rect->ymin= rect->ymax= cursory; } /* XXX todo, multiline drag draws... but maybe not, more types mixed wont work well */ glEnable(GL_BLEND); for(drag= wm->drags.first; drag; drag= drag->next) { /* image or icon */ if(drag->imb) { x= cursorx - drag->sx/2; y= cursory - drag->sy/2; if(rect) drag_rect_minmax(rect, x, y, x+drag->sx, y+drag->sy); else { glColor4f(1.0, 1.0, 1.0, 0.65); /* this blends texture */ glaDrawPixelsTexScaled(x, y, drag->imb->x, drag->imb->y, GL_UNSIGNED_BYTE, drag->imb->rect, drag->scale, drag->scale); } } else { x= cursorx - 8; y= cursory - 2; /* icons assumed to be 16 pixels */ if(rect) drag_rect_minmax(rect, x, y, x+16, y+16); else UI_icon_draw_aspect(x, y, drag->icon, 1.0, 0.8); } /* item name */ if(drag->imb) { x= cursorx - drag->sx/2; y= cursory - drag->sy/2 - 16; } else { x= cursorx + 10; y= cursory + 1; } if(rect) { int w= UI_GetStringWidth(wm_drag_name(drag)); drag_rect_minmax(rect, x, y, x+w, y+16); } else { glColor4ub(255, 255, 255, 255); UI_DrawString(x, y, wm_drag_name(drag)); } /* operator name with roundbox */ if(drag->opname[0]) { if(drag->imb) { x= cursorx - drag->sx/2; y= cursory + drag->sy/2 + 4; } else { x= cursorx - 8; y= cursory + 16; } if(rect) { int w= UI_GetStringWidth(wm_drag_name(drag)); drag_rect_minmax(rect, x, y, x+w, y+16); } else wm_drop_operator_draw(drag->opname, x, y); } } glDisable(GL_BLEND); }
/* 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); uiBlockSetHandleFunc(block, do_file_buttons, NULL); /* 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 = uiDefButTextO(block, TEX, "FILE_OT_directory", 0, "", 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); if ((params->flag & FILE_DIRSEL_ONLY) == 0) { but = uiDefBut(block, TEX, B_FS_FILENAME, "", 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); /* operator button above does this automatic */ /* 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); }
/* Draw current frame number in a little green box beside the current frame indicator */ static void draw_cfra_number (Scene *scene, View2D *v2d, float cfra, short time) { float xscale, yscale, x, y; char str[32]; short slen; /* because the frame number text is subject to the same scaling as the contents of the view */ UI_view2d_getscale(v2d, &xscale, &yscale); glScalef(1.0f/xscale, 1.0f, 1.0f); if (time) { /* Timecode: * - In general, minutes and seconds should be shown, as most clips will be * within this length. Hours will only be included if relevant. * - Only show frames when zoomed in enough for them to be relevant * (using separator of '!' for frames). * When showing frames, use slightly different display to avoid confusion with mm:ss format * TODO: factor into reusable function. * Meanwhile keep in sync: * source/blender/editors/animation/anim_draw.c * source/blender/editors/interface/view2d.c */ float val= FRA2TIME(CFRA); int hours=0, minutes=0, seconds=0, frames=0; char neg[2]= ""; /* get values */ if (val < 0) { /* correction for negative values */ sprintf(neg, "-"); val = -val; } if (val >= 3600) { /* hours */ /* XXX should we only display a single digit for hours since clips are * VERY UNLIKELY to be more than 1-2 hours max? However, that would * go against conventions... */ hours= (int)val / 3600; val= (float)fmod(val, 3600); } if (val >= 60) { /* minutes */ minutes= (int)val / 60; val= (float)fmod(val, 60); } { /* seconds + frames * Frames are derived from 'fraction' of second. We need to perform some additional rounding * to cope with 'half' frames, etc., which should be fine in most cases */ seconds= (int)val; frames= (int)floor( ((val - seconds) * FPS) + 0.5f ); } /* print timecode to temp string buffer */ if (hours) sprintf(str, " %s%02d:%02d:%02d!%02d", neg, hours, minutes, seconds, frames); else if (minutes) sprintf(str, " %s%02d:%02d!%02d", neg, minutes, seconds, frames); else sprintf(str, " %s%d!%02d", neg, seconds, frames); } else sprintf(str, " %d", CFRA); slen= (short)UI_GetStringWidth(str) - 1; /* get starting coordinates for drawing */ x= cfra * xscale; y= 18; /* draw green box around/behind text */ UI_ThemeColorShadeAlpha(TH_CFRAME, 0, -100); glRectf(x, y, x+slen, y+15); /* draw current frame number - black text */ UI_ThemeColor(TH_TEXT); UI_DrawString(x-5, y+3, str); // XXX may need to be updated for font stuff /* restore view transform */ glScalef(xscale, 1.0, 1.0); }