Merge branch 'blender-v2.82-release'
This commit is contained in:
@@ -33,7 +33,7 @@ defs_precalc = {
|
|||||||
"glColor3ubv": {0: 3},
|
"glColor3ubv": {0: 3},
|
||||||
"glColor4ubv": {0: 4},
|
"glColor4ubv": {0: 4},
|
||||||
|
|
||||||
"glColor4usv": {0: 3},
|
"glColor3usv": {0: 3},
|
||||||
"glColor4usv": {0: 4},
|
"glColor4usv": {0: 4},
|
||||||
|
|
||||||
"glColor3fv": {0: 3},
|
"glColor3fv": {0: 3},
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ void BKE_reports_init(ReportList *reports, int flag)
|
|||||||
reports->flag = flag;
|
reports->flag = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only frees the list \a reports.
|
||||||
|
* To make displayed reports disappear, either remove window-manager reports
|
||||||
|
* (wmWindowManager.reports, or CTX_wm_reports()), or use #WM_report_banners_cancel().
|
||||||
|
*/
|
||||||
void BKE_reports_clear(ReportList *reports)
|
void BKE_reports_clear(ReportList *reports)
|
||||||
{
|
{
|
||||||
Report *report, *report_next;
|
Report *report, *report_next;
|
||||||
|
|||||||
@@ -153,7 +153,8 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
|
|||||||
XRAY_FLAG_ENABLED(draw_ctx->v3d);
|
XRAY_FLAG_ENABLED(draw_ctx->v3d);
|
||||||
pd->armature.show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0) &&
|
pd->armature.show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0) &&
|
||||||
!is_select_mode;
|
!is_select_mode;
|
||||||
pd->armature.do_pose_fade_geom = (pd->overlay.flag & V3D_OVERLAY_BONE_SELECT) &&
|
pd->armature.do_pose_xray = (pd->overlay.flag & V3D_OVERLAY_BONE_SELECT) != 0;
|
||||||
|
pd->armature.do_pose_fade_geom = pd->armature.do_pose_xray &&
|
||||||
((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) == 0) &&
|
((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) == 0) &&
|
||||||
draw_ctx->object_pose != NULL;
|
draw_ctx->object_pose != NULL;
|
||||||
|
|
||||||
@@ -2238,8 +2239,7 @@ static void armature_context_setup(ArmatureDrawContext *ctx,
|
|||||||
float *const_color)
|
float *const_color)
|
||||||
{
|
{
|
||||||
const bool is_object_mode = !do_envelope_dist;
|
const bool is_object_mode = !do_envelope_dist;
|
||||||
const bool is_xray = (ob->dtx & OB_DRAWXRAY) != 0 ||
|
const bool is_xray = (ob->dtx & OB_DRAWXRAY) != 0 || (pd->armature.do_pose_xray && is_pose_mode);
|
||||||
(pd->armature.do_pose_fade_geom && is_pose_mode);
|
|
||||||
const bool draw_as_wire = (ob->dt < OB_SOLID);
|
const bool draw_as_wire = (ob->dt < OB_SOLID);
|
||||||
const bool is_filled = (!pd->armature.transparent && !draw_as_wire) || !is_object_mode;
|
const bool is_filled = (!pd->armature.transparent && !draw_as_wire) || !is_object_mode;
|
||||||
const bool is_transparent = pd->armature.transparent || (draw_as_wire && !is_object_mode);
|
const bool is_transparent = pd->armature.transparent || (draw_as_wire && !is_object_mode);
|
||||||
@@ -2424,7 +2424,8 @@ void OVERLAY_pose_draw(OVERLAY_Data *vedata)
|
|||||||
DRW_draw_pass(psl->armature_bone_select_ps);
|
DRW_draw_pass(psl->armature_bone_select_ps);
|
||||||
|
|
||||||
if (DRW_state_is_fbo()) {
|
if (DRW_state_is_fbo()) {
|
||||||
GPU_framebuffer_bind(fbl->overlay_line_fb);
|
GPU_framebuffer_bind(fbl->overlay_line_in_front_fb);
|
||||||
|
GPU_framebuffer_clear_depth(fbl->overlay_line_in_front_fb, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRW_draw_pass(psl->armature_ps[1]);
|
DRW_draw_pass(psl->armature_ps[1]);
|
||||||
|
|||||||
@@ -300,6 +300,7 @@ typedef struct OVERLAY_PrivateData {
|
|||||||
struct {
|
struct {
|
||||||
bool transparent;
|
bool transparent;
|
||||||
bool show_relations;
|
bool show_relations;
|
||||||
|
bool do_pose_xray;
|
||||||
bool do_pose_fade_geom;
|
bool do_pose_fade_geom;
|
||||||
} armature;
|
} armature;
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -949,8 +949,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
|
|||||||
|
|
||||||
/* Init batches and request VBOs & IBOs */
|
/* Init batches and request VBOs & IBOs */
|
||||||
if (DRW_batch_requested(cache->batch.surfaces, GPU_PRIM_TRIS)) {
|
if (DRW_batch_requested(cache->batch.surfaces, GPU_PRIM_TRIS)) {
|
||||||
DRW_ibo_request(cache->batch.surfaces, &cache->ibo.surfaces_tris);
|
DRW_vbo_request(cache->batch.surfaces, &cache->ordered.loop_pos_nor);
|
||||||
DRW_vbo_request(cache->batch.surfaces, &cache->ordered.pos_nor);
|
|
||||||
}
|
}
|
||||||
if (DRW_batch_requested(cache->batch.surfaces_edges, GPU_PRIM_LINES)) {
|
if (DRW_batch_requested(cache->batch.surfaces_edges, GPU_PRIM_LINES)) {
|
||||||
DRW_ibo_request(cache->batch.surfaces_edges, &cache->ibo.surfaces_lines);
|
DRW_ibo_request(cache->batch.surfaces_edges, &cache->ibo.surfaces_lines);
|
||||||
|
|||||||
@@ -104,12 +104,6 @@ void DRW_hair_init(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct DRWHairInstanceData {
|
|
||||||
DrawData dd;
|
|
||||||
|
|
||||||
float mat[4][4];
|
|
||||||
} DRWHairInstanceData;
|
|
||||||
|
|
||||||
static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
|
static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
|
||||||
ParticleSystem *psys,
|
ParticleSystem *psys,
|
||||||
ModifierData *md,
|
ModifierData *md,
|
||||||
@@ -120,13 +114,7 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
|
|||||||
/* TODO(fclem): Pass the scene as parameter */
|
/* TODO(fclem): Pass the scene as parameter */
|
||||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||||
Scene *scene = draw_ctx->scene;
|
Scene *scene = draw_ctx->scene;
|
||||||
static float unit_mat[4][4] = {
|
float dupli_mat[4][4];
|
||||||
{1, 0, 0, 0},
|
|
||||||
{0, 1, 0, 0},
|
|
||||||
{0, 0, 1, 0},
|
|
||||||
{0, 0, 0, 1},
|
|
||||||
};
|
|
||||||
float(*dupli_mat)[4];
|
|
||||||
Object *dupli_parent = DRW_object_get_dupli_parent(object);
|
Object *dupli_parent = DRW_object_get_dupli_parent(object);
|
||||||
DupliObject *dupli_object = DRW_object_get_dupli(object);
|
DupliObject *dupli_object = DRW_object_get_dupli(object);
|
||||||
|
|
||||||
@@ -164,13 +152,6 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((dupli_parent != NULL) && (dupli_object != NULL)) {
|
if ((dupli_parent != NULL) && (dupli_object != NULL)) {
|
||||||
DRWHairInstanceData *hair_inst_data = (DRWHairInstanceData *)DRW_drawdata_ensure(
|
|
||||||
&object->id,
|
|
||||||
(DrawEngineType *)&drw_shgroup_create_hair_procedural_ex,
|
|
||||||
sizeof(DRWHairInstanceData),
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
dupli_mat = hair_inst_data->mat;
|
|
||||||
if (dupli_object->type & OB_DUPLICOLLECTION) {
|
if (dupli_object->type & OB_DUPLICOLLECTION) {
|
||||||
copy_m4_m4(dupli_mat, dupli_parent->obmat);
|
copy_m4_m4(dupli_mat, dupli_parent->obmat);
|
||||||
}
|
}
|
||||||
@@ -181,14 +162,17 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dupli_mat = unit_mat;
|
unit_m4(dupli_mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", hair_cache->final[subdiv].proc_tex);
|
DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", hair_cache->final[subdiv].proc_tex);
|
||||||
DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &hair_cache->final[subdiv].strands_res, 1);
|
DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &hair_cache->final[subdiv].strands_res, 1);
|
||||||
DRW_shgroup_uniform_int_copy(shgrp, "hairThicknessRes", thickness_res);
|
DRW_shgroup_uniform_int_copy(shgrp, "hairThicknessRes", thickness_res);
|
||||||
DRW_shgroup_uniform_float(shgrp, "hairRadShape", &part->shape, 1);
|
DRW_shgroup_uniform_float(shgrp, "hairRadShape", &part->shape, 1);
|
||||||
DRW_shgroup_uniform_mat4(shgrp, "hairDupliMatrix", dupli_mat);
|
DRW_shgroup_uniform_vec4_copy(shgrp, "hairDupliMatrix[0]", dupli_mat[0]);
|
||||||
|
DRW_shgroup_uniform_vec4_copy(shgrp, "hairDupliMatrix[1]", dupli_mat[1]);
|
||||||
|
DRW_shgroup_uniform_vec4_copy(shgrp, "hairDupliMatrix[2]", dupli_mat[2]);
|
||||||
|
DRW_shgroup_uniform_vec4_copy(shgrp, "hairDupliMatrix[3]", dupli_mat[3]);
|
||||||
DRW_shgroup_uniform_float_copy(shgrp, "hairRadRoot", part->rad_root * part->rad_scale * 0.5f);
|
DRW_shgroup_uniform_float_copy(shgrp, "hairRadRoot", part->rad_root * part->rad_scale * 0.5f);
|
||||||
DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", part->rad_tip * part->rad_scale * 0.5f);
|
DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", part->rad_tip * part->rad_scale * 0.5f);
|
||||||
DRW_shgroup_uniform_bool_copy(
|
DRW_shgroup_uniform_bool_copy(
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ uniform float hairRadTip = 0.0;
|
|||||||
uniform float hairRadShape = 0.5;
|
uniform float hairRadShape = 0.5;
|
||||||
uniform bool hairCloseTip = true;
|
uniform bool hairCloseTip = true;
|
||||||
|
|
||||||
uniform mat4 hairDupliMatrix;
|
uniform vec4 hairDupliMatrix[4];
|
||||||
|
|
||||||
/* -- Per control points -- */
|
/* -- Per control points -- */
|
||||||
uniform samplerBuffer hairPointBuffer; /* RGBA32F */
|
uniform samplerBuffer hairPointBuffer; /* RGBA32F */
|
||||||
@@ -159,8 +159,11 @@ void hair_get_pos_tan_binor_time(bool is_persp,
|
|||||||
wtan = wpos - texelFetch(hairPointBuffer, id - 1).point_position;
|
wtan = wpos - texelFetch(hairPointBuffer, id - 1).point_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpos = (hairDupliMatrix * vec4(wpos, 1.0)).xyz;
|
mat4 obmat = mat4(
|
||||||
wtan = -normalize(mat3(hairDupliMatrix) * wtan);
|
hairDupliMatrix[0], hairDupliMatrix[1], hairDupliMatrix[2], hairDupliMatrix[3]);
|
||||||
|
|
||||||
|
wpos = (obmat * vec4(wpos, 1.0)).xyz;
|
||||||
|
wtan = -normalize(mat3(obmat) * wtan);
|
||||||
|
|
||||||
vec3 camera_vec = (is_persp) ? camera_pos - wpos : camera_z;
|
vec3 camera_vec = (is_persp) ? camera_pos - wpos : camera_z;
|
||||||
wbinor = normalize(cross(camera_vec, wtan));
|
wbinor = normalize(cross(camera_vec, wtan));
|
||||||
|
|||||||
@@ -307,6 +307,7 @@ void WM_main_remap_editor_id_reference(struct ID *old_id, struct ID *new_id);
|
|||||||
|
|
||||||
/* reports */
|
/* reports */
|
||||||
void WM_report_banner_show(void);
|
void WM_report_banner_show(void);
|
||||||
|
void WM_report_banners_cancel(struct Main *bmain);
|
||||||
void WM_report(ReportType type, const char *message);
|
void WM_report(ReportType type, const char *message);
|
||||||
void WM_reportf(ReportType type, const char *format, ...) ATTR_PRINTF_FORMAT(2, 3);
|
void WM_reportf(ReportType type, const char *format, ...) ATTR_PRINTF_FORMAT(2, 3);
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
#include "RNA_access.h"
|
#include "RNA_access.h"
|
||||||
|
|
||||||
#include "UI_interface.h"
|
#include "UI_interface.h"
|
||||||
|
#include "UI_view2d.h"
|
||||||
|
|
||||||
#include "PIL_time.h"
|
#include "PIL_time.h"
|
||||||
|
|
||||||
@@ -83,6 +84,8 @@
|
|||||||
#include "wm_event_system.h"
|
#include "wm_event_system.h"
|
||||||
#include "wm_event_types.h"
|
#include "wm_event_types.h"
|
||||||
|
|
||||||
|
#include "RNA_enum_types.h"
|
||||||
|
|
||||||
#include "DEG_depsgraph.h"
|
#include "DEG_depsgraph.h"
|
||||||
#include "DEG_depsgraph_query.h"
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
@@ -101,6 +104,7 @@
|
|||||||
#define USE_GIZMO_MOUSE_PRIORITY_HACK
|
#define USE_GIZMO_MOUSE_PRIORITY_HACK
|
||||||
|
|
||||||
static void wm_notifier_clear(wmNotifier *note);
|
static void wm_notifier_clear(wmNotifier *note);
|
||||||
|
static void update_tablet_data(wmWindow *win, wmEvent *event);
|
||||||
|
|
||||||
static int wm_operator_call_internal(bContext *C,
|
static int wm_operator_call_internal(bContext *C,
|
||||||
wmOperatorType *ot,
|
wmOperatorType *ot,
|
||||||
@@ -110,8 +114,6 @@ static int wm_operator_call_internal(bContext *C,
|
|||||||
const bool poll_only,
|
const bool poll_only,
|
||||||
wmEvent *event);
|
wmEvent *event);
|
||||||
|
|
||||||
static bool wm_operator_check_locked_interface(bContext *C, wmOperatorType *ot);
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Event Management
|
/** \name Event Management
|
||||||
* \{ */
|
* \{ */
|
||||||
@@ -124,6 +126,14 @@ wmEvent *wm_event_add_ex(wmWindow *win,
|
|||||||
|
|
||||||
*event = *event_to_add;
|
*event = *event_to_add;
|
||||||
|
|
||||||
|
update_tablet_data(win, event);
|
||||||
|
|
||||||
|
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
|
||||||
|
/* We could have a preference to support relative tablet motion (we can't detect that). */
|
||||||
|
event->is_motion_absolute = ((event->tablet_data != NULL) &&
|
||||||
|
(event->tablet_data->Active != GHOST_kTabletModeNone));
|
||||||
|
}
|
||||||
|
|
||||||
if (event_to_add_after == NULL) {
|
if (event_to_add_after == NULL) {
|
||||||
BLI_addtail(&win->queue, event);
|
BLI_addtail(&win->queue, event);
|
||||||
}
|
}
|
||||||
@@ -167,6 +177,10 @@ void wm_event_free(wmEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event->tablet_data) {
|
||||||
|
MEM_freeN((void *)event->tablet_data);
|
||||||
|
}
|
||||||
|
|
||||||
MEM_freeN(event);
|
MEM_freeN(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +195,9 @@ void wm_event_free_all(wmWindow *win)
|
|||||||
|
|
||||||
void wm_event_init_from_window(wmWindow *win, wmEvent *event)
|
void wm_event_init_from_window(wmWindow *win, wmEvent *event)
|
||||||
{
|
{
|
||||||
|
/* make sure we don't copy any owned pointers */
|
||||||
|
BLI_assert(win->eventstate->tablet_data == NULL);
|
||||||
|
|
||||||
*event = *(win->eventstate);
|
*event = *(win->eventstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,6 +706,26 @@ void WM_report_banner_show(void)
|
|||||||
wm_reports->reporttimer->customdata = rti;
|
wm_reports->reporttimer->customdata = rti;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide all currently displayed banners and abort their timer.
|
||||||
|
*/
|
||||||
|
void WM_report_banners_cancel(Main *bmain)
|
||||||
|
{
|
||||||
|
wmWindowManager *wm = bmain->wm.first;
|
||||||
|
BKE_reports_clear(&wm->reports);
|
||||||
|
WM_event_remove_timer(wm, NULL, wm->reports.reporttimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WM_event_is_last_mousemove(const wmEvent *event)
|
||||||
|
{
|
||||||
|
while ((event = event->next)) {
|
||||||
|
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_INPUT_NDOF
|
#ifdef WITH_INPUT_NDOF
|
||||||
void WM_ndof_deadzone_set(float deadzone)
|
void WM_ndof_deadzone_set(float deadzone)
|
||||||
{
|
{
|
||||||
@@ -1202,6 +1239,105 @@ static void wm_region_mouse_co(bContext *C, wmEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1 /* may want to disable operator remembering previous state for testing */
|
||||||
|
|
||||||
|
static bool operator_last_properties_init_impl(wmOperator *op, IDProperty *last_properties)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
IDPropertyTemplate val = {0};
|
||||||
|
IDProperty *replaceprops = IDP_New(IDP_GROUP, &val, "wmOperatorProperties");
|
||||||
|
PropertyRNA *iterprop;
|
||||||
|
|
||||||
|
CLOG_INFO(WM_LOG_OPERATORS, 1, "loading previous properties for '%s'", op->type->idname);
|
||||||
|
|
||||||
|
iterprop = RNA_struct_iterator_property(op->type->srna);
|
||||||
|
|
||||||
|
RNA_PROP_BEGIN (op->ptr, itemptr, iterprop) {
|
||||||
|
PropertyRNA *prop = itemptr.data;
|
||||||
|
if ((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) {
|
||||||
|
if (!RNA_property_is_set(op->ptr, prop)) { /* don't override a setting already set */
|
||||||
|
const char *identifier = RNA_property_identifier(prop);
|
||||||
|
IDProperty *idp_src = IDP_GetPropertyFromGroup(last_properties, identifier);
|
||||||
|
if (idp_src) {
|
||||||
|
IDProperty *idp_dst = IDP_CopyProperty(idp_src);
|
||||||
|
|
||||||
|
/* note - in the future this may need to be done recursively,
|
||||||
|
* but for now RNA doesn't access nested operators */
|
||||||
|
idp_dst->flag |= IDP_FLAG_GHOST;
|
||||||
|
|
||||||
|
/* add to temporary group instead of immediate replace,
|
||||||
|
* because we are iterating over this group */
|
||||||
|
IDP_AddToGroup(replaceprops, idp_dst);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RNA_PROP_END;
|
||||||
|
|
||||||
|
IDP_MergeGroup(op->properties, replaceprops, true);
|
||||||
|
IDP_FreeProperty(replaceprops);
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WM_operator_last_properties_init(wmOperator *op)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
if (op->type->last_properties) {
|
||||||
|
changed |= operator_last_properties_init_impl(op, op->type->last_properties);
|
||||||
|
for (wmOperator *opm = op->macro.first; opm; opm = opm->next) {
|
||||||
|
IDProperty *idp_src = IDP_GetPropertyFromGroup(op->type->last_properties, opm->idname);
|
||||||
|
if (idp_src) {
|
||||||
|
changed |= operator_last_properties_init_impl(opm, idp_src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WM_operator_last_properties_store(wmOperator *op)
|
||||||
|
{
|
||||||
|
if (op->type->last_properties) {
|
||||||
|
IDP_FreeProperty(op->type->last_properties);
|
||||||
|
op->type->last_properties = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op->properties) {
|
||||||
|
CLOG_INFO(WM_LOG_OPERATORS, 1, "storing properties for '%s'", op->type->idname);
|
||||||
|
op->type->last_properties = IDP_CopyProperty(op->properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op->macro.first != NULL) {
|
||||||
|
for (wmOperator *opm = op->macro.first; opm; opm = opm->next) {
|
||||||
|
if (opm->properties) {
|
||||||
|
if (op->type->last_properties == NULL) {
|
||||||
|
op->type->last_properties = IDP_New(
|
||||||
|
IDP_GROUP, &(IDPropertyTemplate){0}, "wmOperatorProperties");
|
||||||
|
}
|
||||||
|
IDProperty *idp_macro = IDP_CopyProperty(opm->properties);
|
||||||
|
STRNCPY(idp_macro->name, opm->type->idname);
|
||||||
|
IDP_ReplaceInGroup(op->type->last_properties, idp_macro);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (op->type->last_properties != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
bool WM_operator_last_properties_init(wmOperator *UNUSED(op))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WM_operator_last_properties_store(wmOperator *UNUSED(op))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Also used for exec when 'event' is NULL.
|
* Also used for exec when 'event' is NULL.
|
||||||
*/
|
*/
|
||||||
@@ -1756,6 +1892,42 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* do userdef mappings */
|
||||||
|
int WM_userdef_event_map(int kmitype)
|
||||||
|
{
|
||||||
|
switch (kmitype) {
|
||||||
|
case WHEELOUTMOUSE:
|
||||||
|
return (U.uiflag & USER_WHEELZOOMDIR) ? WHEELUPMOUSE : WHEELDOWNMOUSE;
|
||||||
|
case WHEELINMOUSE:
|
||||||
|
return (U.uiflag & USER_WHEELZOOMDIR) ? WHEELDOWNMOUSE : WHEELUPMOUSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kmitype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use so we can check if 'wmEvent.type' is released in modal operators.
|
||||||
|
*
|
||||||
|
* An alternative would be to add a 'wmEvent.type_nokeymap'... or similar.
|
||||||
|
*/
|
||||||
|
int WM_userdef_event_type_from_keymap_type(int kmitype)
|
||||||
|
{
|
||||||
|
switch (kmitype) {
|
||||||
|
case EVT_TWEAK_L:
|
||||||
|
return LEFTMOUSE;
|
||||||
|
case EVT_TWEAK_M:
|
||||||
|
return MIDDLEMOUSE;
|
||||||
|
case EVT_TWEAK_R:
|
||||||
|
return RIGHTMOUSE;
|
||||||
|
case WHEELOUTMOUSE:
|
||||||
|
return (U.uiflag & USER_WHEELZOOMDIR) ? WHEELUPMOUSE : WHEELDOWNMOUSE;
|
||||||
|
case WHEELINMOUSE:
|
||||||
|
return (U.uiflag & USER_WHEELZOOMDIR) ? WHEELDOWNMOUSE : WHEELUPMOUSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kmitype;
|
||||||
|
}
|
||||||
|
|
||||||
static bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi)
|
static bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi)
|
||||||
{
|
{
|
||||||
if (kmi->flag & KMI_INACTIVE) {
|
if (kmi->flag & KMI_INACTIVE) {
|
||||||
@@ -1777,16 +1949,19 @@ static bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi)
|
|||||||
|
|
||||||
if (kmitype != KM_ANY) {
|
if (kmitype != KM_ANY) {
|
||||||
if (ELEM(kmitype, TABLET_STYLUS, TABLET_ERASER)) {
|
if (ELEM(kmitype, TABLET_STYLUS, TABLET_ERASER)) {
|
||||||
const wmTabletData *wmtab = &winevent->tablet;
|
const wmTabletData *wmtab = winevent->tablet_data;
|
||||||
|
|
||||||
if (winevent->type != LEFTMOUSE) {
|
if (wmtab == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (winevent->type != LEFTMOUSE) {
|
||||||
/* tablet events can occur on hover + keypress */
|
/* tablet events can occur on hover + keypress */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if ((kmitype == TABLET_STYLUS) && (wmtab->active != EVT_TABLET_STYLUS)) {
|
else if ((kmitype == TABLET_STYLUS) && (wmtab->Active != EVT_TABLET_STYLUS)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if ((kmitype == TABLET_ERASER) && (wmtab->active != EVT_TABLET_ERASER)) {
|
else if ((kmitype == TABLET_ERASER) && (wmtab->Active != EVT_TABLET_ERASER)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1866,10 +2041,10 @@ static wmKeyMapItem *wm_eventmatch_modal_keymap_items(const wmKeyMap *keymap,
|
|||||||
* This is done since we only want to use double click events to match key-map items,
|
* This is done since we only want to use double click events to match key-map items,
|
||||||
* allowing modal functions to check for press/release events without having to interpret them.
|
* allowing modal functions to check for press/release events without having to interpret them.
|
||||||
*/
|
*/
|
||||||
static void wm_event_modalkeymap_begin(const bContext *C,
|
static void wm_event_modalkeymap(const bContext *C,
|
||||||
wmOperator *op,
|
wmOperator *op,
|
||||||
wmEvent *event,
|
wmEvent *event,
|
||||||
bool *dbl_click_disabled)
|
bool *dbl_click_disabled)
|
||||||
{
|
{
|
||||||
BLI_assert(event->type != EVT_MODAL_MAP);
|
BLI_assert(event->type != EVT_MODAL_MAP);
|
||||||
|
|
||||||
@@ -1922,13 +2097,25 @@ static void wm_event_modalkeymap_begin(const bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore changes from #wm_event_modalkeymap_begin
|
* Check whether operator is allowed to run in case interface is locked,
|
||||||
*
|
* If interface is unlocked, will always return truth.
|
||||||
* \warning bad hacking event system...
|
|
||||||
* better restore event type for checking of #KM_CLICK for example.
|
|
||||||
* Modal maps could use different method (ton).
|
|
||||||
*/
|
*/
|
||||||
static void wm_event_modalkeymap_end(wmEvent *event, bool dbl_click_disabled)
|
static bool wm_operator_check_locked_interface(bContext *C, wmOperatorType *ot)
|
||||||
|
{
|
||||||
|
wmWindowManager *wm = CTX_wm_manager(C);
|
||||||
|
|
||||||
|
if (wm->is_interface_locked) {
|
||||||
|
if ((ot->flag & OPTYPE_LOCK_BYPASS) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bad hacking event system... better restore event type for checking of KM_CLICK for example */
|
||||||
|
/* XXX modal maps could use different method (ton) */
|
||||||
|
static void wm_event_modalmap_end(wmEvent *event, bool dbl_click_disabled)
|
||||||
{
|
{
|
||||||
if (event->type == EVT_MODAL_MAP) {
|
if (event->type == EVT_MODAL_MAP) {
|
||||||
event->type = event->prevtype;
|
event->type = event->prevtype;
|
||||||
@@ -1947,8 +2134,7 @@ static int wm_handler_operator_call(bContext *C,
|
|||||||
ListBase *handlers,
|
ListBase *handlers,
|
||||||
wmEventHandler *handler_base,
|
wmEventHandler *handler_base,
|
||||||
wmEvent *event,
|
wmEvent *event,
|
||||||
PointerRNA *properties,
|
PointerRNA *properties)
|
||||||
const char *kmi_idname)
|
|
||||||
{
|
{
|
||||||
int retval = OPERATOR_PASS_THROUGH;
|
int retval = OPERATOR_PASS_THROUGH;
|
||||||
|
|
||||||
@@ -1973,7 +2159,7 @@ static int wm_handler_operator_call(bContext *C,
|
|||||||
|
|
||||||
wm_handler_op_context(C, handler, event);
|
wm_handler_op_context(C, handler, event);
|
||||||
wm_region_mouse_co(C, event);
|
wm_region_mouse_co(C, event);
|
||||||
wm_event_modalkeymap_begin(C, op, event, &dbl_click_disabled);
|
wm_event_modalkeymap(C, op, event, &dbl_click_disabled);
|
||||||
|
|
||||||
if (ot->flag & OPTYPE_UNDO) {
|
if (ot->flag & OPTYPE_UNDO) {
|
||||||
wm->op_undo_depth++;
|
wm->op_undo_depth++;
|
||||||
@@ -1988,7 +2174,7 @@ static int wm_handler_operator_call(bContext *C,
|
|||||||
* the event, operator etc have all been freed. - campbell */
|
* the event, operator etc have all been freed. - campbell */
|
||||||
if (CTX_wm_manager(C) == wm) {
|
if (CTX_wm_manager(C) == wm) {
|
||||||
|
|
||||||
wm_event_modalkeymap_end(event, dbl_click_disabled);
|
wm_event_modalmap_end(event, dbl_click_disabled);
|
||||||
|
|
||||||
if (ot->flag & OPTYPE_UNDO) {
|
if (ot->flag & OPTYPE_UNDO) {
|
||||||
wm->op_undo_depth--;
|
wm->op_undo_depth--;
|
||||||
@@ -2050,7 +2236,7 @@ static int wm_handler_operator_call(bContext *C,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wmOperatorType *ot = WM_operatortype_find(kmi_idname, 0);
|
wmOperatorType *ot = WM_operatortype_find(event->keymap_idname, 0);
|
||||||
|
|
||||||
if (ot && wm_operator_check_locked_interface(C, ot)) {
|
if (ot && wm_operator_check_locked_interface(C, ot)) {
|
||||||
bool use_last_properties = true;
|
bool use_last_properties = true;
|
||||||
@@ -2388,8 +2574,10 @@ static int wm_handlers_do_keymap_with_keymap_handler(
|
|||||||
|
|
||||||
PRINT("%s: item matched '%s'\n", __func__, kmi->idname);
|
PRINT("%s: item matched '%s'\n", __func__, kmi->idname);
|
||||||
|
|
||||||
action |= wm_handler_operator_call(
|
/* weak, but allows interactive callback to not use rawkey */
|
||||||
C, handlers, &handler->head, event, kmi->ptr, kmi->idname);
|
event->keymap_idname = kmi->idname;
|
||||||
|
|
||||||
|
action |= wm_handler_operator_call(C, handlers, &handler->head, event, kmi->ptr);
|
||||||
|
|
||||||
if (action & WM_HANDLER_BREAK) {
|
if (action & WM_HANDLER_BREAK) {
|
||||||
/* not always_pass here, it denotes removed handler_base */
|
/* not always_pass here, it denotes removed handler_base */
|
||||||
@@ -2443,11 +2631,13 @@ static int wm_handlers_do_keymap_with_gizmo_handler(
|
|||||||
if (wm_eventmatch(event, kmi)) {
|
if (wm_eventmatch(event, kmi)) {
|
||||||
PRINT("%s: item matched '%s'\n", __func__, kmi->idname);
|
PRINT("%s: item matched '%s'\n", __func__, kmi->idname);
|
||||||
|
|
||||||
|
/* weak, but allows interactive callback to not use rawkey */
|
||||||
|
event->keymap_idname = kmi->idname;
|
||||||
|
|
||||||
CTX_wm_gizmo_group_set(C, gzgroup);
|
CTX_wm_gizmo_group_set(C, gzgroup);
|
||||||
|
|
||||||
/* handler->op is called later, we want keymap op to be triggered here */
|
/* handler->op is called later, we want keymap op to be triggered here */
|
||||||
action |= wm_handler_operator_call(
|
action |= wm_handler_operator_call(C, handlers, &handler->head, event, kmi->ptr);
|
||||||
C, handlers, &handler->head, event, kmi->ptr, kmi->idname);
|
|
||||||
|
|
||||||
CTX_wm_gizmo_group_set(C, NULL);
|
CTX_wm_gizmo_group_set(C, NULL);
|
||||||
|
|
||||||
@@ -2738,7 +2928,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
action |= wm_handler_operator_call(C, handlers, handler_base, event, NULL, NULL);
|
action |= wm_handler_operator_call(C, handlers, handler_base, event, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -3847,6 +4037,91 @@ void WM_event_add_mousemove(const bContext *C)
|
|||||||
window->addmousemove = 1;
|
window->addmousemove = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for modal callbacks, check configuration for how to interpret exit with tweaks */
|
||||||
|
bool WM_event_is_modal_tweak_exit(const wmEvent *event, int tweak_event)
|
||||||
|
{
|
||||||
|
/* if the release-confirm userpref setting is enabled,
|
||||||
|
* tweak events can be canceled when mouse is released
|
||||||
|
*/
|
||||||
|
if (U.flag & USER_RELEASECONFIRM) {
|
||||||
|
/* option on, so can exit with km-release */
|
||||||
|
if (event->val == KM_RELEASE) {
|
||||||
|
switch (tweak_event) {
|
||||||
|
case EVT_TWEAK_L:
|
||||||
|
case EVT_TWEAK_M:
|
||||||
|
case EVT_TWEAK_R:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* if the initial event wasn't a tweak event then
|
||||||
|
* ignore USER_RELEASECONFIRM setting: see [#26756] */
|
||||||
|
if (ELEM(tweak_event, EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* this is fine as long as not doing km-release, otherwise
|
||||||
|
* some items (i.e. markers) being tweaked may end up getting
|
||||||
|
* dropped all over
|
||||||
|
*/
|
||||||
|
if (event->val != KM_RELEASE) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WM_event_type_mask_test(const int event_type, const enum eEventType_Mask mask)
|
||||||
|
{
|
||||||
|
/* Keyboard. */
|
||||||
|
if (mask & EVT_TYPE_MASK_KEYBOARD) {
|
||||||
|
if (ISKEYBOARD(event_type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mask & EVT_TYPE_MASK_KEYBOARD_MODIFIER) {
|
||||||
|
if (ISKEYMODIFIER(event_type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mouse. */
|
||||||
|
if (mask & EVT_TYPE_MASK_MOUSE) {
|
||||||
|
if (ISMOUSE(event_type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mask & EVT_TYPE_MASK_MOUSE_WHEEL) {
|
||||||
|
if (ISMOUSE_WHEEL(event_type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mask & EVT_TYPE_MASK_MOUSE_GESTURE) {
|
||||||
|
if (ISMOUSE_GESTURE(event_type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tweak. */
|
||||||
|
if (mask & EVT_TYPE_MASK_TWEAK) {
|
||||||
|
if (ISTWEAK(event_type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Action Zone. */
|
||||||
|
if (mask & EVT_TYPE_MASK_ACTIONZONE) {
|
||||||
|
if (IS_EVENT_ACTIONZONE(event_type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@@ -4084,23 +4359,41 @@ static void wm_eventemulation(wmEvent *event, bool test_only)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wm_tablet_data_from_ghost(const GHOST_TabletData *tablet_data, wmTabletData *wmtab)
|
/* applies the global tablet pressure correction curve */
|
||||||
|
float wm_pressure_curve(float pressure)
|
||||||
{
|
{
|
||||||
if ((tablet_data != NULL) && tablet_data->Active != GHOST_kTabletModeNone) {
|
if (U.pressure_threshold_max != 0.0f) {
|
||||||
wmtab->active = (int)tablet_data->Active;
|
pressure /= U.pressure_threshold_max;
|
||||||
wmtab->pressure = wm_pressure_curve(tablet_data->Pressure);
|
}
|
||||||
wmtab->x_tilt = tablet_data->Xtilt;
|
|
||||||
wmtab->y_tilt = tablet_data->Ytilt;
|
CLAMP(pressure, 0.0f, 1.0f);
|
||||||
/* We could have a preference to support relative tablet motion (we can't detect that). */
|
|
||||||
wmtab->is_motion_absolute = true;
|
if (U.pressure_softness != 0.0f) {
|
||||||
// printf("%s: using tablet %.5f\n", __func__, wmtab->pressure);
|
pressure = powf(pressure, powf(4.0f, -U.pressure_softness));
|
||||||
|
}
|
||||||
|
|
||||||
|
return pressure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* adds customdata to event */
|
||||||
|
static void update_tablet_data(wmWindow *win, wmEvent *event)
|
||||||
|
{
|
||||||
|
const GHOST_TabletData *td = GHOST_GetTabletData(win->ghostwin);
|
||||||
|
|
||||||
|
/* if there's tablet data from an active tablet device then add it */
|
||||||
|
if ((td != NULL) && td->Active != GHOST_kTabletModeNone) {
|
||||||
|
struct wmTabletData *wmtab = MEM_mallocN(sizeof(wmTabletData), "customdata tablet");
|
||||||
|
|
||||||
|
wmtab->Active = (int)td->Active;
|
||||||
|
wmtab->Pressure = wm_pressure_curve(td->Pressure);
|
||||||
|
wmtab->Xtilt = td->Xtilt;
|
||||||
|
wmtab->Ytilt = td->Ytilt;
|
||||||
|
|
||||||
|
event->tablet_data = wmtab;
|
||||||
|
// printf("%s: using tablet %.5f\n", __func__, wmtab->Pressure);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wmtab->active = EVT_TABLET_NONE;
|
event->tablet_data = NULL;
|
||||||
wmtab->pressure = 1.0f;
|
|
||||||
wmtab->x_tilt = 0.0f;
|
|
||||||
wmtab->y_tilt = 0.0f;
|
|
||||||
wmtab->is_motion_absolute = false;
|
|
||||||
// printf("%s: not using tablet\n", __func__);
|
// printf("%s: not using tablet\n", __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4252,7 +4545,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
|||||||
|
|
||||||
copy_v2_v2_int(&event.x, &cd->x);
|
copy_v2_v2_int(&event.x, &cd->x);
|
||||||
wm_stereo3d_mouse_offset_apply(win, &event.x);
|
wm_stereo3d_mouse_offset_apply(win, &event.x);
|
||||||
wm_tablet_data_from_ghost(&cd->tablet, &event.tablet);
|
|
||||||
|
|
||||||
event.prevtype = event.type;
|
event.prevtype = event.type;
|
||||||
event.prevval = event.val;
|
event.prevval = event.val;
|
||||||
@@ -4260,7 +4552,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
|||||||
{
|
{
|
||||||
wmEvent *event_new = wm_event_add_mousemove(win, &event);
|
wmEvent *event_new = wm_event_add_mousemove(win, &event);
|
||||||
copy_v2_v2_int(&evt->x, &event_new->x);
|
copy_v2_v2_int(&evt->x, &event_new->x);
|
||||||
evt->tablet.is_motion_absolute = event_new->tablet.is_motion_absolute;
|
evt->is_motion_absolute = event_new->is_motion_absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* also add to other window if event is there, this makes overdraws disappear nicely */
|
/* also add to other window if event is there, this makes overdraws disappear nicely */
|
||||||
@@ -4278,7 +4570,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
|||||||
{
|
{
|
||||||
wmEvent *event_new = wm_event_add_mousemove(owin, &oevent);
|
wmEvent *event_new = wm_event_add_mousemove(owin, &oevent);
|
||||||
copy_v2_v2_int(&oevt->x, &event_new->x);
|
copy_v2_v2_int(&oevt->x, &event_new->x);
|
||||||
oevt->tablet.is_motion_absolute = event_new->tablet.is_motion_absolute;
|
oevt->is_motion_absolute = event_new->is_motion_absolute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4292,9 +4584,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
|||||||
pd->deltaX = -pd->deltaX;
|
pd->deltaX = -pd->deltaX;
|
||||||
pd->deltaY = -pd->deltaY;
|
pd->deltaY = -pd->deltaY;
|
||||||
break;
|
break;
|
||||||
case GHOST_kTrackpadEventSmartMagnify:
|
|
||||||
event.type = MOUSESMARTZOOM;
|
|
||||||
break;
|
|
||||||
case GHOST_kTrackpadEventRotate:
|
case GHOST_kTrackpadEventRotate:
|
||||||
event.type = MOUSEROTATE;
|
event.type = MOUSEROTATE;
|
||||||
break;
|
break;
|
||||||
@@ -4345,9 +4634,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
|||||||
event.type = MIDDLEMOUSE;
|
event.type = MIDDLEMOUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get tablet data. */
|
|
||||||
wm_tablet_data_from_ghost(&bd->tablet, &event.tablet);
|
|
||||||
|
|
||||||
wm_eventemulation(&event, false);
|
wm_eventemulation(&event, false);
|
||||||
|
|
||||||
/* copy previous state to prev event state (two old!) */
|
/* copy previous state to prev event state (two old!) */
|
||||||
@@ -4358,6 +4644,17 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
|||||||
evt->val = event.val;
|
evt->val = event.val;
|
||||||
evt->type = event.type;
|
evt->type = event.type;
|
||||||
|
|
||||||
|
if (win->active == 0) {
|
||||||
|
int cx, cy;
|
||||||
|
|
||||||
|
/* Entering window, update mouse pos.
|
||||||
|
* (ghost sends win-activate *after* the mouseclick in window!) */
|
||||||
|
wm_get_cursor_position(win, &cx, &cy);
|
||||||
|
|
||||||
|
event.x = evt->x = cx;
|
||||||
|
event.y = evt->y = cy;
|
||||||
|
}
|
||||||
|
|
||||||
/* double click test */
|
/* double click test */
|
||||||
if (wm_event_is_double_click(&event, evt)) {
|
if (wm_event_is_double_click(&event, evt)) {
|
||||||
CLOG_INFO(WM_LOG_HANDLERS, 1, "Send double click");
|
CLOG_INFO(WM_LOG_HANDLERS, 1, "Send double click");
|
||||||
@@ -4378,7 +4675,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
|||||||
oevent.y = event.y;
|
oevent.y = event.y;
|
||||||
oevent.type = event.type;
|
oevent.type = event.type;
|
||||||
oevent.val = event.val;
|
oevent.val = event.val;
|
||||||
oevent.tablet = event.tablet;
|
|
||||||
|
|
||||||
wm_event_add(owin, &oevent);
|
wm_event_add(owin, &oevent);
|
||||||
}
|
}
|
||||||
@@ -4645,29 +4941,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
|
||||||
/** \name WM Interface Locking
|
|
||||||
* \{ */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether operator is allowed to run in case interface is locked,
|
|
||||||
* If interface is unlocked, will always return truth.
|
|
||||||
*/
|
|
||||||
static bool wm_operator_check_locked_interface(bContext *C, wmOperatorType *ot)
|
|
||||||
{
|
|
||||||
wmWindowManager *wm = CTX_wm_manager(C);
|
|
||||||
|
|
||||||
if (wm->is_interface_locked) {
|
|
||||||
if ((ot->flag & OPTYPE_LOCK_BYPASS) == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WM_set_locked_interface(wmWindowManager *wm, bool lock)
|
void WM_set_locked_interface(wmWindowManager *wm, bool lock)
|
||||||
{
|
{
|
||||||
/* This will prevent events from being handled while interface is locked
|
/* This will prevent events from being handled while interface is locked
|
||||||
@@ -4689,12 +4962,96 @@ void WM_set_locked_interface(wmWindowManager *wm, bool lock)
|
|||||||
BKE_spacedata_draw_locks(lock);
|
BKE_spacedata_draw_locks(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
#ifdef WITH_INPUT_NDOF
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Event / Keymap Matching API
|
/** \name NDOF Utility Functions
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
|
void WM_event_ndof_pan_get(const wmNDOFMotionData *ndof, float r_pan[3], const bool use_zoom)
|
||||||
|
{
|
||||||
|
int z_flag = use_zoom ? NDOF_ZOOM_INVERT : NDOF_PANZ_INVERT_AXIS;
|
||||||
|
r_pan[0] = ndof->tvec[0] * ((U.ndof_flag & NDOF_PANX_INVERT_AXIS) ? -1.0f : 1.0f);
|
||||||
|
r_pan[1] = ndof->tvec[1] * ((U.ndof_flag & NDOF_PANY_INVERT_AXIS) ? -1.0f : 1.0f);
|
||||||
|
r_pan[2] = ndof->tvec[2] * ((U.ndof_flag & z_flag) ? -1.0f : 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WM_event_ndof_rotate_get(const wmNDOFMotionData *ndof, float r_rot[3])
|
||||||
|
{
|
||||||
|
r_rot[0] = ndof->rvec[0] * ((U.ndof_flag & NDOF_ROTX_INVERT_AXIS) ? -1.0f : 1.0f);
|
||||||
|
r_rot[1] = ndof->rvec[1] * ((U.ndof_flag & NDOF_ROTY_INVERT_AXIS) ? -1.0f : 1.0f);
|
||||||
|
r_rot[2] = ndof->rvec[2] * ((U.ndof_flag & NDOF_ROTZ_INVERT_AXIS) ? -1.0f : 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float WM_event_ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3])
|
||||||
|
{
|
||||||
|
float angle;
|
||||||
|
angle = normalize_v3_v3(axis, ndof->rvec);
|
||||||
|
|
||||||
|
axis[0] = axis[0] * ((U.ndof_flag & NDOF_ROTX_INVERT_AXIS) ? -1.0f : 1.0f);
|
||||||
|
axis[1] = axis[1] * ((U.ndof_flag & NDOF_ROTY_INVERT_AXIS) ? -1.0f : 1.0f);
|
||||||
|
axis[2] = axis[2] * ((U.ndof_flag & NDOF_ROTZ_INVERT_AXIS) ? -1.0f : 1.0f);
|
||||||
|
|
||||||
|
return ndof->dt * angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WM_event_ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4])
|
||||||
|
{
|
||||||
|
float axis[3];
|
||||||
|
float angle;
|
||||||
|
|
||||||
|
angle = WM_event_ndof_to_axis_angle(ndof, axis);
|
||||||
|
axis_angle_to_quat(q, axis, angle);
|
||||||
|
}
|
||||||
|
#endif /* WITH_INPUT_NDOF */
|
||||||
|
|
||||||
|
/* if this is a tablet event, return tablet pressure and set *pen_flip
|
||||||
|
* to 1 if the eraser tool is being used, 0 otherwise */
|
||||||
|
float WM_event_tablet_data(const wmEvent *event, int *pen_flip, float tilt[2])
|
||||||
|
{
|
||||||
|
int erasor = 0;
|
||||||
|
float pressure = 1;
|
||||||
|
|
||||||
|
if (tilt) {
|
||||||
|
zero_v2(tilt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event->tablet_data) {
|
||||||
|
const wmTabletData *wmtab = event->tablet_data;
|
||||||
|
|
||||||
|
erasor = (wmtab->Active == EVT_TABLET_ERASER);
|
||||||
|
if (wmtab->Active != EVT_TABLET_NONE) {
|
||||||
|
pressure = wmtab->Pressure;
|
||||||
|
if (tilt) {
|
||||||
|
tilt[0] = wmtab->Xtilt;
|
||||||
|
tilt[1] = wmtab->Ytilt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pen_flip) {
|
||||||
|
(*pen_flip) = erasor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pressure;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WM_event_is_tablet(const struct wmEvent *event)
|
||||||
|
{
|
||||||
|
return (event->tablet_data) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_INPUT_IME
|
||||||
|
/* most os using ctrl/oskey + space to switch ime, avoid added space */
|
||||||
|
bool WM_event_is_ime_switch(const struct wmEvent *event)
|
||||||
|
{
|
||||||
|
return event->val == KM_PRESS && event->type == SPACEKEY &&
|
||||||
|
(event->ctrl || event->oskey || event->shift || event->alt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
wmKeyMap *WM_event_get_keymap_from_handler(wmWindowManager *wm, wmEventHandler_Keymap *handler)
|
wmKeyMap *WM_event_get_keymap_from_handler(wmWindowManager *wm, wmEventHandler_Keymap *handler)
|
||||||
{
|
{
|
||||||
wmKeyMap *keymap;
|
wmKeyMap *keymap;
|
||||||
@@ -4722,10 +5079,10 @@ wmKeyMapItem *WM_event_match_keymap_item(bContext *C, wmKeyMap *keymap, const wm
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wmKeyMapItem *WM_event_match_keymap_item_from_handlers(bContext *C,
|
static wmKeyMapItem *wm_kmi_from_event(bContext *C,
|
||||||
wmWindowManager *wm,
|
wmWindowManager *wm,
|
||||||
ListBase *handlers,
|
ListBase *handlers,
|
||||||
const wmEvent *event)
|
const wmEvent *event)
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
|
LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
|
||||||
/* during this loop, ui handlers for nested menus can tag multiple handlers free */
|
/* during this loop, ui handlers for nested menus can tag multiple handlers free */
|
||||||
@@ -4748,8 +5105,6 @@ wmKeyMapItem *WM_event_match_keymap_item_from_handlers(bContext *C,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Cursor Keymap Status
|
/** \name Cursor Keymap Status
|
||||||
*
|
*
|
||||||
@@ -4962,7 +5317,7 @@ void WM_window_cursor_keymap_status_refresh(bContext *C, wmWindow *win)
|
|||||||
wm_eventemulation(&test_event, true);
|
wm_eventemulation(&test_event, true);
|
||||||
wmKeyMapItem *kmi = NULL;
|
wmKeyMapItem *kmi = NULL;
|
||||||
for (int handler_index = 0; handler_index < ARRAY_SIZE(handlers); handler_index++) {
|
for (int handler_index = 0; handler_index < ARRAY_SIZE(handlers); handler_index++) {
|
||||||
kmi = WM_event_match_keymap_item_from_handlers(C, wm, handlers[handler_index], &test_event);
|
kmi = wm_kmi_from_event(C, wm, handlers[handler_index], &test_event);
|
||||||
if (kmi) {
|
if (kmi) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5058,3 +5413,43 @@ bool WM_window_modal_keymap_status_draw(bContext *UNUSED(C), wmWindow *win, uiLa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Event Click/Drag Checks
|
||||||
|
*
|
||||||
|
* Values under this limit are detected as clicks.
|
||||||
|
*
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
int WM_event_drag_threshold(const struct wmEvent *event)
|
||||||
|
{
|
||||||
|
int drag_threshold;
|
||||||
|
if (WM_event_is_tablet(event)) {
|
||||||
|
drag_threshold = U.drag_threshold_tablet;
|
||||||
|
}
|
||||||
|
else if (ISMOUSE(event->prevtype)) {
|
||||||
|
drag_threshold = U.drag_threshold_mouse;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Typically keyboard, could be NDOF button or other less common types. */
|
||||||
|
drag_threshold = U.drag_threshold;
|
||||||
|
}
|
||||||
|
return drag_threshold * U.dpi_fac;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WM_event_drag_test_with_delta(const wmEvent *event, const int drag_delta[2])
|
||||||
|
{
|
||||||
|
const int drag_threshold = WM_event_drag_threshold(event);
|
||||||
|
return abs(drag_delta[0]) > drag_threshold || abs(drag_delta[1]) > drag_threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WM_event_drag_test(const wmEvent *event, const int prev_xy[2])
|
||||||
|
{
|
||||||
|
const int drag_delta[2] = {
|
||||||
|
prev_xy[0] - event->x,
|
||||||
|
prev_xy[1] - event->y,
|
||||||
|
};
|
||||||
|
return WM_event_drag_test_with_delta(event, drag_delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|||||||
Reference in New Issue
Block a user