UI: Automatic X-Ray #109318

Open
Lukas Sneyd wants to merge 20 commits from lcas/blender:automatic-xray into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
6 changed files with 210 additions and 13 deletions

View File

@ -920,7 +920,7 @@ class VIEW3D_HT_header(Header):
sub.active = overlay.show_overlays
sub.popover(panel="VIEW3D_PT_overlay", text="")
row = layout.row()
row = layout.row(align=True)
row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'})
# While exposing `shading.show_xray(_wireframe)` is correct.
@ -937,6 +937,7 @@ class VIEW3D_HT_header(Header):
icon='XRAY',
depress=draw_depressed,
)
row.popover(panel="VIEW3D_PT_xray", text="")
row = layout.row(align=True)
row.prop(shading, "type", text="", expand=True)
@ -6361,17 +6362,7 @@ class VIEW3D_PT_shading_options(Panel):
row = col.row(align=True)
if shading.type == 'WIREFRAME':
row.prop(shading, "show_xray_wireframe", text="")
sub = row.row()
sub.active = shading.show_xray_wireframe
sub.prop(shading, "xray_alpha_wireframe", text="X-Ray")
elif shading.type == 'SOLID':
row.prop(shading, "show_xray", text="")
sub = row.row()
sub.active = shading.show_xray
sub.prop(shading, "xray_alpha", text="X-Ray")
# X-ray mode is off when alpha is 1.0
if shading.type == 'SOLID':
xray_active = shading.show_xray and shading.xray_alpha != 1
row = col.row(align=True)
@ -6556,6 +6547,56 @@ class VIEW3D_PT_gizmo_display(Panel):
col.prop(view, "show_gizmo_camera_dof_distance", text="Focus Distance")
class VIEW3D_PT_xray(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "X-Ray"
bl_ui_units_x = 13
def draw(self, context):
layout = self.layout
layout.label(text="X-Ray Settings")
shading = VIEW3D_PT_shading.get_shading(context)
col = layout.column()
row = col.row(align=True)
if shading.type == 'WIREFRAME':
row.prop(shading, "show_xray_wireframe", text="")
sub = row.row()
sub.active = shading.show_xray_wireframe
sub.prop(shading, "xray_alpha_wireframe", text="X-Ray Wireframe")
elif shading.type == 'SOLID':
row.prop(shading, "show_xray", text="")
sub = row.row()
sub.active = shading.show_xray
sub.prop(shading, "xray_alpha", text="X-Ray Solid")
class VIEW3D_PT_auto_xray(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_parent_id = 'VIEW3D_PT_xray'
bl_label = "Automatic X-Ray"
bl_ui_units_x = 13
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
row = layout.row()
row.prop(tool_settings, "auto_xray", text="Enable")
sub = row.row()
sub.active = tool_settings.auto_xray
sub.prop(tool_settings, "auto_xray_object", text="Object")
sub.prop(tool_settings, "auto_xray_edit", text="Edit")
row = layout.row()
sub = row.row(align=True)
sub.active = tool_settings.auto_xray
sub.prop(tool_settings, "auto_xray_box", text="Box", toggle=True)
sub.prop(tool_settings, "auto_xray_lasso", text="Lasso", toggle=True)
sub.prop(tool_settings, "auto_xray_circle", text="Circle", toggle=True)
class VIEW3D_PT_overlay(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
@ -8541,6 +8582,8 @@ classes = (
VIEW3D_PT_shading_render_pass,
VIEW3D_PT_shading_compositor,
VIEW3D_PT_gizmo_display,
VIEW3D_PT_xray,
VIEW3D_PT_auto_xray,
VIEW3D_PT_overlay,
VIEW3D_PT_overlay_guides,
VIEW3D_PT_overlay_object,

View File

@ -377,6 +377,13 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
if (idprop) {
IDP_ClearProperty(idprop);
}
/* Auto X-Ray. */
ts->auto_xray_object = true;
ts->auto_xray_edit = true;
ts->auto_xray_box = true;
ts->auto_xray_lasso = true;
ts->auto_xray_circle = true;
}
void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)

View File

@ -398,6 +398,13 @@
/* Placement */ \
.snap_mode_tools = SCE_SNAP_TO_GEOM,\
.plane_axis = 2,\
\
/* Auto X-Ray */ \
.auto_xray_object = true, \
.auto_xray_edit = true, \
.auto_xray_box = true, \
.auto_xray_lasso = true, \
.auto_xray_circle = true, \
}
#define _DNA_DEFAULT_Sculpt \

View File

@ -1585,7 +1585,16 @@ typedef struct ToolSettings {
char gpencil_v3d_align;
/** General 2D Editor. */
char gpencil_v2d_align;
char _pad0[2];
/* X-Ray Options */
char auto_xray;
char auto_xray_reset;
char auto_xray_object;
char auto_xray_edit;
char auto_xray_box;
char auto_xray_lasso;
char auto_xray_circle;
char _pad0[3];
/* Annotations. */
/** Stroke placement settings - 3D View. */

View File

@ -3829,6 +3829,44 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Normal Vector", "Normal Vector used to copy, add or multiply");
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 1, 3);
/* Auto X-Ray */
prop = RNA_def_property(srna, "auto_xray", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray", "Transparent scene display during drag select");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_reset", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_reset", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Reset", "Helper that turns xray off for autoxray");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_object", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_object", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Object", "Automatic X-Ray in object mode");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_edit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_edit", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Edit", "Automatic X-Ray in edit mode");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_box", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_box", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Box", "Transparent scene display during box select");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_lasso", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_lasso", 0);
RNA_def_property_ui_text(
prop, "Auto X-Ray Lasso", "Transparent scene display during lasso select");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_circle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_circle", 0);
RNA_def_property_ui_text(
prop, "Auto X-Ray Circle", "Transparent scene display during circle select");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
/* Unified Paint Settings */
prop = RNA_def_property(srna, "unified_paint_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);

View File

@ -31,6 +31,7 @@
#include "ED_screen.hh"
#include "ED_select_utils.hh"
#include "ED_view3d.hh"
#include "UI_interface.hh"
@ -87,6 +88,18 @@ static void gesture_modal_state_to_operator(wmOperator *op, int modal_state)
}
}
static void gesture_toggle_xray(bContext *C)
{
ToolSettings *ts = CTX_data_tool_settings(C);
wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_toggle_xray", true);
BLI_assert(ot);
PointerRNA ptr;
WM_operator_properties_create_ptr(&ptr, ot);
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, NULL);
WM_operator_properties_free(&ptr);
ts->auto_xray_reset ^= true;
}
static int UNUSED_FUNCTION(gesture_modal_state_from_operator)(wmOperator *op)
{
PropertyRNA *prop;
@ -165,9 +178,24 @@ static bool gesture_box_apply(bContext *C, wmOperator *op)
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
const ARegion *region = CTX_wm_region(C);
const bool wait_for_input = !WM_event_is_mouse_drag_or_press(event) &&
RNA_boolean_get(op->ptr, "wait_for_input");
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
const bool auto_xray = ts->auto_xray && ts->auto_xray_box ?
obedit ? ts->auto_xray_edit : ts->auto_xray_object :
false;
if (ts->auto_xray_reset) {
ts->auto_xray_reset ^= true;
}
if (v3d && auto_xray) {
if (!XRAY_FLAG_ENABLED(v3d)) {
gesture_toggle_xray(C);
}
}
if (wait_for_input) {
op->customdata = WM_gesture_new(win, region, event, WM_GESTURE_CROSS_RECT);
@ -192,8 +220,11 @@ int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
rcti *rect = static_cast<rcti *>(gesture->customdata);
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
@ -216,13 +247,22 @@ int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
gesture->modal_state = event->val;
}
if (gesture_box_apply(C, op)) {
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_FINISHED;
}
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_CANCELLED;
}
case GESTURE_MODAL_CANCEL: {
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_CANCELLED;
}
@ -288,8 +328,24 @@ static void gesture_circle_apply(bContext *C, wmOperator *op);
int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
const bool wait_for_input = !WM_event_is_mouse_drag_or_press(event) &&
RNA_boolean_get(op->ptr, "wait_for_input");
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
const bool auto_xray = ts->auto_xray && ts->auto_xray_circle ?
obedit ? ts->auto_xray_edit : ts->auto_xray_object :
false;
if (ts->auto_xray_reset) {
ts->auto_xray_reset ^= true;
}
if (v3d && auto_xray) {
if (!XRAY_FLAG_ENABLED(v3d)) {
gesture_toggle_xray(C);
}
}
op->customdata = WM_gesture_new(win, CTX_wm_region(C), event, WM_GESTURE_CIRCLE);
wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
@ -347,8 +403,11 @@ static void gesture_circle_apply(bContext *C, wmOperator *op)
int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
rcti *rect = static_cast<rcti *>(gesture->customdata);
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
if (event->type == MOUSEMOVE) {
@ -417,6 +476,9 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (is_finished) {
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_FINISHED; /* use finish or we don't get an undo */
}
@ -479,7 +541,23 @@ void WM_OT_circle_gesture(wmOperatorType *ot)
int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
PropertyRNA *prop;
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
const bool auto_xray = ts->auto_xray && ts->auto_xray_lasso ?
obedit ? ts->auto_xray_edit : ts->auto_xray_object :
false;
if (ts->auto_xray_reset) {
ts->auto_xray_reset ^= true;
}
if (v3d && auto_xray) {
if (!XRAY_FLAG_ENABLED(v3d)) {
gesture_toggle_xray(C);
}
}
op->customdata = WM_gesture_new(win, CTX_wm_region(C), event, WM_GESTURE_LASSO);
@ -519,6 +597,10 @@ static int gesture_lasso_apply(bContext *C, wmOperator *op)
int retval = OPERATOR_FINISHED;
wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
PointerRNA itemptr;
View3D *v3d = CTX_wm_view3d(C);
Object *obedit = CTX_data_edit_object(C);
wmWindow *win = CTX_wm_window(C);
ToolSettings *ts = win->scene->toolsettings;
float loc[2];
int i;
const short *lasso = static_cast<const short int *>(gesture->customdata);
@ -540,12 +622,20 @@ static int gesture_lasso_apply(bContext *C, wmOperator *op)
OPERATOR_RETVAL_CHECK(retval);
}
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
return retval;
}
int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
View3D *v3d = CTX_wm_view3d(C);
Object *obedit = CTX_data_edit_object(C);
wmWindow *win = CTX_wm_window(C);
ToolSettings *ts = win->scene->toolsettings;
if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
@ -599,6 +689,9 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
}
case EVT_ESCKEY: {
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_CANCELLED;
}