WIP: Keymap Click-Drag Direction #105488

Closed
Lukas Sneyd wants to merge 3 commits from lcas:keymap-click-drag-direction into blender-v3.5-release

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
7 changed files with 249 additions and 23 deletions

View File

@ -182,7 +182,24 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level):
if map_type in {'KEYBOARD', 'MOUSE'} and kmi.value == 'CLICK_DRAG':
subrow = sub.row()
subrow.prop(kmi, "direction")
if bpy.context.preferences.inputs.click_drag_direction == 'LEFT_RIGHT':
if kmi.direction == 'ANY' or kmi.direction == 'EAST' or kmi.direction == 'WEST':
subrow.label(text="Direction:")
else:
subrow.label(text="WARNING - No Direction:")
subrow.operator("preferences.set_direction_any", text="Any", depress= kmi.direction == 'ANY').item_id = kmi.id
subrow.operator("preferences.set_direction_left", text="Left", depress= kmi.direction == 'WEST').item_id = kmi.id
subrow.operator("preferences.set_direction_right", text="Right", depress= kmi.direction == 'EAST').item_id = kmi.id
elif bpy.context.preferences.inputs.click_drag_direction == 'UP_DOWN':
if kmi.direction == 'ANY' or kmi.direction == 'NORTH' or kmi.direction == 'SOUTH':
subrow.label(text="Direction:")
else:
subrow.label(text="WARNING - No Direction:")
subrow.operator("preferences.set_direction_any", text="Any", depress= kmi.direction == 'ANY').item_id = kmi.id
subrow.operator("preferences.set_direction_up", text="Up", depress= kmi.direction == 'NORTH').item_id = kmi.id
subrow.operator("preferences.set_direction_down", text="Down", depress= kmi.direction == 'SOUTH').item_id = kmi.id
else:
subrow.prop(kmi, "direction")
subrow = sub.row()
subrow.scale_x = 0.75

View File

@ -400,6 +400,111 @@ class PREFERENCES_OT_keyitem_remove(Operator):
return {'FINISHED'}
class PREFERENCES_OT_set_direction_any(Operator):
"""Drag in any direction"""
bl_idname = "preferences.set_direction_any"
bl_label = "Set Direction Any"
item_id: IntProperty(
name="Item Identifier",
description="Identifier of the item to remove",
)
@classmethod
def poll(cls, context):
return hasattr(context, "keymap")
def execute(self, context):
km = context.keymap
kmi = km.keymap_items.from_id(self.item_id)
km.keymap_items.set_direction_any(kmi)
return {'FINISHED'}
class PREFERENCES_OT_set_direction_left(Operator):
"""Drag to the left"""
bl_idname = "preferences.set_direction_left"
bl_label = "Set Direction Left"
item_id: IntProperty(
name="Item Identifier",
description="Identifier of the item to remove",
)
@classmethod
def poll(cls, context):
return hasattr(context, "keymap")
def execute(self, context):
km = context.keymap
kmi = km.keymap_items.from_id(self.item_id)
km.keymap_items.set_direction_left(kmi)
return {'FINISHED'}
class PREFERENCES_OT_set_direction_right(Operator):
"""Drag to the right"""
bl_idname = "preferences.set_direction_right"
bl_label = "Set Direction Right"
item_id: IntProperty(
name="Item Identifier",
description="Identifier of the item to remove",
)
@classmethod
def poll(cls, context):
return hasattr(context, "keymap")
def execute(self, context):
km = context.keymap
kmi = km.keymap_items.from_id(self.item_id)
km.keymap_items.set_direction_right(kmi)
return {'FINISHED'}
class PREFERENCES_OT_set_direction_up(Operator):
"""Drag upwards"""
bl_idname = "preferences.set_direction_up"
bl_label = "Set Direction Up"
item_id: IntProperty(
name="Item Identifier",
description="Identifier of the item to remove",
)
@classmethod
def poll(cls, context):
return hasattr(context, "keymap")
def execute(self, context):
km = context.keymap
kmi = km.keymap_items.from_id(self.item_id)
km.keymap_items.set_direction_up(kmi)
return {'FINISHED'}
class PREFERENCES_OT_set_direction_down(Operator):
"""Drag downwards"""
bl_idname = "preferences.set_direction_down"
bl_label = "Set Direction Down"
item_id: IntProperty(
name="Item Identifier",
description="Identifier of the item to remove",
)
@classmethod
def poll(cls, context):
return hasattr(context, "keymap")
def execute(self, context):
km = context.keymap
kmi = km.keymap_items.from_id(self.item_id)
km.keymap_items.set_direction_down(kmi)
return {'FINISHED'}
class PREFERENCES_OT_keyconfig_remove(Operator):
"""Remove key config"""
bl_idname = "preferences.keyconfig_remove"
@ -1156,6 +1261,11 @@ classes = (
PREFERENCES_OT_keyconfig_test,
PREFERENCES_OT_keyitem_add,
PREFERENCES_OT_keyitem_remove,
PREFERENCES_OT_set_direction_any,
PREFERENCES_OT_set_direction_left,
PREFERENCES_OT_set_direction_right,
PREFERENCES_OT_set_direction_up,
PREFERENCES_OT_set_direction_down,
PREFERENCES_OT_keyitem_restore,
PREFERENCES_OT_keymap_restore,
PREFERENCES_OT_theme_install,

View File

@ -1566,6 +1566,7 @@ class USERPREF_PT_input_mouse(InputPanel, CenterAlignMixIn, Panel):
rowsub.prop(inputs, "mouse_emulate_3_button_modifier")
flow.prop(inputs, "use_mouse_continuous")
flow.prop(inputs, "use_drag_immediately")
flow.prop(inputs, "click_drag_direction")
flow.prop(inputs, "mouse_double_click_time", text="Double Click Speed")
flow.prop(inputs, "drag_threshold_mouse")
flow.prop(inputs, "drag_threshold_tablet")

View File

@ -840,7 +840,9 @@ typedef struct UserDef {
/** #eGPUBackendType */
short gpu_backend;
char _pad7[4];
/** Keymap click-drag direction style */
char click_drag_direction;
char _pad7[3];
/** Private, defaults to 20 for 72 DPI setting. */
short widget_unit;
@ -1153,6 +1155,13 @@ typedef enum eUserpref_TableAPI {
USER_TABLET_WINTAB = 2,
} eUserpref_TabletAPI;
/** #UserDef.click_drag_direction_types */
typedef enum eUserpref_Click_Drag_Direction {
USER_CLICK_DRAG_DIRECTION_EIGHT_WAY = 0,
USER_CLICK_DRAG_DIRECTION_LEFT_RIGHT = 1,
USER_CLICK_DRAG_DIRECTION_UP_DOWN = 2,
} eUserpref_Click_Drag_Direction;
/** #UserDef.app_flag */
typedef enum eUserpref_APP_Flag {
USER_APP_LOCK_CORNER_SPLIT = (1 << 0),

View File

@ -5774,6 +5774,17 @@ static void rna_def_userdef_input(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem click_drag_direction_types[] = {
{USER_CLICK_DRAG_DIRECTION_EIGHT_WAY,
"EIGHT_WAY",
0,
"Eight",
"Eight directions (N, NE, E, SE, S, SW, W, NW)"},
{USER_CLICK_DRAG_DIRECTION_LEFT_RIGHT, "LEFT_RIGHT", 0, "Left Right", "Left and right"},
{USER_CLICK_DRAG_DIRECTION_UP_DOWN, "UP_DOWN", 0, "Up Down", "Up and down"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem view_zoom_styles[] = {
{USER_ZOOM_CONTINUE,
"CONTINUE",
@ -5880,6 +5891,11 @@ static void rna_def_userdef_input(BlenderRNA *brna)
"Release Confirms",
"Moving things with a mouse drag confirms when releasing the button");
prop = RNA_def_property(srna, "click_drag_direction", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, click_drag_direction_types);
RNA_def_property_ui_text(
prop, "Keymap Drag Directions", "Style of click-drag direction the keymap will use");
prop = RNA_def_property(srna, "use_numeric_input_advanced", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_FLAG_NUMINPUT_ADVANCED);
RNA_def_property_ui_text(prop,

View File

@ -389,6 +389,41 @@ static void rna_KeyMap_item_remove(wmKeyMap *km, ReportList *reports, PointerRNA
RNA_POINTER_INVALIDATE(kmi_ptr);
}
static void rna_keymap_set_direction_any(wmKeyMap *km, PointerRNA *kmi_ptr)
{
wmKeyMapItem *kmi = kmi_ptr->data;
kmi->direction = -1;
WM_keyconfig_update_tag(km, kmi);
}
static void rna_keymap_set_direction_left(wmKeyMap *km, PointerRNA *kmi_ptr)
{
wmKeyMapItem *kmi = kmi_ptr->data;
kmi->direction = 7;
WM_keyconfig_update_tag(km, kmi);
}
static void rna_keymap_set_direction_right(wmKeyMap *km, PointerRNA *kmi_ptr)
{
wmKeyMapItem *kmi = kmi_ptr->data;
kmi->direction = 3;
WM_keyconfig_update_tag(km, kmi);
}
static void rna_keymap_set_direction_up(wmKeyMap *km, PointerRNA *kmi_ptr)
{
wmKeyMapItem *kmi = kmi_ptr->data;
kmi->direction = 1;
WM_keyconfig_update_tag(km, kmi);
}
static void rna_keymap_set_direction_down(wmKeyMap *km, PointerRNA *kmi_ptr)
{
wmKeyMapItem *kmi = kmi_ptr->data;
kmi->direction = 5;
WM_keyconfig_update_tag(km, kmi);
}
static PointerRNA rna_KeyMap_item_find_from_operator(ID *id,
wmKeyMap *km,
const char *idname,
@ -1199,6 +1234,31 @@ void RNA_api_keymapitems(StructRNA *srna)
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "set_direction_any", "rna_keymap_set_direction_any");
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "set_direction_left", "rna_keymap_set_direction_left");
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "set_direction_right", "rna_keymap_set_direction_right");
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "set_direction_up", "rna_keymap_set_direction_up");
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "set_direction_down", "rna_keymap_set_direction_down");
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "from_id", "WM_keymap_item_find_id");
parm = RNA_def_property(func, "id", PROP_INT, PROP_NONE);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);

View File

@ -271,29 +271,42 @@ int WM_event_drag_direction(const wmEvent *event)
event->xy[1] - event->prev_press_xy[1],
};
int theta = round_fl_to_int(4.0f * atan2f((float)delta[1], (float)delta[0]) / (float)M_PI);
int val = KM_DIRECTION_W;
bool left_right = U.click_drag_direction & USER_CLICK_DRAG_DIRECTION_LEFT_RIGHT;
bool up_down = U.click_drag_direction & USER_CLICK_DRAG_DIRECTION_UP_DOWN;
int theta = left_right ?
round_fl_to_int(atan2f(0.0f, (float)delta[0]) / (float)M_PI) :
up_down ?
round_fl_to_int(atan2f(0.0f, (float)delta[1]) / (float)M_PI) :
round_fl_to_int(4.0f * atan2f((float)delta[1], (float)delta[0]) / (float)M_PI);
int val = up_down ? KM_DIRECTION_S : KM_DIRECTION_W;
if (theta == 0) {
val = KM_DIRECTION_E;
if (left_right || up_down) {
if (theta == 0) {
val = up_down ? KM_DIRECTION_N : KM_DIRECTION_E;
}
}
else if (theta == 1) {
val = KM_DIRECTION_NE;
}
else if (theta == 2) {
val = KM_DIRECTION_N;
}
else if (theta == 3) {
val = KM_DIRECTION_NW;
}
else if (theta == -1) {
val = KM_DIRECTION_SE;
}
else if (theta == -2) {
val = KM_DIRECTION_S;
}
else if (theta == -3) {
val = KM_DIRECTION_SW;
else {
if (theta == 0) {
val = KM_DIRECTION_E;
}
else if (theta == 1) {
val = KM_DIRECTION_NE;
}
else if (theta == 2) {
val = KM_DIRECTION_N;
}
else if (theta == 3) {
val = KM_DIRECTION_NW;
}
else if (theta == -1) {
val = KM_DIRECTION_SE;
}
else if (theta == -2) {
val = KM_DIRECTION_S;
}
else if (theta == -3) {
val = KM_DIRECTION_SW;
}
}
#if 0