Compare commits
26 Commits
temp-virtu
...
asset-brow
Author | SHA1 | Date | |
---|---|---|---|
6fd45a110c | |||
b1a319f4e0 | |||
793f65f426 | |||
7c8ad97115 | |||
1d44fc58a0 | |||
76a212f947 | |||
eedde9db74 | |||
e20266b949 | |||
2ef120ace0 | |||
4ac48b1390 | |||
99cc9df257 | |||
![]() |
513328602d | ||
279f271a0a | |||
f00d24e2c1 | |||
963826d8a1 | |||
3fdd579e7c | |||
bc4c9fea77 | |||
ac96c8a898 | |||
78008642ae | |||
5df6caa7f3 | |||
2a00e16682 | |||
948d1b0284 | |||
8a8208bd95 | |||
fcc42b3d46 | |||
8cc294a315 | |||
8ddf9f06ab |
@@ -20,6 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_asset_types.h"
|
||||
@@ -29,11 +30,23 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct AssetLibraryReference;
|
||||
struct AssetMetaData;
|
||||
struct BlendDataReader;
|
||||
struct BlendWriter;
|
||||
struct ID;
|
||||
struct IDProperty;
|
||||
struct PreviewImage;
|
||||
|
||||
typedef void (*PreSaveFn)(void *asset_ptr, struct AssetMetaData *asset_data);
|
||||
|
||||
typedef struct AssetTypeInfo {
|
||||
/**
|
||||
* For local assets (assets in the current .blend file), a callback to execute before the file is
|
||||
* saved.
|
||||
*/
|
||||
PreSaveFn pre_save_fn;
|
||||
} AssetTypeInfo;
|
||||
|
||||
struct AssetMetaData *BKE_asset_metadata_create(void);
|
||||
void BKE_asset_metadata_free(struct AssetMetaData **asset_data);
|
||||
|
||||
@@ -56,6 +69,10 @@ void BKE_asset_metadata_catalog_id_set(struct AssetMetaData *asset_data,
|
||||
|
||||
void BKE_asset_library_reference_init_default(struct AssetLibraryReference *library_ref);
|
||||
|
||||
void BKE_asset_metadata_idprop_ensure(struct AssetMetaData *asset_data, struct IDProperty *prop);
|
||||
struct IDProperty *BKE_asset_metadata_idprop_find(const struct AssetMetaData *asset_data,
|
||||
const char *name) ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
struct PreviewImage *BKE_asset_metadata_preview_get_from_id(const struct AssetMetaData *asset_data,
|
||||
const struct ID *owner_id);
|
||||
|
||||
|
@@ -228,6 +228,11 @@ typedef struct IDTypeInfo {
|
||||
* \note Currently needed for some update operation on point caches.
|
||||
*/
|
||||
IDTypeLibOverrideApplyPost lib_override_apply_post;
|
||||
|
||||
/**
|
||||
* Callbacks for assets, based on the type of asset.
|
||||
*/
|
||||
struct AssetTypeInfo *asset_type_info;
|
||||
} IDTypeInfo;
|
||||
|
||||
/* ********** Declaration of each IDTypeInfo. ********** */
|
||||
|
@@ -244,9 +244,9 @@ void BKE_main_library_weak_reference_remove_item(struct GHash *library_weak_refe
|
||||
|
||||
#define FOREACH_MAIN_LISTBASE_ID_BEGIN(_lb, _id) \
|
||||
{ \
|
||||
ID *_id_next = (_lb)->first; \
|
||||
ID *_id_next = (ID *)(_lb)->first; \
|
||||
for ((_id) = _id_next; (_id) != NULL; (_id) = _id_next) { \
|
||||
_id_next = (_id)->next;
|
||||
_id_next = (ID *)(_id)->next;
|
||||
|
||||
#define FOREACH_MAIN_LISTBASE_ID_END \
|
||||
} \
|
||||
|
@@ -159,6 +159,7 @@ struct Object *BKE_object_duplicate(struct Main *bmain,
|
||||
|
||||
void BKE_object_obdata_size_init(struct Object *ob, const float size);
|
||||
|
||||
void BKE_object_scale_to_vec3(const struct Object *ob, float r_scale[3]);
|
||||
void BKE_object_scale_to_mat3(struct Object *ob, float r_mat[3][3]);
|
||||
void BKE_object_rot_to_mat3(const struct Object *ob, float r_mat[3][3], bool use_drot);
|
||||
void BKE_object_mat3_to_rot(struct Object *ob, float r_mat[3][3], bool use_compat);
|
||||
|
@@ -140,6 +140,25 @@ void BKE_asset_metadata_catalog_id_set(struct AssetMetaData *asset_data,
|
||||
trimmed_id.copy(asset_data->catalog_simple_name, max_simple_name_length);
|
||||
}
|
||||
|
||||
void BKE_asset_metadata_idprop_ensure(AssetMetaData *asset_data, IDProperty *prop)
|
||||
{
|
||||
if (!asset_data->properties) {
|
||||
IDPropertyTemplate val = {0};
|
||||
asset_data->properties = IDP_New(IDP_GROUP, &val, "AssetMetaData.properties");
|
||||
}
|
||||
/* Important: The property may already exist. For now just allow always allow a newly allocated
|
||||
* property, and replace the existing one as a way of updating. */
|
||||
IDP_ReplaceInGroup(asset_data->properties, prop);
|
||||
}
|
||||
|
||||
IDProperty *BKE_asset_metadata_idprop_find(const AssetMetaData *asset_data, const char *name)
|
||||
{
|
||||
if (!asset_data->properties) {
|
||||
return nullptr;
|
||||
}
|
||||
return IDP_GetPropertyFromGroup(asset_data->properties, name);
|
||||
}
|
||||
|
||||
/* Queries -------------------------------------------- */
|
||||
|
||||
PreviewImage *BKE_asset_metadata_preview_get_from_id(const AssetMetaData *UNUSED(asset_data),
|
||||
@@ -169,6 +188,7 @@ void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
|
||||
void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
|
||||
{
|
||||
/* asset_data itself has been read already. */
|
||||
asset_data->local_type_info = nullptr;
|
||||
|
||||
if (asset_data->properties) {
|
||||
BLO_read_data_address(reader, &asset_data->properties);
|
||||
|
@@ -82,6 +82,7 @@
|
||||
#include "BKE_anim_visualization.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_asset.h"
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_constraint.h"
|
||||
@@ -1145,6 +1146,57 @@ static void object_lib_override_apply_post(ID *id_dst, ID *UNUSED(id_src))
|
||||
BLI_freelistN(&pidlist);
|
||||
}
|
||||
|
||||
static IDProperty *object_asset_boundbox_hint_property(Object *ob)
|
||||
{
|
||||
BoundBox *boundbox = BKE_object_boundbox_get(ob);
|
||||
if (!boundbox) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IDPropertyTemplate idprop = {0};
|
||||
idprop.array.len = sizeof(boundbox->vec) / sizeof(**boundbox->vec);
|
||||
idprop.array.type = IDP_FLOAT;
|
||||
|
||||
IDProperty *property = IDP_New(IDP_ARRAY, &idprop, "boundbox_hint");
|
||||
memcpy(IDP_Array(property), boundbox->vec, sizeof(boundbox->vec));
|
||||
|
||||
return property;
|
||||
}
|
||||
|
||||
static IDProperty *object_asset_matrix_basis_property(Object *ob)
|
||||
{
|
||||
float mat[4][4];
|
||||
IDPropertyTemplate idprop = {0};
|
||||
idprop.array.len = sizeof(mat) / sizeof(**mat);
|
||||
idprop.array.type = IDP_FLOAT;
|
||||
|
||||
IDProperty *property = IDP_New(IDP_ARRAY, &idprop, "matrix_basis");
|
||||
BKE_object_to_mat4(ob, (float(*)[])IDP_Array(property));
|
||||
|
||||
return property;
|
||||
}
|
||||
|
||||
static void object_asset_pre_save(void *asset_ptr, struct AssetMetaData *asset_data)
|
||||
{
|
||||
Object *ob = asset_ptr;
|
||||
BLI_assert(GS(ob->id.name) == ID_OB);
|
||||
|
||||
/* Update bounding-box hint for the asset. */
|
||||
IDProperty *boundbox_prop = object_asset_boundbox_hint_property(ob);
|
||||
if (boundbox_prop) {
|
||||
BKE_asset_metadata_idprop_ensure(asset_data, boundbox_prop);
|
||||
}
|
||||
/* Base matrix (object matrix without parent or constraint transforms). */
|
||||
IDProperty *base_matrix_prop = object_asset_matrix_basis_property(ob);
|
||||
if (base_matrix_prop) {
|
||||
BKE_asset_metadata_idprop_ensure(asset_data, base_matrix_prop);
|
||||
}
|
||||
}
|
||||
|
||||
AssetTypeInfo AssetType_OB = {
|
||||
.pre_save_fn = object_asset_pre_save,
|
||||
};
|
||||
|
||||
IDTypeInfo IDType_ID_OB = {
|
||||
.id_code = ID_OB,
|
||||
.id_filter = FILTER_ID_OB,
|
||||
@@ -1171,6 +1223,8 @@ IDTypeInfo IDType_ID_OB = {
|
||||
.blend_read_undo_preserve = NULL,
|
||||
|
||||
.lib_override_apply_post = object_lib_override_apply_post,
|
||||
|
||||
.asset_type_info = &AssetType_OB,
|
||||
};
|
||||
|
||||
void BKE_object_workob_clear(Object *workob)
|
||||
@@ -3033,10 +3087,15 @@ void BKE_object_obdata_size_init(struct Object *ob, const float size)
|
||||
/** \name Object Matrix Get/Set API
|
||||
* \{ */
|
||||
|
||||
void BKE_object_scale_to_vec3(const Object *ob, float r_scale[3])
|
||||
{
|
||||
mul_v3_v3v3(r_scale, ob->scale, ob->dscale);
|
||||
}
|
||||
|
||||
void BKE_object_scale_to_mat3(Object *ob, float mat[3][3])
|
||||
{
|
||||
float vec[3];
|
||||
mul_v3_v3v3(vec, ob->scale, ob->dscale);
|
||||
BKE_object_scale_to_vec3(ob, vec);
|
||||
size_to_mat3(mat, vec);
|
||||
}
|
||||
|
||||
|
@@ -2211,6 +2211,9 @@ static void direct_link_id_common(
|
||||
if (id->asset_data) {
|
||||
BLO_read_data_address(reader, &id->asset_data);
|
||||
BKE_asset_metadata_read(reader, id->asset_data);
|
||||
/* Restore runtime asset type info. */
|
||||
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
|
||||
id->asset_data->local_type_info = id_type->asset_type_info;
|
||||
}
|
||||
|
||||
/* Link direct data of ID properties. */
|
||||
|
@@ -26,6 +26,7 @@ extern "C" {
|
||||
|
||||
struct ID;
|
||||
struct bContext;
|
||||
struct Main;
|
||||
|
||||
/**
|
||||
* Mark the datablock as asset.
|
||||
@@ -45,6 +46,8 @@ bool ED_asset_mark_id(const struct bContext *C, struct ID *id);
|
||||
* \return whether the asset metadata was actually removed; false when the ID was not an asset. */
|
||||
bool ED_asset_clear_id(struct ID *id);
|
||||
|
||||
void ED_assets_pre_save(struct Main *bmain);
|
||||
|
||||
bool ED_asset_can_mark_single_from_context(const struct bContext *C);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -25,7 +25,9 @@
|
||||
|
||||
#include "BKE_asset.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "BLO_readfile.h"
|
||||
|
||||
@@ -51,7 +53,9 @@ bool ED_asset_mark_id(const bContext *C, ID *id)
|
||||
|
||||
id_fake_user_set(id);
|
||||
|
||||
const IDTypeInfo *id_type_info = BKE_idtype_get_info_from_id(id);
|
||||
id->asset_data = BKE_asset_metadata_create();
|
||||
id->asset_data->local_type_info = id_type_info->asset_type_info;
|
||||
|
||||
UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
|
||||
|
||||
@@ -75,6 +79,21 @@ bool ED_asset_clear_id(ID *id)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ED_assets_pre_save(struct Main *bmain)
|
||||
{
|
||||
ID *id;
|
||||
FOREACH_MAIN_ID_BEGIN (bmain, id) {
|
||||
if (!id->asset_data || !id->asset_data->local_type_info) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (id->asset_data->local_type_info->pre_save_fn) {
|
||||
id->asset_data->local_type_info->pre_save_fn(id, id->asset_data);
|
||||
}
|
||||
}
|
||||
FOREACH_MAIN_ID_END;
|
||||
}
|
||||
|
||||
bool ED_asset_can_mark_single_from_context(const bContext *C)
|
||||
{
|
||||
/* Context needs a "id" pointer to be set for #ASSET_OT_mark()/#ASSET_OT_clear() to use. */
|
||||
|
@@ -16,9 +16,6 @@
|
||||
|
||||
/** \file
|
||||
* \ingroup editors
|
||||
*
|
||||
* The public API for assets is defined in dedicated headers. This is a utility file that just
|
||||
* includes all of these.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -40,6 +40,7 @@ void ED_gizmotypes_preselect_3d(void);
|
||||
void ED_gizmotypes_primitive_3d(void);
|
||||
void ED_gizmotypes_blank_3d(void);
|
||||
void ED_gizmotypes_snap_3d(void);
|
||||
void ED_gizmotypes_placement_3d(void);
|
||||
|
||||
struct ARegion;
|
||||
struct Depsgraph;
|
||||
|
@@ -42,6 +42,12 @@ bool ED_gizmo_poll_or_unlink_delayed_from_tool_ex(const struct bContext *C,
|
||||
bool ED_gizmo_poll_or_unlink_delayed_from_tool(const struct bContext *C,
|
||||
struct wmGizmoGroupType *gzgt);
|
||||
|
||||
bool ED_gizmo_poll_from_tool_ex(const struct bContext *C, const char *gzgt_idname);
|
||||
bool ED_gizmo_poll_from_tool(const struct bContext *C, const struct wmGizmoGroupType *gzgt);
|
||||
|
||||
bool ED_gizmo_poll_from_dropbox_ex(const struct bContext *C, const char *gzgt_idname);
|
||||
bool ED_gizmo_poll_from_dropbox(const struct bContext *C, const struct wmGizmoGroupType *gzgt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -776,6 +776,30 @@ void ED_view3d_buttons_region_layout_ex(const struct bContext *C,
|
||||
bool ED_view3d_local_collections_set(struct Main *bmain, struct View3D *v3d);
|
||||
void ED_view3d_local_collections_reset(struct bContext *C, const bool reset_all);
|
||||
|
||||
/* view3d_placement.c */
|
||||
|
||||
enum ePlaceDirection {
|
||||
/** Use the negative direction of the plane axis as up-axis for the
|
||||
* boundbox snapping (snap with front, left or bottom side). */
|
||||
PLACE_DIRECTION_NEG,
|
||||
/** Use the positive direction of the plane axis as up-axis for the
|
||||
* boundbox snapping (snap with back, right or top side). */
|
||||
PLACE_DIRECTION_POS,
|
||||
};
|
||||
|
||||
void ED_view3d_placement_plane_calc(struct bContext *C,
|
||||
const int mval[2],
|
||||
const int plane_axis,
|
||||
float r_co_src[3],
|
||||
float r_mat_orient[3][3]);
|
||||
void ED_view3d_placement_plane_boundbox_calc(struct bContext *C,
|
||||
const int mval[2],
|
||||
const struct BoundBox *boundbox,
|
||||
const enum ePlaceDirection direction,
|
||||
const float scale[3],
|
||||
float r_co_src[3],
|
||||
float r_mat_orient[3][3]);
|
||||
|
||||
#ifdef WITH_XR_OPENXR
|
||||
void ED_view3d_xr_mirror_update(const struct ScrArea *area,
|
||||
const struct View3D *v3d,
|
||||
|
@@ -37,6 +37,7 @@ extern "C" {
|
||||
struct ARegion;
|
||||
struct AssetFilterSettings;
|
||||
struct AssetHandle;
|
||||
struct AssetMetaData;
|
||||
struct AutoComplete;
|
||||
struct EnumPropertyItem;
|
||||
struct FileDirEntry;
|
||||
@@ -780,6 +781,7 @@ void UI_but_drag_set_id(uiBut *but, struct ID *id);
|
||||
void UI_but_drag_set_asset(uiBut *but,
|
||||
const struct AssetHandle *asset,
|
||||
const char *path,
|
||||
struct AssetMetaData *metadata,
|
||||
int import_type, /* eFileAssetImportType */
|
||||
int icon,
|
||||
struct ImBuf *imb,
|
||||
|
@@ -6279,12 +6279,13 @@ void UI_but_drag_set_id(uiBut *but, ID *id)
|
||||
void UI_but_drag_set_asset(uiBut *but,
|
||||
const AssetHandle *asset,
|
||||
const char *path,
|
||||
struct AssetMetaData *metadata,
|
||||
int import_type,
|
||||
int icon,
|
||||
struct ImBuf *imb,
|
||||
float scale)
|
||||
{
|
||||
wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, path, import_type);
|
||||
wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, metadata, path, import_type);
|
||||
|
||||
/* FIXME: This is temporary evil solution to get scene/viewlayer/etc in the copy callback of the
|
||||
* #wmDropBox.
|
||||
|
@@ -70,6 +70,7 @@ static void asset_view_item_but_drag_set(uiBut *but,
|
||||
UI_but_drag_set_asset(but,
|
||||
asset_handle,
|
||||
BLI_strdup(blend_path),
|
||||
ED_asset_handle_get_metadata(asset_handle),
|
||||
FILE_ASSET_IMPORT_APPEND,
|
||||
ED_asset_handle_get_preview_icon_id(asset_handle),
|
||||
imbuf,
|
||||
|
@@ -3530,12 +3530,6 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
|
||||
|
||||
basen->object->visibility_flag &= ~OB_HIDE_VIEWPORT;
|
||||
|
||||
int mval[2];
|
||||
if (object_add_drop_xy_get(C, op, &mval)) {
|
||||
ED_object_location_from_view(C, basen->object->loc);
|
||||
ED_view3d_cursor3d_position(C, mval, false, basen->object->loc);
|
||||
}
|
||||
|
||||
/* object_add_duplicate_internal() doesn't deselect other objects, unlike object_add_common() or
|
||||
* BKE_view_layer_base_deselect_all(). */
|
||||
ED_object_base_deselect_all(view_layer, NULL, SEL_DESELECT);
|
||||
@@ -3553,13 +3547,31 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
|
||||
ED_outliner_select_sync_from_object_tag(C);
|
||||
|
||||
/* For the placement based on the bounding box to work, the object/object-data has to be
|
||||
* evaulated first. */
|
||||
int mval[2];
|
||||
if (object_add_drop_xy_get(C, op, &mval)) {
|
||||
Object *ob_eval = DEG_get_evaluated_object(CTX_data_ensure_evaluated_depsgraph(C),
|
||||
basen->object);
|
||||
BoundBox *boundbox = BKE_object_boundbox_get(ob_eval);
|
||||
|
||||
float rotmat[3][3];
|
||||
float scale[3];
|
||||
BKE_object_scale_to_vec3(basen->object, scale);
|
||||
ED_view3d_placement_plane_boundbox_calc(
|
||||
C, mval, boundbox, PLACE_DIRECTION_NEG, scale, basen->object->loc, rotmat);
|
||||
|
||||
BKE_object_mat3_to_rot(basen->object, rotmat, true);
|
||||
DEG_id_tag_update(&basen->object->id, ID_RECALC_TRANSFORM);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_add_named(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Named Object";
|
||||
ot->name = "Add Object";
|
||||
ot->description = "Add named object";
|
||||
ot->idname = "OBJECT_OT_add_named";
|
||||
|
||||
|
@@ -914,6 +914,14 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
|
||||
if (WM_gizmo_highlight_set(gzmap, NULL)) {
|
||||
ED_region_tag_redraw_no_rebuild(region_prev);
|
||||
}
|
||||
|
||||
/* TODO deduplicate (wm_handlers_do_gizmo_handler().) */
|
||||
const ListBase *groups = WM_gizmomap_group_list(gzmap);
|
||||
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, groups) {
|
||||
if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_ATTACHED_TO_CURSOR) {
|
||||
ED_region_tag_redraw_editor_overlays(region_prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -142,6 +142,7 @@ void ED_spacetypes_init(void)
|
||||
ED_gizmotypes_cage_2d();
|
||||
ED_gizmotypes_cage_3d();
|
||||
ED_gizmotypes_snap_3d();
|
||||
ED_gizmotypes_placement_3d();
|
||||
|
||||
/* Register types for operators and gizmos. */
|
||||
const ListBase *spacetypes = BKE_spacetypes_list();
|
||||
|
@@ -190,6 +190,7 @@ static void file_draw_icon(const SpaceFile *sfile,
|
||||
UI_but_drag_set_asset(but,
|
||||
&(AssetHandle){.file_data = file},
|
||||
BLI_strdup(blend_path),
|
||||
file->asset_data,
|
||||
asset_params->import_type,
|
||||
icon,
|
||||
preview_image,
|
||||
@@ -504,6 +505,7 @@ static void file_draw_preview(const SpaceFile *sfile,
|
||||
UI_but_drag_set_asset(but,
|
||||
&(AssetHandle){.file_data = file},
|
||||
BLI_strdup(blend_path),
|
||||
file->asset_data,
|
||||
asset_params->import_type,
|
||||
icon,
|
||||
imb,
|
||||
|
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_asset.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_global.h"
|
||||
@@ -516,7 +517,12 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C,
|
||||
|
||||
static bool view3d_ob_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||
{
|
||||
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_OB);
|
||||
if (view3d_drop_id_in_main_region_poll(C, drag, event, ID_OB)) {
|
||||
drag->no_preview = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool view3d_collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||
@@ -633,6 +639,45 @@ static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
RNA_boolean_set(drop->ptr, "duplicate", false);
|
||||
}
|
||||
|
||||
static void view3d_ob_drag_gizmo_copy_local(wmDropBox *drop, Object *ob)
|
||||
{
|
||||
BoundBox *boundbox = BKE_object_boundbox_get(ob);
|
||||
if (boundbox) {
|
||||
RNA_float_set_array(drop->gizmo_group_ptr, "bound_box", (float *)boundbox->vec);
|
||||
}
|
||||
float matrix_basis[4][4];
|
||||
BKE_object_to_mat4(ob, matrix_basis);
|
||||
RNA_float_set_array(drop->gizmo_group_ptr, "matrix_basis", (float *)matrix_basis);
|
||||
}
|
||||
|
||||
static void view3d_ob_drag_gizmo_copy_external(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
const struct AssetMetaData *meta_data = WM_drag_get_asset_meta_data(drag, ID_OB);
|
||||
|
||||
const IDProperty *boundbox_prop = BKE_asset_metadata_idprop_find(meta_data, "boundbox_hint");
|
||||
if (boundbox_prop) {
|
||||
BLI_assert(boundbox_prop->len == sizeof(((BoundBox *)NULL)->vec) / sizeof(float));
|
||||
RNA_float_set_array(drop->gizmo_group_ptr, "bound_box", IDP_Array(boundbox_prop));
|
||||
}
|
||||
|
||||
const IDProperty *matrix_basis_prop = BKE_asset_metadata_idprop_find(meta_data, "matrix_basis");
|
||||
if (matrix_basis_prop) {
|
||||
BLI_assert(matrix_basis_prop->len == sizeof(((Object *)NULL)->obmat) / sizeof(float));
|
||||
RNA_float_set_array(drop->gizmo_group_ptr, "matrix_basis", IDP_Array(matrix_basis_prop));
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_ob_drag_gizmo_copy(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = WM_drag_get_local_ID(drag, ID_OB);
|
||||
if (id) {
|
||||
view3d_ob_drag_gizmo_copy_local(drop, (Object *)id);
|
||||
}
|
||||
else {
|
||||
view3d_ob_drag_gizmo_copy_external(drag, drop);
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_GR);
|
||||
@@ -694,13 +739,15 @@ static void view3d_lightcache_update(bContext *C)
|
||||
static void view3d_dropboxes(void)
|
||||
{
|
||||
ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
|
||||
wmDropBox *dropbox;
|
||||
|
||||
WM_dropbox_add(lb,
|
||||
"OBJECT_OT_add_named",
|
||||
view3d_ob_drop_poll,
|
||||
view3d_ob_drop_copy,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
NULL);
|
||||
dropbox = WM_dropbox_add(lb,
|
||||
"OBJECT_OT_add_named",
|
||||
view3d_ob_drop_poll,
|
||||
view3d_ob_drop_copy,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
NULL);
|
||||
WM_dropbox_gizmogroup_set(dropbox, "VIEW3D_GGT_placement", view3d_ob_drag_gizmo_copy);
|
||||
WM_dropbox_add(lb,
|
||||
"OBJECT_OT_drop_named_material",
|
||||
view3d_mat_drop_poll,
|
||||
|
@@ -30,12 +30,14 @@
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_vfont_types.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
@@ -64,7 +66,6 @@
|
||||
|
||||
static const char *view3d_gzgt_placement_id = "VIEW3D_GGT_placement";
|
||||
|
||||
static void preview_plane_cursor_setup(wmGizmoGroup *gzgroup);
|
||||
static void preview_plane_cursor_visible_set(wmGizmoGroup *gzgroup, bool do_draw);
|
||||
|
||||
/**
|
||||
@@ -377,6 +378,25 @@ static wmGizmoGroup *idp_gizmogroup_from_region(ARegion *region)
|
||||
return gzmap ? WM_gizmomap_group_find(gzmap, view3d_gzgt_placement_id) : NULL;
|
||||
}
|
||||
|
||||
static wmGizmo *idp_snap_gizmo_from_region(ARegion *region)
|
||||
{
|
||||
/* Assign snap gizmo which is may be used as part of the tool. */
|
||||
wmGizmoGroup *gzgroup = idp_gizmogroup_from_region(region);
|
||||
if ((gzgroup == NULL) || (gzgroup->gizmos.first == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gzgroup->gizmos.first;
|
||||
}
|
||||
|
||||
static void idp_paintcursor_from_gizmo_visible_set(wmGizmo *gz, bool visible)
|
||||
{
|
||||
/* Can be NULL when gizmos are disabled. */
|
||||
if (gz->parent_gzgroup->customdata != NULL) {
|
||||
preview_plane_cursor_visible_set(gz->parent_gzgroup, visible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate 3D view incremental (grid) snapping.
|
||||
*
|
||||
@@ -454,7 +474,7 @@ static void draw_line_loop(const float coords[][3], int coords_len, const float
|
||||
float viewport[4];
|
||||
GPU_viewport_size_get_f(viewport);
|
||||
GPU_batch_uniform_2fv(batch, "viewportSize", &viewport[2]);
|
||||
GPU_batch_uniform_1f(batch, "lineWidth", U.pixelsize);
|
||||
GPU_batch_uniform_1f(batch, "lineWidth", GPU_line_width_get());
|
||||
|
||||
GPU_batch_draw(batch);
|
||||
|
||||
@@ -487,7 +507,7 @@ static void draw_line_pairs(const float coords_a[][3],
|
||||
float viewport[4];
|
||||
GPU_viewport_size_get_f(viewport);
|
||||
GPU_batch_uniform_2fv(batch, "viewportSize", &viewport[2]);
|
||||
GPU_batch_uniform_1f(batch, "lineWidth", U.pixelsize);
|
||||
GPU_batch_uniform_1f(batch, "lineWidth", GPU_line_width_get());
|
||||
|
||||
GPU_batch_draw(batch);
|
||||
|
||||
@@ -535,7 +555,7 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4])
|
||||
float viewport[4];
|
||||
GPU_viewport_size_get_f(viewport);
|
||||
GPU_batch_uniform_2fv(batch, "viewportSize", &viewport[2]);
|
||||
GPU_batch_uniform_1f(batch, "lineWidth", U.pixelsize);
|
||||
GPU_batch_uniform_1f(batch, "lineWidth", GPU_line_width_get());
|
||||
|
||||
GPU_batch_draw(batch);
|
||||
|
||||
@@ -1006,6 +1026,90 @@ static void view3d_interactive_add_calc_plane(bContext *C,
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public Placement Plane Functionality
|
||||
* \{ */
|
||||
|
||||
void ED_view3d_placement_plane_calc(bContext *C,
|
||||
const int mval[2],
|
||||
const int plane_axis,
|
||||
float r_co_src[3],
|
||||
float r_mat_orient[3][3])
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
|
||||
/* TODO what if there is no snap gizmo? */
|
||||
wmGizmo *snap_gizmo = idp_snap_gizmo_from_region(region);
|
||||
const float mval_fl[] = {mval[0], mval[1]};
|
||||
|
||||
/* TODO Options here should be input parameters. */
|
||||
view3d_interactive_add_calc_plane(C,
|
||||
scene,
|
||||
v3d,
|
||||
region,
|
||||
mval_fl,
|
||||
snap_gizmo,
|
||||
PLACE_SNAP_TO_GEOMETRY,
|
||||
PLACE_DEPTH_SURFACE,
|
||||
PLACE_ORIENT_SURFACE,
|
||||
plane_axis,
|
||||
false,
|
||||
r_co_src,
|
||||
r_mat_orient);
|
||||
}
|
||||
|
||||
static void placement_plane_adjust_to_boundbox(const BoundBox *boundbox,
|
||||
const enum ePlaceDirection direction,
|
||||
const float scale[3],
|
||||
const int plane_axis,
|
||||
const float plane_mat_orient[3][3],
|
||||
float r_co_src[3])
|
||||
{
|
||||
BLI_assert(ELEM(direction, PLACE_DIRECTION_NEG, PLACE_DIRECTION_POS));
|
||||
|
||||
const bool is_negative_up = scale[plane_axis] < 0;
|
||||
/* Calculate the offset for all axes. */
|
||||
float offset_vec[3] = {0};
|
||||
{
|
||||
/* Move the offset to put the return coordinate to the center of the bounding box. */
|
||||
BKE_boundbox_calc_center_aabb(boundbox, offset_vec);
|
||||
|
||||
/* Push offset at the plane axis so the bounding box surface is where the snapping point is. */
|
||||
float size[3];
|
||||
BKE_boundbox_calc_size_aabb(boundbox, size);
|
||||
offset_vec[plane_axis] -= size[plane_axis] * (is_negative_up ? -1 : 1);
|
||||
|
||||
/* Scale offset with the object scale. */
|
||||
mul_v3_v3(offset_vec, scale);
|
||||
if (direction == PLACE_DIRECTION_NEG) {
|
||||
mul_v3_fl(offset_vec, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Rotate the offset vector to the plane rotation. */
|
||||
mul_v3_m3v3(offset_vec, plane_mat_orient, offset_vec);
|
||||
/* Finally, add the rotated offset to the returned position. */
|
||||
add_v3_v3(r_co_src, offset_vec);
|
||||
}
|
||||
|
||||
void ED_view3d_placement_plane_boundbox_calc(bContext *C,
|
||||
const int mval[2],
|
||||
const BoundBox *boundbox,
|
||||
const enum ePlaceDirection direction,
|
||||
const float scale[3],
|
||||
float r_co_src[3],
|
||||
float r_mat_orient[3][3])
|
||||
{
|
||||
const int plane_axis = 2;
|
||||
ED_view3d_placement_plane_calc(C, mval, plane_axis, r_co_src, r_mat_orient);
|
||||
placement_plane_adjust_to_boundbox(
|
||||
boundbox, direction, scale, plane_axis, r_mat_orient, r_co_src);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Add Object Modal Operator
|
||||
* \{ */
|
||||
@@ -1032,19 +1136,8 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
|
||||
struct InteractivePlaceData *ipd = op->customdata;
|
||||
|
||||
/* Assign snap gizmo which is may be used as part of the tool. */
|
||||
{
|
||||
wmGizmoGroup *gzgroup = idp_gizmogroup_from_region(ipd->region);
|
||||
if (gzgroup != NULL) {
|
||||
if (gzgroup->gizmos.first) {
|
||||
ipd->snap_gizmo = gzgroup->gizmos.first;
|
||||
}
|
||||
|
||||
/* Can be NULL when gizmos are disabled. */
|
||||
if (gzgroup->customdata != NULL) {
|
||||
preview_plane_cursor_visible_set(gzgroup, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
ipd->snap_gizmo = idp_snap_gizmo_from_region(ipd->region);
|
||||
idp_paintcursor_from_gizmo_visible_set(ipd->snap_gizmo, false);
|
||||
|
||||
/* For tweak events the snap target may have changed since dragging,
|
||||
* update the snap target at the cursor location where tweak began.
|
||||
@@ -1243,12 +1336,8 @@ static void view3d_interactive_add_exit(bContext *C, wmOperator *op)
|
||||
ED_region_tag_redraw(ipd->region);
|
||||
|
||||
{
|
||||
wmGizmoGroup *gzgroup = idp_gizmogroup_from_region(ipd->region);
|
||||
if (gzgroup != NULL) {
|
||||
if (gzgroup->customdata != NULL) {
|
||||
preview_plane_cursor_visible_set(gzgroup, true);
|
||||
}
|
||||
}
|
||||
wmGizmo *snap_gz = idp_snap_gizmo_from_region(ipd->region);
|
||||
idp_paintcursor_from_gizmo_visible_set(snap_gz, true);
|
||||
}
|
||||
|
||||
MEM_freeN(ipd);
|
||||
@@ -1762,22 +1851,72 @@ static void WIDGETGROUP_placement_setup(const bContext *UNUSED(C), wmGizmoGroup
|
||||
gizmo->flag |= WM_GIZMO_HIDDEN_KEYMAP;
|
||||
}
|
||||
|
||||
/* Sets the gizmos custom-data which has its own free callback. */
|
||||
preview_plane_cursor_setup(gzgroup);
|
||||
{
|
||||
const wmGizmoType *gzt_plane = WM_gizmotype_find("GIZMO_GT_placement_plane_3d", true);
|
||||
gizmo = WM_gizmo_new_ptr(gzt_plane, gzgroup, NULL);
|
||||
|
||||
WM_gizmo_set_color(gizmo, (float[4]){1.0f, 1.0f, 1.0f, 1.0f});
|
||||
|
||||
/* Don't handle any events, this is for display only. */
|
||||
gizmo->flag |= WM_GIZMO_HIDDEN_KEYMAP;
|
||||
}
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_placement_draw_prepare(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
|
||||
{
|
||||
/* TODO only set for drag & drop. */
|
||||
if (!gzgroup->ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
wmGizmo *gizmo_plane = ((wmGizmo *)gzgroup->gizmos.first)->next;
|
||||
|
||||
PropertyRNA *boundbox_prop = RNA_struct_find_property(gzgroup->ptr, "bound_box");
|
||||
if (boundbox_prop && RNA_property_is_set(gzgroup->ptr, boundbox_prop)) {
|
||||
float array[8][3];
|
||||
RNA_property_float_get_array(gzgroup->ptr, boundbox_prop, (float *)array);
|
||||
RNA_float_set_array(gizmo_plane->ptr, "bound_box", (float *)array);
|
||||
}
|
||||
|
||||
PropertyRNA *matrix_basis_prop = RNA_struct_find_property(gzgroup->ptr, "matrix_basis");
|
||||
if (matrix_basis_prop && RNA_property_is_set(gzgroup->ptr, matrix_basis_prop)) {
|
||||
float array[4][4];
|
||||
RNA_property_float_get_array(gzgroup->ptr, matrix_basis_prop, (float *)array);
|
||||
RNA_float_set_array(gizmo_plane->ptr, "matrix_basis", (float *)array);
|
||||
}
|
||||
}
|
||||
|
||||
static bool WIDGETGROUP_placement_poll(const bContext *C, wmGizmoGroupType *gzgt)
|
||||
{
|
||||
return ED_gizmo_poll_from_dropbox(C, gzgt) || ED_gizmo_poll_from_tool(C, gzgt);
|
||||
}
|
||||
|
||||
void VIEW3D_GGT_placement(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
gzgt->name = "Placement Widget";
|
||||
gzgt->idname = view3d_gzgt_placement_id;
|
||||
|
||||
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL;
|
||||
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL |
|
||||
WM_GIZMOGROUPTYPE_ATTACHED_TO_CURSOR;
|
||||
|
||||
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
|
||||
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
|
||||
|
||||
gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
|
||||
gzgt->poll = WIDGETGROUP_placement_poll;
|
||||
gzgt->setup = WIDGETGROUP_placement_setup;
|
||||
gzgt->draw_prepare = WIDGETGROUP_placement_draw_prepare;
|
||||
|
||||
const int boundbox_dimsize[] = {8, 3};
|
||||
prop = RNA_def_property(gzgt->srna, "bound_box", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_multi_array(prop, 2, boundbox_dimsize);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
|
||||
const int matrix_dimsize[] = {4, 4};
|
||||
prop = RNA_def_property(gzgt->srna, "matrix_basis", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_multi_array(prop, 2, matrix_dimsize);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -1819,13 +1958,7 @@ static void gizmo_plane_update_cursor(const bContext *C,
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
|
||||
/* Assign snap gizmo which is may be used as part of the tool. */
|
||||
wmGizmo *snap_gizmo = NULL;
|
||||
{
|
||||
wmGizmoGroup *gzgroup = idp_gizmogroup_from_region(region);
|
||||
if ((gzgroup != NULL) && gzgroup->gizmos.first) {
|
||||
snap_gizmo = gzgroup->gizmos.first;
|
||||
}
|
||||
}
|
||||
wmGizmo *snap_gizmo = idp_snap_gizmo_from_region(region);
|
||||
|
||||
/* This ensures the snap gizmo has settings from this tool.
|
||||
* This function call could be moved a more appropriate place,
|
||||
@@ -1964,6 +2097,11 @@ struct PlacementCursor {
|
||||
|
||||
void *paintcursor;
|
||||
|
||||
float boundbox[8][3];
|
||||
bool draw_boundbox;
|
||||
|
||||
float scale[3];
|
||||
|
||||
int plane_axis;
|
||||
float matrix[4][4];
|
||||
|
||||
@@ -1972,9 +2110,8 @@ struct PlacementCursor {
|
||||
float persmat_prev[4][4];
|
||||
};
|
||||
|
||||
static void cursor_plane_draw(bContext *C, int x, int y, void *customdata)
|
||||
static void cursor_plane_draw_ex(const bContext *C, const int mval[2], struct PlacementCursor *plc)
|
||||
{
|
||||
struct PlacementCursor *plc = (struct PlacementCursor *)customdata;
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
const RegionView3D *rv3d = region->regiondata;
|
||||
|
||||
@@ -1994,6 +2131,9 @@ static void cursor_plane_draw(bContext *C, int x, int y, void *customdata)
|
||||
return;
|
||||
}
|
||||
|
||||
GPU_line_smooth(false);
|
||||
GPU_line_width(1.0f);
|
||||
|
||||
/* Check this gizmo group is in the region. */
|
||||
{
|
||||
wmGizmoMap *gzmap = region->gizmo_map;
|
||||
@@ -2004,8 +2144,6 @@ static void cursor_plane_draw(bContext *C, int x, int y, void *customdata)
|
||||
}
|
||||
}
|
||||
|
||||
const int mval[2] = {x - region->winrct.xmin, y - region->winrct.ymin};
|
||||
|
||||
/* Update matrix? */
|
||||
if ((plc->mval_prev[0] != mval[0]) || (plc->mval_prev[1] != mval[1]) ||
|
||||
!equals_m4m4(plc->persmat_prev, rv3d->persmat)) {
|
||||
@@ -2055,17 +2193,29 @@ static void cursor_plane_draw(bContext *C, int x, int y, void *customdata)
|
||||
}
|
||||
|
||||
/* Setup viewport & matrix. */
|
||||
wmViewport(®ion->winrct);
|
||||
if (plc->paintcursor) {
|
||||
/* Paint cursors are on window level, need to set the viewport. */
|
||||
wmViewport(®ion->winrct);
|
||||
}
|
||||
GPU_matrix_push_projection();
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_projection_set(rv3d->winmat);
|
||||
GPU_matrix_set(rv3d->viewmat);
|
||||
|
||||
const float scale_mod = U.gizmo_size * 2 * U.dpi_fac / U.pixelsize;
|
||||
float final_scale;
|
||||
if (plc->draw_boundbox) {
|
||||
/* Take diagonal of lower face to make the size based on the boundbox. */
|
||||
float lower_min[3], lower_max[3];
|
||||
mul_v3_v3v3(lower_min, plc->boundbox[0], plc->scale);
|
||||
mul_v3_v3v3(lower_max, plc->boundbox[6], plc->scale);
|
||||
final_scale = len_v3v3(lower_min, lower_max);
|
||||
}
|
||||
else {
|
||||
const float scale_mod = U.gizmo_size * 2 * U.dpi_fac / U.pixelsize;
|
||||
final_scale = (scale_mod * pixel_size);
|
||||
}
|
||||
|
||||
float final_scale = (scale_mod * pixel_size);
|
||||
|
||||
const int lines_subdiv = 10;
|
||||
const int lines_subdiv = 10.0f;
|
||||
int lines = lines_subdiv;
|
||||
|
||||
float final_scale_fade = final_scale;
|
||||
@@ -2093,12 +2243,46 @@ static void cursor_plane_draw(bContext *C, int x, int y, void *customdata)
|
||||
gizmo_plane_draw_grid(
|
||||
lines, final_scale, final_scale_fade, plc->matrix, plc->plane_axis, color);
|
||||
|
||||
/* TODO support different plane axis (assumes Z right now). */
|
||||
if (plc->draw_boundbox) {
|
||||
float box_col[4] = {0.4f, 0.8f, 1.0f, 0.75f};
|
||||
BoundBox bounds;
|
||||
memcpy(bounds.vec, plc->boundbox, sizeof(bounds.vec));
|
||||
|
||||
float size[3];
|
||||
BKE_boundbox_calc_size_aabb(&bounds, size);
|
||||
|
||||
float min[3] = {-size[0], -size[1], 0.0f};
|
||||
float max[3] = {size[0], size[1], size[2] * 2};
|
||||
mul_v3_v3(min, plc->scale);
|
||||
mul_v3_v3(max, plc->scale);
|
||||
BKE_boundbox_init_from_minmax(&bounds, min, max);
|
||||
|
||||
GPU_matrix_mul(plc->matrix);
|
||||
/* Ensure the bounding-box points up. Matches how it will be placed eventualy. */
|
||||
const bool negative_up = bounds.vec[1][2] < 0;
|
||||
if (negative_up) {
|
||||
GPU_matrix_scale_1f(-1.0f);
|
||||
}
|
||||
|
||||
GPU_line_width(2.0f);
|
||||
draw_line_bounds(&bounds, box_col);
|
||||
}
|
||||
|
||||
/* Restore matrix. */
|
||||
GPU_matrix_pop();
|
||||
GPU_matrix_pop_projection();
|
||||
}
|
||||
}
|
||||
|
||||
static void cursor_plane_draw_cursor_fn(bContext *C, int x, int y, void *customdata)
|
||||
{
|
||||
struct PlacementCursor *plc = (struct PlacementCursor *)customdata;
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
const int mval[2] = {x - region->winrct.xmin, y - region->winrct.ymin};
|
||||
cursor_plane_draw_ex(C, mval, plc);
|
||||
}
|
||||
|
||||
static void preview_plane_cursor_free(void *customdata)
|
||||
{
|
||||
struct PlacementCursor *plc = customdata;
|
||||
@@ -2111,13 +2295,13 @@ static void preview_plane_cursor_free(void *customdata)
|
||||
MEM_freeN(plc);
|
||||
}
|
||||
|
||||
static void preview_plane_cursor_setup(wmGizmoGroup *gzgroup)
|
||||
static void UNUSED_FUNCTION(preview_plane_cursor_setup)(wmGizmoGroup *gzgroup)
|
||||
{
|
||||
BLI_assert(gzgroup->customdata == NULL);
|
||||
struct PlacementCursor *plc = MEM_callocN(sizeof(*plc), __func__);
|
||||
plc->gzgroup = gzgroup;
|
||||
plc->paintcursor = WM_paint_cursor_activate(
|
||||
SPACE_VIEW3D, RGN_TYPE_WINDOW, NULL, cursor_plane_draw, plc);
|
||||
SPACE_VIEW3D, RGN_TYPE_WINDOW, NULL, cursor_plane_draw_cursor_fn, plc);
|
||||
gzgroup->customdata = plc;
|
||||
gzgroup->customdata_free = preview_plane_cursor_free;
|
||||
|
||||
@@ -2131,3 +2315,91 @@ static void preview_plane_cursor_visible_set(wmGizmoGroup *gzgroup, bool do_draw
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Placement Plane Gizmo
|
||||
* \{ */
|
||||
|
||||
struct PlacementPlaneGizmo {
|
||||
wmGizmo gizmo;
|
||||
struct PlacementCursor *plc;
|
||||
};
|
||||
|
||||
static void gizmo_placement_plane_setup(wmGizmo *gz)
|
||||
{
|
||||
struct PlacementPlaneGizmo *plane_gz = (struct PlacementPlaneGizmo *)gz;
|
||||
plane_gz->plc = MEM_callocN(sizeof(*plane_gz->plc), __func__);
|
||||
plane_gz->plc->gzgroup = gz->parent_gzgroup;
|
||||
}
|
||||
|
||||
static void gizmo_placement_plane_free(wmGizmo *gz)
|
||||
{
|
||||
struct PlacementPlaneGizmo *plane_gz = (struct PlacementPlaneGizmo *)gz;
|
||||
MEM_SAFE_FREE(plane_gz->plc);
|
||||
}
|
||||
|
||||
static void gizmo_placement_plane_draw(const bContext *C, wmGizmo *gz)
|
||||
{
|
||||
struct PlacementPlaneGizmo *plane_gz = (struct PlacementPlaneGizmo *)gz;
|
||||
struct PlacementCursor *plc = plane_gz->plc;
|
||||
const wmWindow *win = CTX_wm_window(C);
|
||||
|
||||
plc->do_draw = true;
|
||||
|
||||
PropertyRNA *boundbox_prop = RNA_struct_find_property(gz->ptr, "bound_box");
|
||||
if (RNA_property_is_set(gz->ptr, boundbox_prop)) {
|
||||
RNA_property_float_get_array(gz->ptr, boundbox_prop, (float *)plc->boundbox);
|
||||
plc->draw_boundbox = true;
|
||||
}
|
||||
else {
|
||||
plc->draw_boundbox = false;
|
||||
}
|
||||
|
||||
PropertyRNA *matrix_basis_prop = RNA_struct_find_property(gz->ptr, "matrix_basis");
|
||||
if (RNA_property_is_set(gz->ptr, matrix_basis_prop)) {
|
||||
float mat[4][4];
|
||||
RNA_property_float_get_array(gz->ptr, matrix_basis_prop, (float *)mat);
|
||||
mat4_to_size(plc->scale, mat);
|
||||
}
|
||||
else {
|
||||
copy_v3_fl(plc->scale, 1.0f);
|
||||
}
|
||||
|
||||
const wmEvent *eventstate = win->eventstate;
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
const int mval[2] = {eventstate->x - region->winrct.xmin, eventstate->y - region->winrct.ymin};
|
||||
|
||||
cursor_plane_draw_ex(C, mval, plc);
|
||||
}
|
||||
|
||||
static void GIZMO_GT_placement_plane_3d(wmGizmoType *gzt)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
gzt->idname = "GIZMO_GT_placement_plane_3d";
|
||||
|
||||
/* api callbacks */
|
||||
gzt->setup = gizmo_placement_plane_setup;
|
||||
gzt->draw = gizmo_placement_plane_draw;
|
||||
gzt->free = gizmo_placement_plane_free;
|
||||
|
||||
gzt->struct_size = sizeof(struct PlacementPlaneGizmo);
|
||||
|
||||
const int boundbox_dimsize[] = {8, 3};
|
||||
prop = RNA_def_property(gzt->srna, "bound_box", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_multi_array(prop, 2, boundbox_dimsize);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
|
||||
const int matrix_dimsize[] = {4, 4};
|
||||
prop = RNA_def_property(gzt->srna, "matrix_basis", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_multi_array(prop, 2, matrix_dimsize);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
void ED_gizmotypes_placement_3d(void)
|
||||
{
|
||||
WM_gizmotype_append(GIZMO_GT_placement_plane_3d);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@@ -75,3 +75,27 @@ bool ED_gizmo_poll_or_unlink_delayed_from_tool(const bContext *C, wmGizmoGroupTy
|
||||
{
|
||||
return ED_gizmo_poll_or_unlink_delayed_from_tool_ex(C, gzgt, gzgt->idname);
|
||||
}
|
||||
|
||||
bool ED_gizmo_poll_from_tool_ex(const bContext *C, const char *gzgt_idname)
|
||||
{
|
||||
bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
|
||||
if ((tref_rt == NULL) || !STREQ(gzgt_idname, tref_rt->gizmo_group)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ED_gizmo_poll_from_tool(const bContext *C, const wmGizmoGroupType *gzgt)
|
||||
{
|
||||
return ED_gizmo_poll_from_tool_ex(C, gzgt->idname);
|
||||
}
|
||||
|
||||
bool ED_gizmo_poll_from_dropbox_ex(const bContext *C, const char *gzgt_idname)
|
||||
{
|
||||
return WM_drag_with_gizmogroup_find(CTX_wm_manager(C), gzgt_idname) != NULL;
|
||||
}
|
||||
|
||||
bool ED_gizmo_poll_from_dropbox(const bContext *C, const wmGizmoGroupType *gzgt)
|
||||
{
|
||||
return ED_gizmo_poll_from_dropbox_ex(C, gzgt->idname);
|
||||
}
|
||||
|
@@ -56,6 +56,9 @@ typedef struct AssetFilterSettings {
|
||||
* more than that from the file. So pointers to other IDs or ID data are strictly forbidden.
|
||||
*/
|
||||
typedef struct AssetMetaData {
|
||||
/** Runtime type, to reference event callbacks. Only valid for local assets. */
|
||||
struct AssetTypeInfo *local_type_info;
|
||||
|
||||
/** Custom asset meta-data. Cannot store pointers to IDs (#STRUCT_NO_DATABLOCK_IDPROPERTIES)! */
|
||||
struct IDProperty *properties;
|
||||
|
||||
|
@@ -735,6 +735,9 @@ struct wmDropBox *WM_dropbox_add(
|
||||
void (*copy)(struct wmDrag *, struct wmDropBox *),
|
||||
void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *),
|
||||
WMDropboxTooltipFunc tooltip);
|
||||
void WM_dropbox_gizmogroup_set(struct wmDropBox *,
|
||||
const char gizmo_group[MAX_NAME],
|
||||
void (*copy_gizmo_group)(struct wmDrag *, struct wmDropBox *));
|
||||
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
|
||||
|
||||
/* ID drag and drop */
|
||||
@@ -744,9 +747,11 @@ struct ID *WM_drag_get_local_ID_from_event(const struct wmEvent *event, short id
|
||||
bool WM_drag_is_ID_type(const struct wmDrag *drag, int idcode);
|
||||
|
||||
wmDragAsset *WM_drag_create_asset_data(const struct AssetHandle *asset,
|
||||
struct AssetMetaData *metadata,
|
||||
const char *path,
|
||||
int import_type);
|
||||
struct wmDragAsset *WM_drag_get_asset_data(const struct wmDrag *drag, int idcode);
|
||||
struct AssetMetaData *WM_drag_get_asset_meta_data(const struct wmDrag *drag, int idcode);
|
||||
struct ID *WM_drag_get_local_ID_or_import_from_asset(const struct wmDrag *drag, int idcode);
|
||||
|
||||
void WM_drag_free_imported_drag_ID(struct Main *bmain,
|
||||
@@ -759,6 +764,9 @@ void WM_drag_add_asset_list_item(wmDrag *drag,
|
||||
const struct AssetHandle *asset);
|
||||
const ListBase *WM_drag_asset_list_get(const wmDrag *drag);
|
||||
|
||||
const struct wmDrag *WM_drag_with_gizmogroup_find(
|
||||
const struct wmWindowManager *wm, const char name[MAX_NAME]) ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
const char *WM_drag_get_item_name(struct wmDrag *drag);
|
||||
|
||||
/* Set OpenGL viewport and scissor */
|
||||
|
@@ -982,6 +982,7 @@ typedef struct wmDragAsset {
|
||||
/* Always freed. */
|
||||
const char *path;
|
||||
int id_type;
|
||||
struct AssetMetaData *metadata;
|
||||
int import_type; /* eFileAssetImportType */
|
||||
|
||||
/* FIXME: This is temporary evil solution to get scene/view-layer/etc in the copy callback of the
|
||||
@@ -1031,8 +1032,15 @@ typedef struct wmDrag {
|
||||
float scale;
|
||||
int sx, sy;
|
||||
|
||||
/** Don't draw the icon or image (`imb`). Can be set in the `poll()` callback of the drop-box. */
|
||||
bool no_preview;
|
||||
|
||||
/** If filled, draws operator tooltip/operator name. */
|
||||
char tooltip[200];
|
||||
/** If set, draws gizmo group. */
|
||||
char gizmo_group[64];
|
||||
struct IDProperty *gizmo_group_prop;
|
||||
|
||||
unsigned int flags;
|
||||
|
||||
/** List of wmDragIDs, all are guaranteed to have the same ID type. */
|
||||
@@ -1041,6 +1049,8 @@ typedef struct wmDrag {
|
||||
ListBase asset_items;
|
||||
} wmDrag;
|
||||
|
||||
typedef void (*wmDropBoxCopyFn)(struct wmDrag *, struct wmDropBox *);
|
||||
|
||||
/**
|
||||
* Dropboxes are like keymaps, part of the screen/area/region definition.
|
||||
* Allocation and free is on startup and exit.
|
||||
@@ -1052,7 +1062,9 @@ typedef struct wmDropBox {
|
||||
bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *);
|
||||
|
||||
/** Before exec, this copies drag info to #wmDrop properties. */
|
||||
void (*copy)(struct wmDrag *, struct wmDropBox *);
|
||||
wmDropBoxCopyFn copy;
|
||||
/** Before `gizmo_group` is enabled, this copies drag info to #wmDrop gizmo-group properties. */
|
||||
wmDropBoxCopyFn copy_gizmo_group;
|
||||
|
||||
/**
|
||||
* If the operator is cancelled (returns `OPERATOR_CANCELLED`), this can be used for cleanup of
|
||||
@@ -1068,15 +1080,18 @@ typedef struct wmDropBox {
|
||||
* Not saved in file, so can be pointer.
|
||||
*/
|
||||
wmOperatorType *ot;
|
||||
|
||||
/** Operator properties, assigned to ptr->data and can be written to a file. */
|
||||
struct IDProperty *properties;
|
||||
/** RNA pointer to access properties. */
|
||||
struct PointerRNA *ptr;
|
||||
|
||||
/** Default invoke. */
|
||||
short opcontext;
|
||||
|
||||
/**
|
||||
* If poll succeeds, gizmo is drawn.
|
||||
*/
|
||||
char gizmo_group[64];
|
||||
struct PointerRNA *gizmo_group_ptr;
|
||||
} wmDropBox;
|
||||
|
||||
/**
|
||||
|
@@ -155,6 +155,11 @@ typedef enum eWM_GizmoFlagGroupTypeFlag {
|
||||
*/
|
||||
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK = (1 << 9),
|
||||
|
||||
/**
|
||||
* Redraw the region's gizmos on mouse moves.
|
||||
*/
|
||||
WM_GIZMOGROUPTYPE_ATTACHED_TO_CURSOR = (1 << 9),
|
||||
|
||||
/**
|
||||
* Cause continuous redraws, i.e. set the region redraw flag on every main loop iteration. This
|
||||
* should really be avoided by using proper region redraw tagging, notifiers and the message-bus,
|
||||
@@ -483,6 +488,9 @@ typedef struct wmGizmoGroup {
|
||||
struct wmGizmoGroupType *type;
|
||||
ListBase gizmos;
|
||||
|
||||
struct PointerRNA *ptr;
|
||||
struct IDProperty *properties;
|
||||
|
||||
struct wmGizmoMap *parent_gzmap;
|
||||
|
||||
/** Python stores the class instance here. */
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_workspace.h"
|
||||
@@ -122,6 +123,14 @@ void wm_gizmogroup_free(bContext *C, wmGizmoGroup *gzgroup)
|
||||
MEM_freeN(gzgroup->reports);
|
||||
}
|
||||
|
||||
if (gzgroup->ptr) {
|
||||
gzgroup->properties = gzgroup->ptr->data;
|
||||
MEM_freeN(gzgroup->ptr);
|
||||
}
|
||||
if (gzgroup->properties) {
|
||||
IDP_FreeProperty(gzgroup->properties);
|
||||
}
|
||||
|
||||
if (gzgroup->customdata_free) {
|
||||
gzgroup->customdata_free(gzgroup->customdata);
|
||||
}
|
||||
|
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
@@ -130,6 +131,15 @@ wmDropBox *WM_dropbox_add(ListBase *lb,
|
||||
return drop;
|
||||
}
|
||||
|
||||
void WM_dropbox_gizmogroup_set(wmDropBox *drop,
|
||||
const char gizmo_group[MAX_NAME],
|
||||
wmDropBoxCopyFn copy_gizmo_group)
|
||||
{
|
||||
BLI_strncpy(drop->gizmo_group, gizmo_group, sizeof(drop->gizmo_group));
|
||||
drop->copy_gizmo_group = copy_gizmo_group;
|
||||
WM_gizmo_group_type_add(gizmo_group);
|
||||
}
|
||||
|
||||
void wm_dropbox_free(void)
|
||||
{
|
||||
|
||||
@@ -250,6 +260,25 @@ void WM_drag_free_list(struct ListBase *lb)
|
||||
}
|
||||
}
|
||||
|
||||
struct wmDropboxActiveInfo {
|
||||
wmDropBox *drop;
|
||||
/* Some string the operator sets (operator name or some tooltip). */
|
||||
const char *operator_string;
|
||||
const char *gizmo_group;
|
||||
};
|
||||
|
||||
static void wm_gizmogroup_properties_create(PointerRNA *ptr, const char *gz_group_name)
|
||||
{
|
||||
const wmGizmoGroupType *gz_grouptype = WM_gizmogrouptype_find(gz_group_name, false);
|
||||
|
||||
if (gz_grouptype) {
|
||||
RNA_pointer_create(NULL, gz_grouptype->srna, NULL, ptr);
|
||||
}
|
||||
else {
|
||||
RNA_pointer_create(NULL, &RNA_GizmoGroupProperties, NULL, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static char *dropbox_tooltip(bContext *C, wmDrag *drag, const wmEvent *event, wmDropBox *drop)
|
||||
{
|
||||
char *tooltip = NULL;
|
||||
@@ -264,6 +293,40 @@ static char *dropbox_tooltip(bContext *C, wmDrag *drag, const wmEvent *event, wm
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
static void wm_gizmogroup_properties_alloc(PointerRNA **ptr,
|
||||
IDProperty **properties,
|
||||
const char *gz_group_name)
|
||||
{
|
||||
if (*properties == NULL) {
|
||||
IDPropertyTemplate val = {0};
|
||||
*properties = IDP_New(IDP_GROUP, &val, "wmGizmoGroupProp");
|
||||
}
|
||||
if (*ptr == NULL) {
|
||||
*ptr = MEM_callocN(sizeof(PointerRNA), "wmGizmoGroupPtr");
|
||||
wm_gizmogroup_properties_create(*ptr, gz_group_name);
|
||||
}
|
||||
|
||||
(*ptr)->data = *properties;
|
||||
}
|
||||
|
||||
static void dropbox_gizmo_activate(bContext *C, wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
if (!STREQ(drag->gizmo_group, drop->gizmo_group)) {
|
||||
if (drop->gizmo_group[0]) {
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
wmGizmoGroup *gzgroup = WM_gizmomap_group_find(region->gizmo_map, drop->gizmo_group);
|
||||
if (gzgroup) {
|
||||
wm_gizmogroup_properties_alloc(&gzgroup->ptr, &gzgroup->properties, drop->gizmo_group);
|
||||
WM_gizmo_properties_sanitize(gzgroup->ptr, 0);
|
||||
drop->gizmo_group_ptr = gzgroup->ptr;
|
||||
|
||||
drop->copy_gizmo_group(drag, drop);
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_strncpy(drag->gizmo_group, drop->gizmo_group, sizeof(drag->gizmo_group));
|
||||
}
|
||||
|
||||
static wmDropBox *dropbox_active(bContext *C,
|
||||
ListBase *handlers,
|
||||
wmDrag *drag,
|
||||
@@ -285,11 +348,18 @@ static wmDropBox *dropbox_active(bContext *C,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* return active operator tooltip/name when mouse is in box */
|
||||
static char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||
/* return active operator name when mouse is in box */
|
||||
/**
|
||||
* \returns Pointer to static `wmDropboxActiveInfo` data, when the mouse is in a box with a
|
||||
* succeeding poll().
|
||||
*/
|
||||
static struct wmDropboxActiveInfo *wm_dropbox_active(bContext *C,
|
||||
wmDrag *drag,
|
||||
const wmEvent *event)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
wmDropBox *drop = dropbox_active(C, &win->handlers, drag, event);
|
||||
|
||||
if (!drop) {
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
drop = dropbox_active(C, &area->handlers, drag, event);
|
||||
@@ -298,9 +368,15 @@ static char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
drop = dropbox_active(C, ®ion->handlers, drag, event);
|
||||
}
|
||||
|
||||
if (drop) {
|
||||
return dropbox_tooltip(C, drag, event, drop);
|
||||
static struct wmDropboxActiveInfo active_info;
|
||||
active_info.drop = drop;
|
||||
active_info.gizmo_group = drop->gizmo_group;
|
||||
active_info.operator_string = dropbox_tooltip(C, drag, event, drop);
|
||||
return &active_info;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -316,19 +392,28 @@ static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *e
|
||||
}
|
||||
|
||||
drag->tooltip[0] = 0;
|
||||
/* Allow setting this in the `poll()`. */
|
||||
drag->no_preview = false;
|
||||
|
||||
/* check buttons (XXX todo rna and value) */
|
||||
if (UI_but_active_drop_name(C)) {
|
||||
BLI_strncpy(drag->tooltip, IFACE_("Paste name"), sizeof(drag->tooltip));
|
||||
drag->gizmo_group[0] = 0;
|
||||
}
|
||||
else {
|
||||
char *tooltip = wm_dropbox_active(C, drag, event);
|
||||
struct wmDropboxActiveInfo *active_info = wm_dropbox_active(C, drag, event);
|
||||
|
||||
if (tooltip) {
|
||||
BLI_strncpy(drag->tooltip, tooltip, sizeof(drag->tooltip));
|
||||
MEM_freeN(tooltip);
|
||||
if (active_info && active_info->operator_string) {
|
||||
BLI_strncpy(drag->tooltip, active_info->operator_string, sizeof(drag->tooltip));
|
||||
MEM_freeN((char *)active_info->operator_string);
|
||||
// WM_cursor_modal_set(win, WM_CURSOR_COPY);
|
||||
}
|
||||
if (active_info && active_info->gizmo_group) {
|
||||
dropbox_gizmo_activate(C, drag, active_info->drop);
|
||||
}
|
||||
else {
|
||||
drag->gizmo_group[0] = 0;
|
||||
}
|
||||
// else
|
||||
// WM_cursor_modal_restore(win);
|
||||
/* unsure about cursor type, feels to be too much */
|
||||
@@ -406,11 +491,15 @@ bool WM_drag_is_ID_type(const wmDrag *drag, int idcode)
|
||||
/**
|
||||
* \note: Does not store \a asset in any way, so it's fine to pass a temporary.
|
||||
*/
|
||||
wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset, const char *path, int import_type)
|
||||
wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset,
|
||||
AssetMetaData *metadata,
|
||||
const char *path,
|
||||
int import_type)
|
||||
{
|
||||
wmDragAsset *asset_drag = MEM_mallocN(sizeof(*asset_drag), "wmDragAsset");
|
||||
|
||||
BLI_strncpy(asset_drag->name, ED_asset_handle_get_name(asset), sizeof(asset_drag->name));
|
||||
asset_drag->metadata = metadata;
|
||||
asset_drag->path = path;
|
||||
asset_drag->id_type = ED_asset_handle_get_id_type(asset);
|
||||
asset_drag->import_type = import_type;
|
||||
@@ -434,6 +523,21 @@ wmDragAsset *WM_drag_get_asset_data(const wmDrag *drag, int idcode)
|
||||
return (ELEM(idcode, 0, asset_drag->id_type)) ? asset_drag : NULL;
|
||||
}
|
||||
|
||||
struct AssetMetaData *WM_drag_get_asset_meta_data(const wmDrag *drag, int idcode)
|
||||
{
|
||||
wmDragAsset *drag_asset = WM_drag_get_asset_data(drag, idcode);
|
||||
if (drag_asset) {
|
||||
return drag_asset->metadata;
|
||||
}
|
||||
|
||||
ID *local_id = WM_drag_get_local_ID(drag, idcode);
|
||||
if (local_id) {
|
||||
return local_id->asset_data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag)
|
||||
{
|
||||
const char *name = asset_drag->name;
|
||||
@@ -565,11 +669,12 @@ void WM_drag_add_asset_list_item(
|
||||
drag_asset->asset_data.local_id = local_id;
|
||||
}
|
||||
else {
|
||||
AssetMetaData *metadata = ED_asset_handle_get_metadata(asset);
|
||||
char asset_blend_path[FILE_MAX_LIBEXTRA];
|
||||
ED_asset_handle_get_full_library_path(C, asset_library_ref, asset, asset_blend_path);
|
||||
drag_asset->is_external = true;
|
||||
drag_asset->asset_data.external_info = WM_drag_create_asset_data(
|
||||
asset, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND);
|
||||
asset, metadata, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND);
|
||||
}
|
||||
BLI_addtail(&drag->asset_items, drag_asset);
|
||||
}
|
||||
@@ -665,8 +770,12 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
|
||||
int padding = 4 * UI_DPI_FAC;
|
||||
|
||||
/* image or icon */
|
||||
int x, y;
|
||||
if (drag->imb) {
|
||||
int x = cursorx - 2 * padding;
|
||||
int y = cursory - 2 * UI_DPI_FAC;
|
||||
if (drag->no_preview) {
|
||||
/* Pass. */
|
||||
}
|
||||
else if (drag->imb) {
|
||||
x = cursorx - drag->sx / 2;
|
||||
y = cursory - drag->sy / 2;
|
||||
|
||||
@@ -692,9 +801,6 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
|
||||
}
|
||||
}
|
||||
else {
|
||||
x = cursorx - 2 * padding;
|
||||
y = cursory - 2 * UI_DPI_FAC;
|
||||
|
||||
if (rect) {
|
||||
drag_rect_minmax(rect, x, y, x + iconsize, y + iconsize);
|
||||
}
|
||||
@@ -704,7 +810,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
|
||||
}
|
||||
|
||||
/* item name */
|
||||
if (drag->imb) {
|
||||
if (!drag->no_preview && drag->imb) {
|
||||
x = cursorx - drag->sx / 2;
|
||||
y = cursory - drag->sy / 2 - iconsize;
|
||||
}
|
||||
@@ -755,3 +861,16 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
|
||||
}
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
/* ************** Queries ***************** */
|
||||
|
||||
const wmDrag *WM_drag_with_gizmogroup_find(const wmWindowManager *wm, const char name[MAX_NAME])
|
||||
{
|
||||
LISTBASE_FOREACH (const wmDrag *, drag, &wm->drags) {
|
||||
if (STREQ(drag->gizmo_group, name)) {
|
||||
return drag;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -2964,6 +2964,13 @@ static int wm_handlers_do_gizmo_handler(bContext *C,
|
||||
}
|
||||
}
|
||||
|
||||
const ListBase *groups = WM_gizmomap_group_list(gzmap);
|
||||
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, groups) {
|
||||
if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_ATTACHED_TO_CURSOR) {
|
||||
ED_region_tag_redraw_editor_overlays(CTX_wm_region(C));
|
||||
}
|
||||
}
|
||||
|
||||
/* restore the area */
|
||||
CTX_wm_area_set(C, area);
|
||||
CTX_wm_region_set(C, region);
|
||||
@@ -3080,6 +3087,10 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
|
||||
|
||||
action |= WM_HANDLER_BREAK;
|
||||
|
||||
if (drop->gizmo_group[0]) {
|
||||
/* Redraw so gizmos disappear visually. */
|
||||
ED_region_tag_redraw_editor_overlays(CTX_wm_region(C));
|
||||
}
|
||||
/* Free the drags. */
|
||||
WM_drag_free_list(lb);
|
||||
WM_drag_free_list(&single_lb);
|
||||
@@ -3386,7 +3397,10 @@ static void wm_paintcursor_test(bContext *C, const wmEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
static void wm_event_drag_and_drop_test(wmWindowManager *wm, wmWindow *win, wmEvent *event)
|
||||
static void wm_event_drag_and_drop_test(bContext *C,
|
||||
wmWindowManager *wm,
|
||||
wmWindow *win,
|
||||
wmEvent *event)
|
||||
{
|
||||
bScreen *screen = WM_window_get_active_screen(win);
|
||||
|
||||
@@ -3398,6 +3412,7 @@ static void wm_event_drag_and_drop_test(wmWindowManager *wm, wmWindow *win, wmEv
|
||||
screen->do_draw_drag = true;
|
||||
}
|
||||
else if (event->type == EVT_ESCKEY) {
|
||||
ED_region_tag_redraw_editor_overlays(CTX_wm_region(C));
|
||||
WM_drag_free_list(&wm->drags);
|
||||
|
||||
screen->do_draw_drag = true;
|
||||
@@ -3673,7 +3688,7 @@ void wm_event_do_handlers(bContext *C)
|
||||
}
|
||||
|
||||
/* Check dragging, creates new event or frees, adds draw tag. */
|
||||
wm_event_drag_and_drop_test(wm, win, event);
|
||||
wm_event_drag_and_drop_test(C, wm, win, event);
|
||||
|
||||
/* Builtin tweak, if action is break it removes tweak. */
|
||||
wm_tweakevent_test(C, event, action);
|
||||
|
@@ -105,6 +105,7 @@
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_thumbs.h"
|
||||
|
||||
#include "ED_asset.h"
|
||||
#include "ED_datafiles.h"
|
||||
#include "ED_fileselect.h"
|
||||
#include "ED_image.h"
|
||||
@@ -1781,6 +1782,7 @@ static bool wm_file_write(bContext *C,
|
||||
/* Call pre-save callbacks before writing preview,
|
||||
* that way you can generate custom file thumbnail. */
|
||||
BKE_callback_exec_null(bmain, BKE_CB_EVT_SAVE_PRE);
|
||||
ED_assets_pre_save(bmain);
|
||||
|
||||
/* Enforce full override check/generation on file save. */
|
||||
BKE_lib_override_library_main_operations_create(bmain, true);
|
||||
@@ -2098,6 +2100,7 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
BKE_callback_exec_null(bmain, BKE_CB_EVT_SAVE_PRE);
|
||||
ED_assets_pre_save(bmain);
|
||||
|
||||
/* check current window and close it if temp */
|
||||
if (win && WM_window_is_temp_screen(win)) {
|
||||
|
Reference in New Issue
Block a user