diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index 4a91cc52f14..19841a9c43f 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -7920,6 +7920,8 @@ def km_grease_pencil_primitive_tool_modal_map(params): ("SCALE", {"type": 'S', "value": 'PRESS'}, None), ("INCREASE_SUBDIVISION", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), ("DECREASE_SUBDIVISION", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), + ("CHANGE_RADIUS", {"type": 'F', "value": 'PRESS'}, None), + ("CHANGE_OPACITY", {"type": 'F', "value": 'PRESS', "shift": True}, None), ]) return keymap diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_primitive.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_primitive.cc index e535449d261..4ccef7a0b3f 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_primitive.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_primitive.cc @@ -74,6 +74,10 @@ enum class OperatorMode : int8_t { RotateAll = 5, /* Scale all control points. */ ScaleAll = 6, + /* Change brush radius. */ + ChangeRadius = 7, + /* Change brush opacity. */ + ChangeOpacity = 8, }; enum class ControlPointType : int8_t { @@ -93,6 +97,8 @@ enum class ModalKeyMode : int8_t { Scale, IncreaseSubdivision, DecreaseSubdivision, + ChangeRadius, + ChangeOpacity, }; static constexpr float ui_primary_point_draw_size_px = 8.0f; @@ -141,6 +147,11 @@ struct PrimitiveToolOperation { float2 start_position_2d; int active_control_point_index; + /* Reference mouse position for initial radial control value. */ + float2 reference_position_2d; + /* Initial value of radius or opacity. */ + std::variant initial_value; + ViewOpsData *vod; }; @@ -957,6 +968,68 @@ static void grease_pencil_primitive_scale_all_update(PrimitiveToolOperation &ptd } } +static void grease_pencil_primitive_init_radius(PrimitiveToolOperation &ptd) +{ + PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id); + const int value = RNA_int_get(&brush_ptr, "size"); + + ptd.initial_value.emplace(value); + ptd.reference_position_2d = ptd.start_position_2d - float2(value, 0.0f); +} + +static void grease_pencil_primitive_init_opacity(PrimitiveToolOperation &ptd) +{ + const float display_size = 200.0f * UI_SCALE_FAC; + + PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id); + const float value = RNA_float_get(&brush_ptr, "strength"); + + ptd.initial_value.emplace(value); + ptd.reference_position_2d = ptd.start_position_2d - float2(value * display_size, 0.0f); +} + +static void grease_pencil_primitive_cancel_radius(PrimitiveToolOperation &ptd) +{ + PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id); + RNA_int_set(&brush_ptr, "size", std::get(ptd.initial_value)); +} + +static void grease_pencil_primitive_cancel_opacity(PrimitiveToolOperation &ptd) +{ + PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id); + RNA_float_set(&brush_ptr, "strength", std::get(ptd.initial_value)); +} + +static void grease_pencil_primitive_change_radius(PrimitiveToolOperation &ptd, + const wmEvent *event) +{ + /* Clamp reference position if mouse moves past the limits. */ + const float2 mouse_co = float2(event->mval); + ptd.reference_position_2d.x = std::min(ptd.reference_position_2d.x, mouse_co.x); + const float2 delta = mouse_co - ptd.reference_position_2d; + /* Clamp to work around brush property getting "stuck" on zero. */ + const int new_value = std::max(int(delta.x), 1); + + PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id); + RNA_int_set(&brush_ptr, "size", new_value); +} + +static void grease_pencil_primitive_change_opacity(PrimitiveToolOperation &ptd, + const wmEvent *event) +{ + const float display_size = 200.0f * UI_SCALE_FAC; + + /* Clamp reference position if mouse moves past the limits. */ + const float2 mouse_co = float2(event->mval); + ptd.reference_position_2d.x = std::max(std::min(ptd.reference_position_2d.x, mouse_co.x), + mouse_co.x - display_size); + const float2 delta = mouse_co - ptd.reference_position_2d; + const float new_value = delta.x / display_size; + + PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id); + RNA_float_set(&brush_ptr, "strength", new_value); +} + static int primitive_check_ui_hover(const PrimitiveToolOperation &ptd, const wmEvent *event) { float closest_distance_squared = std::numeric_limits::max(); @@ -1121,6 +1194,26 @@ static int grease_pencil_primitive_event_modal_map(bContext *C, } return OPERATOR_RUNNING_MODAL; } + case int(ModalKeyMode::ChangeRadius): { + if (ptd.mode == OperatorMode::Idle) { + ptd.start_position_2d = float2(event->mval); + ptd.mode = OperatorMode::ChangeRadius; + grease_pencil_primitive_init_radius(ptd); + + grease_pencil_primitive_save(ptd); + } + return OPERATOR_RUNNING_MODAL; + } + case int(ModalKeyMode::ChangeOpacity): { + if (ptd.mode == OperatorMode::Idle) { + ptd.start_position_2d = float2(event->mval); + ptd.mode = OperatorMode::ChangeOpacity; + grease_pencil_primitive_init_opacity(ptd); + + grease_pencil_primitive_save(ptd); + } + return OPERATOR_RUNNING_MODAL; + } } return OPERATOR_RUNNING_MODAL; @@ -1134,7 +1227,9 @@ static int grease_pencil_primitive_mouse_event(PrimitiveToolOperation &ptd, cons OperatorMode::Extruding, OperatorMode::DragAll, OperatorMode::RotateAll, - OperatorMode::ScaleAll)) + OperatorMode::ScaleAll, + OperatorMode::ChangeRadius, + OperatorMode::ChangeOpacity)) { ptd.mode = OperatorMode::Idle; return OPERATOR_RUNNING_MODAL; @@ -1226,6 +1321,14 @@ static void grease_pencil_primitive_operator_update(PrimitiveToolOperation &ptd, grease_pencil_primitive_rotate_all_update(ptd, event); break; } + case OperatorMode::ChangeRadius: { + grease_pencil_primitive_change_radius(ptd, event); + break; + } + case OperatorMode::ChangeOpacity: { + grease_pencil_primitive_change_opacity(ptd, event); + break; + } case OperatorMode::Idle: { /* Do nothing. */ break; @@ -1290,6 +1393,13 @@ static int grease_pencil_primitive_modal(bContext *C, wmOperator *op, const wmEv return OPERATOR_CANCELLED; } else { + if (ptd.mode == OperatorMode::ChangeRadius) { + grease_pencil_primitive_cancel_radius(ptd); + } + if (ptd.mode == OperatorMode::ChangeOpacity) { + grease_pencil_primitive_cancel_opacity(ptd); + } + ptd.mode = OperatorMode::Idle; grease_pencil_primitive_load(ptd); @@ -1496,6 +1606,8 @@ void ED_primitivetool_modal_keymap(wmKeyConfig *keyconf) 0, "Decrease Subdivision", ""}, + {int(ModalKeyMode::ChangeRadius), "CHANGE_RADIUS", 0, "Change Radius", ""}, + {int(ModalKeyMode::ChangeOpacity), "CHANGE_OPACITY", 0, "Change Opacity", ""}, {0, nullptr, 0, nullptr, nullptr}, };