Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/view2d.c
| Show All 25 Lines | |||||
| #include <math.h> | #include <math.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_userdef_types.h" | #include "DNA_userdef_types.h" | ||||
| #include "BLI_array.h" | |||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_link_utils.h" | #include "BLI_link_utils.h" | ||||
| #include "BLI_rect.h" | #include "BLI_rect.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_memarena.h" | #include "BLI_memarena.h" | ||||
| #include "BLI_timecode.h" | #include "BLI_timecode.h" | ||||
| #include "BLI_string.h" | |||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "GPU_immediate.h" | #include "GPU_immediate.h" | ||||
| #include "GPU_matrix.h" | #include "GPU_matrix.h" | ||||
| #include "GPU_state.h" | #include "GPU_state.h" | ||||
| ▲ Show 20 Lines • Show All 1,064 Lines • ▼ Show 20 Lines | void UI_view2d_zoom_cache_reset(void) | ||||
| /* note: only some views draw text, we could check for this case to avoid clearning cache */ | /* note: only some views draw text, we could check for this case to avoid clearning cache */ | ||||
| BLF_cache_clear(); | BLF_cache_clear(); | ||||
| } | } | ||||
| /* *********************************************************************** */ | /* *********************************************************************** */ | ||||
| /* View Matrix Setup */ | /* View Matrix Setup */ | ||||
| /* mapping function to ensure 'cur' draws extended over the area where sliders are */ | /* mapping function to ensure 'cur' draws extended over the area where sliders are */ | ||||
| static void view2d_map_cur_using_mask(View2D *v2d, rctf *r_curmasked) | static void view2d_map_cur_using_mask(const View2D *v2d, rctf *r_curmasked) | ||||
| { | { | ||||
| *r_curmasked = v2d->cur; | *r_curmasked = v2d->cur; | ||||
| if (view2d_scroll_mapped(v2d->scroll)) { | if (view2d_scroll_mapped(v2d->scroll)) { | ||||
| float sizex = BLI_rcti_size_x(&v2d->mask); | float sizex = BLI_rcti_size_x(&v2d->mask); | ||||
| float sizey = BLI_rcti_size_y(&v2d->mask); | float sizey = BLI_rcti_size_y(&v2d->mask); | ||||
| /* prevent tiny or narrow regions to get | /* prevent tiny or narrow regions to get | ||||
| Show All 15 Lines | if (sizex > 0.0f && sizey > 0.0f) { | ||||
| if (v2d->mask.ymax + 1 != v2d->winy) { | if (v2d->mask.ymax + 1 != v2d->winy) { | ||||
| r_curmasked->ymax += dy * (float)(v2d->winy - v2d->mask.ymax - 1); | r_curmasked->ymax += dy * (float)(v2d->winy - v2d->mask.ymax - 1); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Set view matrices to use 'cur' rect as viewing frame for View2D drawing */ | /* Set view matrices to use 'cur' rect as viewing frame for View2D drawing */ | ||||
| void UI_view2d_view_ortho(View2D *v2d) | void UI_view2d_view_ortho(const View2D *v2d) | ||||
| { | { | ||||
| rctf curmasked; | rctf curmasked; | ||||
| const int sizex = BLI_rcti_size_x(&v2d->mask); | const int sizex = BLI_rcti_size_x(&v2d->mask); | ||||
| const int sizey = BLI_rcti_size_y(&v2d->mask); | const int sizey = BLI_rcti_size_y(&v2d->mask); | ||||
| const float eps = 0.001f; | const float eps = 0.001f; | ||||
| float xofs = 0.0f, yofs = 0.0f; | float xofs = 0.0f, yofs = 0.0f; | ||||
| /* Pixel offsets (-GLA_PIXEL_OFS) are needed to get 1:1 | /* Pixel offsets (-GLA_PIXEL_OFS) are needed to get 1:1 | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | void UI_view2d_view_restore(const bContext *C) | ||||
| GPU_matrix_identity_set(); | GPU_matrix_identity_set(); | ||||
| // ED_region_pixelspace(CTX_wm_region(C)); | // ED_region_pixelspace(CTX_wm_region(C)); | ||||
| } | } | ||||
| /* *********************************************************************** */ | /* *********************************************************************** */ | ||||
| /* Gridlines */ | /* Gridlines */ | ||||
| /* View2DGrid is typedef'd in UI_view2d.h */ | |||||
| struct View2DGrid { | |||||
| float dx, dy; /* stepsize (in pixels) between gridlines */ | |||||
| float startx, starty; /* initial coordinates to start drawing grid from */ | |||||
| int powerx, powery; /* step as power of 10 */ | |||||
| }; | |||||
| /* --------------- */ | |||||
| /* try to write step as a power of 10 */ | |||||
| static void step_to_grid(float *step, const int unit, int *r_power) | |||||
| { | |||||
| const float loga = (float)log10(*step); | |||||
| float rem; | |||||
| int power = (int)(loga); | |||||
| rem = loga - power; | |||||
| rem = (float)pow(10.0, rem); | |||||
| if (loga < 0.0f) { | |||||
| if (rem < 0.2f) { | |||||
| rem = 0.2f; | |||||
| } | |||||
| else if (rem < 0.5f) { | |||||
| rem = 0.5f; | |||||
| } | |||||
| else { | |||||
| rem = 1.0f; | |||||
| } | |||||
| *step = rem * (float)pow(10.0, power); | |||||
| /* for frames, we want 1.0 frame intervals only */ | |||||
| if (unit == V2D_UNIT_FRAMES) { | |||||
| rem = 1.0f; | |||||
| /* use 2 since there are grid lines drawn in between, | |||||
| * this way to get 1 line per frame */ | |||||
| *step = 2.0f; | |||||
| } | |||||
| /* prevents printing 1.0 2.0 3.0 etc */ | |||||
| if (rem == 1.0f) { | |||||
| power++; | |||||
| } | |||||
| } | |||||
| else { | |||||
| if (rem < 2.0f) { | |||||
| rem = 2.0f; | |||||
| } | |||||
| else if (rem < 5.0f) { | |||||
| rem = 5.0f; | |||||
| } | |||||
| else { | |||||
| rem = 10.0f; | |||||
| } | |||||
| *step = rem * (float)pow(10.0, power); | |||||
| power++; | |||||
| /* prevents printing 1.0, 2.0, 3.0, etc. */ | |||||
| if (rem == 10.0f) { | |||||
| power++; | |||||
| } | |||||
| } | |||||
| *r_power = power; | |||||
| } | |||||
| /** | |||||
| * Initialize settings necessary for drawing gridlines in a 2d-view | |||||
| * | |||||
| * - Currently, will return pointer to View2DGrid struct that needs to | |||||
| * be freed with UI_view2d_grid_free() | |||||
| * - Units + clamping args will be checked, to make sure they are valid values that can be used | |||||
| * so it is very possible that we won't return grid at all! | |||||
| * | |||||
| * - xunits,yunits = V2D_UNIT_* grid steps in seconds or frames | |||||
| * - xclamp,yclamp = V2D_CLAMP_* only show whole-number intervals | |||||
| * - winx = width of region we're drawing to, note: not used but keeping for completeness. | |||||
| * - winy = height of region we're drawing into | |||||
| */ | |||||
| View2DGrid *UI_view2d_grid_calc(Scene *scene, | |||||
| View2D *v2d, | |||||
| short xunits, | |||||
| short xclamp, | |||||
| short yunits, | |||||
| short yclamp, | |||||
| int UNUSED(winx), | |||||
| int winy) | |||||
| { | |||||
| View2DGrid *grid; | |||||
| float space, seconddiv; | |||||
| /* check that there are at least some workable args */ | |||||
| if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) && ELEM(V2D_ARG_DUMMY, yunits, yclamp)) { | |||||
| return NULL; | |||||
| } | |||||
| /* grid here is allocated... */ | |||||
| grid = MEM_callocN(sizeof(View2DGrid), "View2DGrid"); | |||||
| /* rule: gridstep is minimal GRIDSTEP pixels */ | |||||
| if (xunits == V2D_UNIT_SECONDS) { | |||||
| seconddiv = (float)(0.01 * FPS); | |||||
| } | |||||
| else { | |||||
| seconddiv = 1.0f; | |||||
| } | |||||
| /* calculate x-axis grid scale (only if both args are valid) */ | |||||
| if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) == 0) { | |||||
| space = BLI_rctf_size_x(&v2d->cur); | |||||
| if (space != 0.0f) { | |||||
| const float pixels = (float)BLI_rcti_size_x(&v2d->mask); | |||||
| if (pixels != 0.0f) { | |||||
| grid->dx = (U.v2d_min_gridsize * UI_DPI_FAC * space) / (seconddiv * pixels); | |||||
| step_to_grid(&grid->dx, xunits, &grid->powerx); | |||||
| grid->dx *= seconddiv; | |||||
| } | |||||
| } | |||||
| if (xclamp == V2D_GRID_CLAMP) { | |||||
| CLAMP_MIN(grid->dx, 0.1f); | |||||
| CLAMP_MIN(grid->powerx, 0); | |||||
| grid->powerx -= 2; | |||||
| } | |||||
| } | |||||
| /* calculate y-axis grid scale (only if both args are valid) */ | |||||
| if (ELEM(V2D_ARG_DUMMY, yunits, yclamp) == 0) { | |||||
| space = BLI_rctf_size_y(&v2d->cur); | |||||
| if (space != 0.0f) { | |||||
| const float pixels = (float)winy; | |||||
| if (pixels != 0.0f) { | |||||
| grid->dy = U.v2d_min_gridsize * UI_DPI_FAC * space / pixels; | |||||
| step_to_grid(&grid->dy, yunits, &grid->powery); | |||||
| } | |||||
| } | |||||
| if (yclamp == V2D_GRID_CLAMP) { | |||||
| CLAMP_MIN(grid->dy, 1.0f); | |||||
| CLAMP_MIN(grid->powery, 1); | |||||
| } | |||||
| } | |||||
| /* calculate start position */ | |||||
| if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) == 0) { | |||||
| grid->startx = seconddiv * (v2d->cur.xmin / seconddiv - | |||||
| (float)fmod(v2d->cur.xmin / seconddiv, grid->dx / seconddiv)); | |||||
| if (v2d->cur.xmin < 0.0f) { | |||||
| grid->startx -= grid->dx; | |||||
| } | |||||
| } | |||||
| else { | |||||
| grid->startx = v2d->cur.xmin; | |||||
| } | |||||
| if (ELEM(V2D_ARG_DUMMY, yunits, yclamp) == 0) { | |||||
| grid->starty = (v2d->cur.ymin - (float)fmod(v2d->cur.ymin, grid->dy)); | |||||
| if (v2d->cur.ymin < 0.0f) { | |||||
| grid->starty -= grid->dy; | |||||
| } | |||||
| } | |||||
| else { | |||||
| grid->starty = v2d->cur.ymin; | |||||
| } | |||||
| return grid; | |||||
| } | |||||
| /* Draw gridlines in the given 2d-region */ | |||||
| void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag) | |||||
| { | |||||
| float vec1[2], vec2[2]; | |||||
| int a, step; | |||||
| int vertical_minor_step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC); | |||||
| int horizontal_major_step = (BLI_rcti_size_y(&v2d->mask) + 1) / | |||||
| (U.v2d_min_gridsize * UI_DPI_FAC); | |||||
| uchar grid_line_color[3]; | |||||
| /* check for grid first, as it may not exist */ | |||||
| if (grid == NULL) { | |||||
| return; | |||||
| } | |||||
| /* Count the needed vertices for the gridlines */ | |||||
| unsigned vertex_count = 0; | |||||
| if (flag & V2D_VERTICAL_LINES) { | |||||
| /* vertical lines */ | |||||
| vertex_count += 2 * vertical_minor_step; /* minor gridlines */ | |||||
| vertex_count += 2 * (vertical_minor_step + 2); /* major gridlines */ | |||||
| } | |||||
| if (flag & V2D_HORIZONTAL_LINES) { | |||||
| /* horizontal lines */ | |||||
| vertex_count += 2 * (horizontal_major_step + 1); /* major gridlines */ | |||||
| /* fine lines */ | |||||
| if (flag & V2D_HORIZONTAL_FINELINES) { | |||||
| vertex_count += 2 * (horizontal_major_step + 1); | |||||
| } | |||||
| } | |||||
| /* axes */ | |||||
| if (flag & V2D_HORIZONTAL_AXIS) { | |||||
| vertex_count += 2; | |||||
| } | |||||
| if (flag & V2D_VERTICAL_AXIS) { | |||||
| vertex_count += 2; | |||||
| } | |||||
| /* If there is nothing to render, exit early */ | |||||
| if (vertex_count == 0) { | |||||
| return; | |||||
| } | |||||
| GPUVertFormat *format = immVertexFormat(); | |||||
| uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | |||||
| uint color = GPU_vertformat_attr_add( | |||||
| format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); | |||||
| immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); | |||||
| immBegin(GPU_PRIM_LINES, vertex_count); | |||||
| /* vertical lines */ | |||||
| if (flag & V2D_VERTICAL_LINES) { | |||||
| /* initialize initial settings */ | |||||
| vec1[0] = vec2[0] = grid->startx; | |||||
| vec1[1] = grid->starty; | |||||
| vec2[1] = v2d->cur.ymax; | |||||
| /* minor gridlines */ | |||||
| step = vertical_minor_step; | |||||
| if (step != 0) { | |||||
| UI_GetThemeColor3ubv(TH_GRID, grid_line_color); | |||||
| for (a = 0; a < step; a++) { | |||||
| immAttrSkip(color); | |||||
| immVertex2fv(pos, vec1); | |||||
| immAttr3ubv(color, grid_line_color); | |||||
| immVertex2fv(pos, vec2); | |||||
| vec2[0] = vec1[0] += grid->dx; | |||||
| } | |||||
| } | |||||
| /* major gridlines */ | |||||
| vec2[0] = vec1[0] -= 0.5f * grid->dx; | |||||
| UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color); | |||||
| step++; | |||||
| for (a = 0; a <= step; a++) { | |||||
| immAttrSkip(color); | |||||
| immVertex2fv(pos, vec1); | |||||
| immAttr3ubv(color, grid_line_color); | |||||
| immVertex2fv(pos, vec2); | |||||
| vec2[0] = vec1[0] -= grid->dx; | |||||
| } | |||||
| } | |||||
| /* horizontal lines */ | |||||
| if (flag & V2D_HORIZONTAL_LINES) { | |||||
| /* only major gridlines */ | |||||
| vec1[1] = vec2[1] = grid->starty; | |||||
| vec1[0] = grid->startx; | |||||
| vec2[0] = v2d->cur.xmax; | |||||
| step = horizontal_major_step; | |||||
| UI_GetThemeColor3ubv(TH_GRID, grid_line_color); | |||||
| for (a = 0; a <= step; a++) { | |||||
| immAttrSkip(color); | |||||
| immVertex2fv(pos, vec1); | |||||
| immAttr3ubv(color, grid_line_color); | |||||
| immVertex2fv(pos, vec2); | |||||
| vec2[1] = vec1[1] += grid->dy; | |||||
| } | |||||
| /* fine grid lines */ | |||||
| vec2[1] = vec1[1] -= 0.5f * grid->dy; | |||||
| step++; | |||||
| if (flag & V2D_HORIZONTAL_FINELINES) { | |||||
| UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color); | |||||
| for (a = 0; a < step; a++) { | |||||
| immAttrSkip(color); | |||||
| immVertex2fv(pos, vec1); | |||||
| immAttr3ubv(color, grid_line_color); | |||||
| immVertex2fv(pos, vec2); | |||||
| vec2[1] = vec1[1] -= grid->dy; | |||||
| } | |||||
| } | |||||
| } | |||||
| /* Axes are drawn as darker lines */ | |||||
| UI_GetThemeColorShade3ubv(TH_GRID, -50, grid_line_color); | |||||
| /* horizontal axis */ | |||||
| if (flag & V2D_HORIZONTAL_AXIS) { | |||||
| vec1[0] = v2d->cur.xmin; | |||||
| vec2[0] = v2d->cur.xmax; | |||||
| vec1[1] = vec2[1] = 0.0f; | |||||
| immAttrSkip(color); | |||||
| immVertex2fv(pos, vec1); | |||||
| immAttr3ubv(color, grid_line_color); | |||||
| immVertex2fv(pos, vec2); | |||||
| } | |||||
| /* vertical axis */ | |||||
| if (flag & V2D_VERTICAL_AXIS) { | |||||
| vec1[1] = v2d->cur.ymin; | |||||
| vec2[1] = v2d->cur.ymax; | |||||
| vec1[0] = vec2[0] = 0.0f; | |||||
| immAttrSkip(color); | |||||
| immVertex2fv(pos, vec1); | |||||
| immAttr3ubv(color, grid_line_color); | |||||
| immVertex2fv(pos, vec2); | |||||
| } | |||||
| immEnd(); | |||||
| immUnbindProgram(); | |||||
| } | |||||
| /* Draw a constant grid in given 2d-region */ | /* Draw a constant grid in given 2d-region */ | ||||
| void UI_view2d_constant_grid_draw(View2D *v2d, float step) | void UI_view2d_constant_grid_draw(View2D *v2d, float step) | ||||
| { | { | ||||
| float start_x, start_y; | float start_x, start_y; | ||||
| int count_x, count_y; | int count_x, count_y; | ||||
| start_x = v2d->cur.xmin; | start_x = v2d->cur.xmin; | ||||
| if (start_x < 0.0) { | if (start_x < 0.0) { | ||||
| ▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | void UI_view2d_multi_grid_draw(View2D *v2d, int colorid, float step, int level_size, int totlevels) | ||||
| immVertex2f(pos, v2d->cur.xmin, 0.0f); | immVertex2f(pos, v2d->cur.xmin, 0.0f); | ||||
| immAttr3ubv(color, grid_line_color); | immAttr3ubv(color, grid_line_color); | ||||
| immVertex2f(pos, v2d->cur.xmax, 0.0f); | immVertex2f(pos, v2d->cur.xmax, 0.0f); | ||||
| immEnd(); | immEnd(); | ||||
| immUnbindProgram(); | immUnbindProgram(); | ||||
| } | } | ||||
| static void get_scale_indicator_text( | |||||
| const Scene *scene, float value, int brevity_level, short unit, uint max_length, char *r_str) | |||||
| { | |||||
| if (unit == V2D_UNIT_SECONDS) { | |||||
| BLI_timecode_string_from_time( | |||||
| r_str, max_length, brevity_level, value / (float)FPS, FPS, U.timecode_style); | |||||
| } | |||||
| else { | |||||
| BLI_timecode_string_from_time_seconds(r_str, max_length, brevity_level, value); | |||||
| } | |||||
| } | |||||
| void UI_view2d_grid_draw_numbers_horizontal(const Scene *scene, | |||||
| const View2D *v2d, | |||||
| const View2DGrid *grid, | |||||
| const rcti *rect, | |||||
| int unit, | |||||
| bool whole_numbers_only) | |||||
| { | |||||
| BLI_assert(grid); | |||||
| float xstep = grid->dx * UI_view2d_scale_get_x(v2d); | |||||
| if (xstep <= 0.0f) { | |||||
| return; | |||||
| } | |||||
| float initial_xpos = UI_view2d_view_to_region_x(v2d, grid->startx); | |||||
| float ypos = (float)rect->ymin + 4 * UI_DPI_FAC; | |||||
| float initial_value = grid->startx; | |||||
| float value_step = grid->dx; | |||||
| int brevity_level = grid->powerx; | |||||
| /* Make sure that the value_step is >= 1 when only whole numbers are displayed. | |||||
| * Otherwise the same number could be displayed more than once. */ | |||||
| if (whole_numbers_only) { | |||||
| while (value_step < 0.9999f) { | |||||
| xstep *= 2.0f; | |||||
| value_step *= 2.0f; | |||||
| } | |||||
| } | |||||
| /* Skip first few steps if they don't intersect | |||||
| * the rectangle that will contain the numbers. */ | |||||
| while (initial_xpos < rect->xmin) { | |||||
| initial_xpos += xstep; | |||||
| initial_value += value_step; | |||||
| } | |||||
| if (unit == V2D_UNIT_FRAMES) { | |||||
| brevity_level = 1; | |||||
| } | |||||
| const int font_id = BLF_default(); | |||||
| UI_FontThemeColor(font_id, TH_TEXT); | |||||
| BLF_batch_draw_begin(); | |||||
| for (float xpos = initial_xpos, value = initial_value; xpos < rect->xmax; | |||||
| xpos += xstep, value += value_step) { | |||||
| char text[32]; | |||||
| get_scale_indicator_text(scene, value, brevity_level, unit, sizeof(text), text); | |||||
| float text_width = BLF_width(font_id, text, strlen(text)); | |||||
| BLF_draw_default_ascii(xpos - text_width / 2.0f, ypos, 0.0f, text, sizeof(text)); | |||||
| } | |||||
| BLF_batch_draw_end(); | |||||
| } | |||||
| void UI_view2d_grid_draw_numbers_vertical(const Scene *scene, | |||||
| const View2D *v2d, | |||||
| const View2DGrid *grid, | |||||
| const rcti *rect, | |||||
| int unit, | |||||
| float text_offset) | |||||
| { | |||||
| BLI_assert(grid); | |||||
| float ystep = grid->dy * UI_view2d_scale_get_y(v2d); | |||||
| if (ystep <= 0.0f) { | |||||
| return; | |||||
| } | |||||
| const int font_id = BLF_default(); | |||||
| UI_FontThemeColor(font_id, TH_TEXT); | |||||
| BLF_enable(font_id, BLF_ROTATION); | |||||
| BLF_rotation(font_id, M_PI_2); | |||||
| float initial_value = grid->starty; | |||||
| float value_step = grid->dy; | |||||
| float xpos = rect->xmax - 2.0f * UI_DPI_FAC; | |||||
| float initial_ypos = UI_view2d_view_to_region_y(v2d, grid->starty); | |||||
| /* Currently only used by the sequencer to display | |||||
| * channel numbers in the center. */ | |||||
| initial_ypos += text_offset * ystep; | |||||
| /* Skip first few steps if they don't intersect | |||||
| * the rectangle that will contain the numbers. */ | |||||
| while (initial_ypos < rect->ymin) { | |||||
| initial_ypos += ystep; | |||||
| initial_value += value_step; | |||||
| } | |||||
| for (float ypos = initial_ypos, value = initial_value; ypos < rect->ymax; | |||||
| ypos += ystep, value += value_step) { | |||||
| char text[32]; | |||||
| get_scale_indicator_text(scene, value, grid->powery, unit, sizeof(text), text); | |||||
| float text_width = BLF_width(font_id, text, sizeof(text)); | |||||
| BLF_draw_default_ascii(xpos, ypos - text_width / 2.0f, 0.0f, text, sizeof(text)); | |||||
| } | |||||
| BLF_disable(font_id, BLF_ROTATION); | |||||
| } | |||||
| /* the price we pay for not exposting structs :( */ | |||||
| void UI_view2d_grid_size(View2DGrid *grid, float *r_dx, float *r_dy) | |||||
| { | |||||
| *r_dx = grid->dx; | |||||
| *r_dy = grid->dy; | |||||
| } | |||||
| /* free temporary memory used for drawing grid */ | |||||
| void UI_view2d_grid_free(View2DGrid *grid) | |||||
| { | |||||
| /* only free if there's a grid */ | |||||
| if (grid) { | |||||
| MEM_freeN(grid); | |||||
| } | |||||
| } | |||||
| /* *********************************************************************** */ | /* *********************************************************************** */ | ||||
| /* Scrollers */ | /* Scrollers */ | ||||
| /** | /** | ||||
| * View2DScrollers is typedef'd in UI_view2d.h | * View2DScrollers is typedef'd in UI_view2d.h | ||||
| * | * | ||||
| * \warning The start of this struct must not change, as view2d_ops.c uses this too. | * \warning The start of this struct must not change, as view2d_ops.c uses this too. | ||||
| * For now, we don't need to have a separate (internal) header for structs like this... | * For now, we don't need to have a separate (internal) header for structs like this... | ||||
| ▲ Show 20 Lines • Show All 904 Lines • Show Last 20 Lines | |||||