diff options
4 files changed, 111 insertions, 59 deletions
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 2fb0e9a0bea..68e273f2244 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -1694,6 +1694,7 @@ def km_image(params): ("image.view_all", {"type": 'HOME', "value": 'PRESS', "shift": True}, {"properties": [("fit_view", True)]}), ("image.view_selected", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None), + ("image.view_cursor_center", {"type": 'C', "value": 'PRESS', "shift": True}, None), ("image.view_pan", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), ("image.view_pan", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True}, None), ("image.view_pan", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 0044c6072a4..d302f099772 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -50,6 +50,7 @@ void IMAGE_OT_view_all(struct wmOperatorType *ot); void IMAGE_OT_view_pan(struct wmOperatorType *ot); void IMAGE_OT_view_selected(struct wmOperatorType *ot); void IMAGE_OT_view_center_cursor(struct wmOperatorType *ot); +void IMAGE_OT_view_cursor_center(struct wmOperatorType *ot); void IMAGE_OT_view_zoom(struct wmOperatorType *ot); void IMAGE_OT_view_zoom_in(struct wmOperatorType *ot); void IMAGE_OT_view_zoom_out(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 72405a51aca..48e1397601f 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -244,6 +244,70 @@ static bool image_not_packed_poll(bContext *C) return (ima && BLI_listbase_is_empty(&ima->packedfiles)); } +static void image_view_all(struct SpaceImage *sima, struct ARegion *region, struct wmOperator *op) +{ + float aspx, aspy, zoomx, zoomy, w, h; + int width, height; + const bool fit_view = RNA_boolean_get(op->ptr, "fit_view"); + + ED_space_image_get_size(sima, &width, &height); + ED_space_image_get_aspect(sima, &aspx, &aspy); + + w = width * aspx; + h = height * aspy; + + float xof = 0.0f, yof = 0.0f; + if ((sima->image == NULL) || (sima->image->source == IMA_SRC_TILED)) { + /* Extend the shown area to cover all UDIM tiles. */ + int x_tiles, y_tiles; + if (sima->image == NULL) { + x_tiles = sima->tile_grid_shape[0]; + y_tiles = sima->tile_grid_shape[1]; + } + else { + x_tiles = y_tiles = 1; + LISTBASE_FOREACH (ImageTile *, tile, &sima->image->tiles) { + int tile_x = (tile->tile_number - 1001) % 10; + int tile_y = (tile->tile_number - 1001) / 10; + x_tiles = max_ii(x_tiles, tile_x + 1); + y_tiles = max_ii(y_tiles, tile_y + 1); + } + } + xof = 0.5f * (x_tiles - 1.0f) * w; + yof = 0.5f * (y_tiles - 1.0f) * h; + w *= x_tiles; + h *= y_tiles; + } + + /* check if the image will fit in the image with (zoom == 1) */ + width = BLI_rcti_size_x(®ion->winrct) + 1; + height = BLI_rcti_size_y(®ion->winrct) + 1; + + if (fit_view) { + const int margin = 5; /* margin from border */ + + zoomx = (float)width / (w + 2 * margin); + zoomy = (float)height / (h + 2 * margin); + + sima_zoom_set(sima, region, min_ff(zoomx, zoomy), NULL, false); + } + else { + if ((w >= width || h >= height) && (width > 0 && height > 0)) { + zoomx = (float)width / w; + zoomy = (float)height / h; + + /* find the zoom value that will fit the image in the image space */ + sima_zoom_set(sima, region, 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy)), NULL, false); + } + else { + sima_zoom_set(sima, region, 1.0f, NULL, false); + } + } + + sima->xof = xof; + sima->yof = yof; +} + bool space_image_main_region_poll(bContext *C) { SpaceImage *sima = CTX_wm_space_image(C); @@ -736,70 +800,12 @@ static int image_view_all_exec(bContext *C, wmOperator *op) { SpaceImage *sima; ARegion *region; - float aspx, aspy, zoomx, zoomy, w, h; - int width, height; - const bool fit_view = RNA_boolean_get(op->ptr, "fit_view"); /* retrieve state */ sima = CTX_wm_space_image(C); region = CTX_wm_region(C); - ED_space_image_get_size(sima, &width, &height); - ED_space_image_get_aspect(sima, &aspx, &aspy); - - w = width * aspx; - h = height * aspy; - - float xof = 0.0f, yof = 0.0f; - if ((sima->image == NULL) || (sima->image->source == IMA_SRC_TILED)) { - /* Extend the shown area to cover all UDIM tiles. */ - int x_tiles, y_tiles; - if (sima->image == NULL) { - x_tiles = sima->tile_grid_shape[0]; - y_tiles = sima->tile_grid_shape[1]; - } - else { - x_tiles = y_tiles = 1; - LISTBASE_FOREACH (ImageTile *, tile, &sima->image->tiles) { - int tile_x = (tile->tile_number - 1001) % 10; - int tile_y = (tile->tile_number - 1001) / 10; - x_tiles = max_ii(x_tiles, tile_x + 1); - y_tiles = max_ii(y_tiles, tile_y + 1); - } - } - xof = 0.5f * (x_tiles - 1.0f) * w; - yof = 0.5f * (y_tiles - 1.0f) * h; - w *= x_tiles; - h *= y_tiles; - } - - /* check if the image will fit in the image with (zoom == 1) */ - width = BLI_rcti_size_x(®ion->winrct) + 1; - height = BLI_rcti_size_y(®ion->winrct) + 1; - - if (fit_view) { - const int margin = 5; /* margin from border */ - - zoomx = (float)width / (w + 2 * margin); - zoomy = (float)height / (h + 2 * margin); - - sima_zoom_set(sima, region, min_ff(zoomx, zoomy), NULL, false); - } - else { - if ((w >= width || h >= height) && (width > 0 && height > 0)) { - zoomx = (float)width / w; - zoomy = (float)height / h; - - /* find the zoom value that will fit the image in the image space */ - sima_zoom_set(sima, region, 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy)), NULL, false); - } - else { - sima_zoom_set(sima, region, 1.0f, NULL, false); - } - } - - sima->xof = xof; - sima->yof = yof; + image_view_all(sima, region, op); ED_region_tag_redraw(region); @@ -830,6 +836,49 @@ void IMAGE_OT_view_all(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Cursor To Center View Operator + * \{ */ + +static int view_cursor_center_exec(bContext *C, wmOperator *op) +{ + SpaceImage *sima; + ARegion *region; + + sima = CTX_wm_space_image(C); + region = CTX_wm_region(C); + + image_view_all(sima, region, op); + + sima->cursor[0] = 0.5f; + sima->cursor[1] = 0.5f; + + /* Needed for updating the cursor. */ + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL); + + return OPERATOR_FINISHED; +} + +void IMAGE_OT_view_cursor_center(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Cursor To Center View"; + ot->description = "Set 2D Cursor To Center View location"; + ot->idname = "IMAGE_OT_view_cursor_center"; + + /* api callbacks */ + ot->exec = view_cursor_center_exec; + ot->poll = ED_space_image_cursor_poll; + + /* properties */ + prop = RNA_def_boolean(ot->srna, "fit_view", 0, "Fit View", "Fit frame to the viewport"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Center View To Cursor Operator * \{ */ diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index c51d2f25efd..5a03b4f6ef0 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -200,6 +200,7 @@ static void image_operatortypes(void) WM_operatortype_append(IMAGE_OT_view_pan); WM_operatortype_append(IMAGE_OT_view_selected); WM_operatortype_append(IMAGE_OT_view_center_cursor); + WM_operatortype_append(IMAGE_OT_view_cursor_center); WM_operatortype_append(IMAGE_OT_view_zoom); WM_operatortype_append(IMAGE_OT_view_zoom_in); WM_operatortype_append(IMAGE_OT_view_zoom_out); |