Add Chromium-only Blender WebEngine parity work
This commit is contained in:
479
blender-5.2.0/source/blender/windowmanager/gizmo/WM_gizmo_api.hh
Normal file
479
blender-5.2.0/source/blender/windowmanager/gizmo/WM_gizmo_api.hh
Normal file
@@ -0,0 +1,479 @@
|
||||
/* SPDX-FileCopyrightText: 2016 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup wm
|
||||
*
|
||||
* \name Gizmo API
|
||||
* \brief API for external use of wmGizmo types.
|
||||
*
|
||||
* Only included in WM_api.hh
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "WM_gizmo_types.hh"
|
||||
#include "wm_gizmo_fn.hh"
|
||||
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
struct ARegion;
|
||||
struct bContext;
|
||||
struct IDProperty;
|
||||
struct Main;
|
||||
struct PointerRNA;
|
||||
struct PropertyRNA;
|
||||
struct ScrArea;
|
||||
struct bToolRef;
|
||||
struct wmGizmo;
|
||||
struct wmGizmoGroup;
|
||||
struct wmGizmoGroupType;
|
||||
struct wmGizmoGroupTypeRef;
|
||||
struct wmGizmoMap;
|
||||
struct wmGizmoMapType;
|
||||
struct wmGizmoMapType_Params;
|
||||
struct wmGizmoOpElem;
|
||||
struct wmGizmoProperty;
|
||||
struct wmGizmoPropertyType;
|
||||
struct wmGizmoType;
|
||||
struct wmKeyConfig;
|
||||
struct wmMsgSubscribeKey;
|
||||
struct wmMsgSubscribeValue;
|
||||
struct wmOperatorType;
|
||||
struct wmWindow;
|
||||
struct wmWindowManager;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmo. */
|
||||
|
||||
wmGizmo *WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties);
|
||||
/**
|
||||
* \param idname: Must be a valid gizmo type name,
|
||||
* if you need to check it exists use #WM_gizmo_new_ptr
|
||||
* because callers of this function don't NULL check the return value.
|
||||
*/
|
||||
wmGizmo *WM_gizmo_new(StringRef idname, wmGizmoGroup *gzgroup, PointerRNA *properties);
|
||||
/**
|
||||
* \warning this doesn't check #wmGizmoMap (highlight, selection etc).
|
||||
* Typical use is when freeing the windowing data,
|
||||
* where caller can manage clearing selection, highlight... etc.
|
||||
*/
|
||||
void WM_gizmo_free(wmGizmo *gz);
|
||||
/**
|
||||
* Free \a gizmo and unlink from \a gizmolist.
|
||||
* \a gizmolist is allowed to be NULL.
|
||||
*/
|
||||
void WM_gizmo_unlink(ListBaseT<wmGizmo> *gizmolist, wmGizmoMap *gzmap, wmGizmo *gz, bContext *C);
|
||||
|
||||
/**
|
||||
* Remove from selection array without running callbacks.
|
||||
*/
|
||||
bool WM_gizmo_select_unlink(wmGizmoMap *gzmap, wmGizmo *gz);
|
||||
bool WM_gizmo_select_set(wmGizmoMap *gzmap, wmGizmo *gz, bool select);
|
||||
bool WM_gizmo_highlight_set(wmGizmoMap *gzmap, wmGizmo *gz);
|
||||
|
||||
/**
|
||||
* Special function to run from setup so gizmos start out interactive.
|
||||
*
|
||||
* We could do this when linking them,
|
||||
* but this complicates things since the window update code needs to run first.
|
||||
*/
|
||||
void WM_gizmo_modal_set_from_setup(
|
||||
wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, int part_index, const wmEvent *event);
|
||||
|
||||
/**
|
||||
* Replaces the current gizmo modal.
|
||||
* The substitute gizmo start out interactive.
|
||||
* It is similar to #WM_gizmo_modal_set_from_setup but without operator initialization.
|
||||
*/
|
||||
void WM_gizmo_modal_set_while_modal(wmGizmoMap *gzmap,
|
||||
bContext *C,
|
||||
wmGizmo *gz,
|
||||
const wmEvent *event);
|
||||
|
||||
wmGizmoOpElem *WM_gizmo_operator_get(wmGizmo *gz, int part_index);
|
||||
PointerRNA *WM_gizmo_operator_set(wmGizmo *gz,
|
||||
int part_index,
|
||||
wmOperatorType *ot,
|
||||
IDProperty *properties);
|
||||
wmOperatorStatus WM_gizmo_operator_invoke(bContext *C,
|
||||
wmGizmo *gz,
|
||||
wmGizmoOpElem *gzop,
|
||||
const wmEvent *event);
|
||||
|
||||
/* Callbacks. */
|
||||
|
||||
void WM_gizmo_set_fn_custom_modal(wmGizmo *gz, wmGizmoFnModal fn);
|
||||
|
||||
void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3]);
|
||||
/**
|
||||
* #wmGizmo.matrix utility, set the orientation by its Z axis.
|
||||
*/
|
||||
void WM_gizmo_set_matrix_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3]);
|
||||
/**
|
||||
* #wmGizmo.matrix utility, set the orientation by its Y/Z axis.
|
||||
*/
|
||||
void WM_gizmo_set_matrix_rotation_from_yz_axis(wmGizmo *gz,
|
||||
const float y_axis[3],
|
||||
const float z_axis[3]);
|
||||
|
||||
void WM_gizmo_set_matrix_offset_location(wmGizmo *gz, const float offset[3]);
|
||||
/**
|
||||
* #wmGizmo.matrix_offset utility, set the orientation by its Z axis.
|
||||
*/
|
||||
void WM_gizmo_set_matrix_offset_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3]);
|
||||
/**
|
||||
* #wmGizmo.matrix_offset utility, set the orientation by its Y/Z axis.
|
||||
*/
|
||||
void WM_gizmo_set_matrix_offset_rotation_from_yz_axis(wmGizmo *gz,
|
||||
const float y_axis[3],
|
||||
const float z_axis[3]);
|
||||
|
||||
void WM_gizmo_set_flag(wmGizmo *gz, int flag, bool enable);
|
||||
void WM_gizmo_set_scale(wmGizmo *gz, float scale);
|
||||
void WM_gizmo_set_line_width(wmGizmo *gz, float line_width);
|
||||
|
||||
void WM_gizmo_get_color(const wmGizmo *gz, float color[4]);
|
||||
void WM_gizmo_set_color(wmGizmo *gz, const float color[4]);
|
||||
void WM_gizmo_get_color_highlight(const wmGizmo *gz, float color_hi[4]);
|
||||
void WM_gizmo_set_color_highlight(wmGizmo *gz, const float color_hi[4]);
|
||||
|
||||
/**
|
||||
* Leaving values NULL use values from #wmGizmo.
|
||||
*/
|
||||
struct wmGizmoMatrixParams {
|
||||
const float (*matrix_space)[4];
|
||||
const float (*matrix_basis)[4];
|
||||
const float (*matrix_offset)[4];
|
||||
const float *scale_final;
|
||||
};
|
||||
|
||||
void WM_gizmo_calc_matrix_final_params(const wmGizmo *gz,
|
||||
const wmGizmoMatrixParams *params,
|
||||
float r_mat[4][4]);
|
||||
void WM_gizmo_calc_matrix_final_no_offset(const wmGizmo *gz, float r_mat[4][4]);
|
||||
|
||||
void WM_gizmo_calc_matrix_final(const wmGizmo *gz, float r_mat[4][4]);
|
||||
|
||||
/* Properties. */
|
||||
|
||||
void WM_gizmo_properties_create_ptr(PointerRNA *ptr, wmGizmoType *gzt);
|
||||
void WM_gizmo_properties_create(PointerRNA *ptr, StringRef gtstring);
|
||||
/**
|
||||
* Similar to #WM_gizmo_properties_create
|
||||
* except its uses ID properties used for key-maps and macros.
|
||||
*/
|
||||
void WM_gizmo_properties_alloc(PointerRNA **ptr, IDProperty **properties, StringRef gtstring);
|
||||
void WM_gizmo_properties_sanitize(PointerRNA *ptr, bool no_context);
|
||||
/**
|
||||
* Set all props to their default.
|
||||
*
|
||||
* \param do_update: Only update un-initialized props.
|
||||
*
|
||||
* \note There's nothing specific to gizmos here.
|
||||
* This could be made a general function.
|
||||
*/
|
||||
bool WM_gizmo_properties_default(PointerRNA *ptr, bool do_update);
|
||||
/**
|
||||
* Remove all props without #PROP_SKIP_SAVE.
|
||||
*/
|
||||
void WM_gizmo_properties_reset(wmGizmo *gz);
|
||||
void WM_gizmo_properties_clear(PointerRNA *ptr);
|
||||
void WM_gizmo_properties_free(PointerRNA *ptr);
|
||||
|
||||
/* `wm_gizmo_type.cc` */
|
||||
|
||||
const wmGizmoType *WM_gizmotype_find(StringRef idname, bool quiet);
|
||||
void WM_gizmotype_append(void (*gtfunc)(wmGizmoType *));
|
||||
void WM_gizmotype_append_ptr(void (*gtfunc)(wmGizmoType *, void *), void *userdata);
|
||||
bool WM_gizmotype_remove(bContext *C, Main *bmain, StringRef idname);
|
||||
void WM_gizmotype_remove_ptr(bContext *C, Main *bmain, wmGizmoType *gzt);
|
||||
/**
|
||||
* Free but don't remove from the global list.
|
||||
*/
|
||||
void WM_gizmotype_free_ptr(wmGizmoType *gzt);
|
||||
|
||||
/* `wm_gizmo_group_type.cc` */
|
||||
|
||||
wmGizmoGroupType *WM_gizmogrouptype_find(StringRef idname, bool quiet);
|
||||
wmGizmoGroupType *WM_gizmogrouptype_append(void (*wtfunc)(wmGizmoGroupType *));
|
||||
wmGizmoGroupType *WM_gizmogrouptype_append_ptr(void (*wtfunc)(wmGizmoGroupType *, void *),
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* Append and insert into a gizmo type-map.
|
||||
* This is most common for C gizmos which are enabled by default.
|
||||
*/
|
||||
wmGizmoGroupTypeRef *WM_gizmogrouptype_append_and_link(wmGizmoMapType *gzmap_type,
|
||||
void (*wtfunc)(wmGizmoGroupType *));
|
||||
|
||||
/* `wm_gizmo_map.cc` */
|
||||
|
||||
/* Dynamic Updates (for RNA runtime registration). */
|
||||
void WM_gizmoconfig_update_tag_group_type_init(wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt);
|
||||
void WM_gizmoconfig_update_tag_group_type_remove(wmGizmoMapType *gzmap_type,
|
||||
wmGizmoGroupType *gzgt);
|
||||
/**
|
||||
* Run in case new types have been added (runs often, early exit where possible).
|
||||
* Follows #WM_keyconfig_update conventions.
|
||||
*/
|
||||
void WM_gizmoconfig_update(Main *bmain);
|
||||
|
||||
void WM_gizmoconfig_update_tag_group_remove(wmGizmoMap *gzmap);
|
||||
|
||||
void WM_gizmoconfig_update_tag_reinit_all();
|
||||
|
||||
/* `wm_gizmo_target_props.cc`. */
|
||||
|
||||
wmGizmoProperty *WM_gizmo_target_property_find(wmGizmo *gz, const char *idname);
|
||||
|
||||
void WM_gizmo_target_property_def_rna_ptr(wmGizmo *gz,
|
||||
const wmGizmoPropertyType *gz_prop_type,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int index);
|
||||
void WM_gizmo_target_property_def_rna(
|
||||
wmGizmo *gz, const char *idname, PointerRNA *ptr, const char *propname, int index);
|
||||
|
||||
void WM_gizmo_target_property_def_func_ptr(wmGizmo *gz,
|
||||
const wmGizmoPropertyType *gz_prop_type,
|
||||
const wmGizmoPropertyFnParams *params);
|
||||
void WM_gizmo_target_property_def_func(wmGizmo *gz,
|
||||
const char *idname,
|
||||
const wmGizmoPropertyFnParams *params);
|
||||
|
||||
void WM_gizmo_target_property_clear_rna_ptr(wmGizmo *gz, const wmGizmoPropertyType *gz_prop_type);
|
||||
void WM_gizmo_target_property_clear_rna(wmGizmo *gz, const char *idname);
|
||||
|
||||
bool WM_gizmo_target_property_is_valid_any(const wmGizmo *gz);
|
||||
bool WM_gizmo_target_property_is_valid(const wmGizmoProperty *gz_prop);
|
||||
float WM_gizmo_target_property_float_get(const wmGizmo *gz, wmGizmoProperty *gz_prop);
|
||||
void WM_gizmo_target_property_float_set(bContext *C,
|
||||
const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop,
|
||||
float value);
|
||||
|
||||
void WM_gizmo_target_property_float_get_array(const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop,
|
||||
float *value);
|
||||
void WM_gizmo_target_property_float_set_array(bContext *C,
|
||||
const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop,
|
||||
const float *value);
|
||||
|
||||
bool WM_gizmo_target_property_float_range_get(const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop,
|
||||
float range[2]);
|
||||
|
||||
int WM_gizmo_target_property_array_length(const wmGizmo *gz, wmGizmoProperty *gz_prop);
|
||||
|
||||
/* Definitions. */
|
||||
|
||||
const wmGizmoPropertyType *WM_gizmotype_target_property_find(const wmGizmoType *gzt,
|
||||
const char *idname);
|
||||
void WM_gizmotype_target_property_def(wmGizmoType *gzt,
|
||||
const char *idname,
|
||||
int data_type,
|
||||
int array_length);
|
||||
|
||||
/* Utilities. */
|
||||
|
||||
void WM_gizmo_do_msg_notify_tag_refresh(bContext *C,
|
||||
wmMsgSubscribeKey *msg_key,
|
||||
wmMsgSubscribeValue *msg_val);
|
||||
/**
|
||||
* Runs on the "prepare draw" pass, drawing the region clears.
|
||||
*/
|
||||
void WM_gizmo_target_property_subscribe_all(wmGizmo *gz, wmMsgBus *mbus, ARegion *region);
|
||||
|
||||
/**
|
||||
* Auto-key function if auto-key is enabled.
|
||||
*/
|
||||
void WM_gizmo_target_property_anim_autokey(bContext *C,
|
||||
const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmoGroup. */
|
||||
|
||||
/* Callbacks for #wmGizmoGroupType::setup_keymap. */
|
||||
wmKeyMap *WM_gizmogroup_setup_keymap_generic(const wmGizmoGroupType *gzgt, wmKeyConfig *kc);
|
||||
wmKeyMap *WM_gizmogroup_setup_keymap_generic_select(const wmGizmoGroupType *gzgt, wmKeyConfig *kc);
|
||||
wmKeyMap *WM_gizmogroup_setup_keymap_generic_drag(const wmGizmoGroupType *gzgt, wmKeyConfig *kc);
|
||||
wmKeyMap *WM_gizmogroup_setup_keymap_generic_maybe_drag(const wmGizmoGroupType *gzgt,
|
||||
wmKeyConfig *kc);
|
||||
|
||||
/* Utility functions (not callbacks). */
|
||||
|
||||
wmKeyMap *WM_gizmo_keymap_generic_with_keyconfig(wmKeyConfig *kc);
|
||||
wmKeyMap *WM_gizmo_keymap_generic(wmWindowManager *wm);
|
||||
|
||||
wmKeyMap *WM_gizmo_keymap_generic_select_with_keyconfig(wmKeyConfig *kc);
|
||||
wmKeyMap *WM_gizmo_keymap_generic_select(wmWindowManager *wm);
|
||||
|
||||
wmKeyMap *WM_gizmo_keymap_generic_drag_with_keyconfig(wmKeyConfig *kc);
|
||||
wmKeyMap *WM_gizmo_keymap_generic_drag(wmWindowManager *wm);
|
||||
|
||||
wmKeyMap *WM_gizmo_keymap_generic_press_drag_with_keyconfig(wmKeyConfig *kc);
|
||||
wmKeyMap *WM_gizmo_keymap_generic_press_drag(wmWindowManager *wm);
|
||||
|
||||
/**
|
||||
* Drag or press depending on preference.
|
||||
*/
|
||||
wmKeyMap *WM_gizmo_keymap_generic_maybe_drag_with_keyconfig(wmKeyConfig *kc);
|
||||
wmKeyMap *WM_gizmo_keymap_generic_maybe_drag(wmWindowManager *wm);
|
||||
|
||||
void WM_gizmogroup_ensure_init(const bContext *C, wmGizmoGroup *gzgroup);
|
||||
|
||||
/* Sort utilities for use with `BLI_listbase_sort`. */
|
||||
|
||||
int WM_gizmo_cmp_temp_fl(const void *gz_a_ptr, const void *gz_b_ptr);
|
||||
int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmoMap. */
|
||||
|
||||
/**
|
||||
* Creates a gizmo-map with all registered gizmos for that type
|
||||
*/
|
||||
wmGizmoMap *WM_gizmomap_new_from_type(const wmGizmoMapType_Params *gzmap_params);
|
||||
/**
|
||||
* Re-create the gizmos (use when changing theme settings).
|
||||
*/
|
||||
void WM_gizmomap_reinit(wmGizmoMap *gzmap);
|
||||
const ListBaseT<wmGizmoGroup> *WM_gizmomap_group_list(wmGizmoMap *gzmap);
|
||||
wmGizmoGroup *WM_gizmomap_group_find(wmGizmoMap *gzmap, const char *idname);
|
||||
wmGizmoGroup *WM_gizmomap_group_find_ptr(wmGizmoMap *gzmap, const wmGizmoGroupType *gzgt);
|
||||
|
||||
eWM_GizmoFlagMapDrawStep WM_gizmomap_drawstep_from_gizmo_group(const wmGizmoGroup *gzgroup);
|
||||
void WM_gizmomap_tag_refresh_drawstep(wmGizmoMap *gzmap, eWM_GizmoFlagMapDrawStep drawstep);
|
||||
void WM_gizmomap_tag_refresh(wmGizmoMap *gzmap);
|
||||
|
||||
bool WM_gizmomap_tag_delay_refresh_for_tweak_check(wmGizmoMap *gzmap);
|
||||
|
||||
void WM_gizmomap_draw(wmGizmoMap *gzmap, const bContext *C, eWM_GizmoFlagMapDrawStep drawstep);
|
||||
void WM_gizmomap_add_handlers(ARegion *region, wmGizmoMap *gzmap);
|
||||
/**
|
||||
* Select/Deselect all selectable gizmos in \a gzmap.
|
||||
* \return if selection has changed.
|
||||
*
|
||||
* TODO: select all by type.
|
||||
*/
|
||||
bool WM_gizmomap_select_all(bContext *C, wmGizmoMap *gzmap, int action);
|
||||
bool WM_gizmomap_cursor_set(const wmGizmoMap *gzmap, wmWindow *win);
|
||||
void WM_gizmomap_message_subscribe(const bContext *C,
|
||||
wmGizmoMap *gzmap,
|
||||
ARegion *region,
|
||||
wmMsgBus *mbus);
|
||||
bool WM_gizmomap_is_any_selected(const wmGizmoMap *gzmap);
|
||||
wmGizmo *WM_gizmomap_get_modal(const wmGizmoMap *gzmap);
|
||||
|
||||
/**
|
||||
* \note We could use a callback to define bounds, for now just use matrix location.
|
||||
*/
|
||||
bool WM_gizmomap_minmax(
|
||||
const wmGizmoMap *gzmap, bool use_hidden, bool use_select, float r_min[3], float r_max[3]);
|
||||
|
||||
ARegion *WM_gizmomap_tooltip_init(
|
||||
bContext *C, ARegion *region, int *pass, double *pass_delay, bool *r_exit_on_event);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmoMapType. */
|
||||
|
||||
wmGizmoMapType *WM_gizmomaptype_find(const wmGizmoMapType_Params *gzmap_params);
|
||||
wmGizmoMapType *WM_gizmomaptype_ensure(const wmGizmoMapType_Params *gzmap_params);
|
||||
|
||||
wmGizmoGroupTypeRef *WM_gizmomaptype_group_find(wmGizmoMapType *gzmap_type, StringRef idname);
|
||||
wmGizmoGroupTypeRef *WM_gizmomaptype_group_find_ptr(wmGizmoMapType *gzmap_type,
|
||||
const wmGizmoGroupType *gzgt);
|
||||
/**
|
||||
* Use this for registering gizmos on startup.
|
||||
* For runtime, use #WM_gizmomaptype_group_link_runtime.
|
||||
*/
|
||||
wmGizmoGroupTypeRef *WM_gizmomaptype_group_link(wmGizmoMapType *gzmap_type, StringRef idname);
|
||||
wmGizmoGroupTypeRef *WM_gizmomaptype_group_link_ptr(wmGizmoMapType *gzmap_type,
|
||||
wmGizmoGroupType *gzgt);
|
||||
|
||||
void WM_gizmomaptype_group_init_runtime_keymap(const Main *bmain, wmGizmoGroupType *gzgt);
|
||||
void WM_gizmomaptype_group_init_runtime(const Main *bmain,
|
||||
wmGizmoMapType *gzmap_type,
|
||||
wmGizmoGroupType *gzgt);
|
||||
wmGizmoGroup *WM_gizmomaptype_group_init_runtime_with_region(wmGizmoMapType *gzmap_type,
|
||||
wmGizmoGroupType *gzgt,
|
||||
ARegion *region);
|
||||
void WM_gizmomaptype_group_unlink(bContext *C,
|
||||
Main *bmain,
|
||||
wmGizmoMapType *gzmap_type,
|
||||
const wmGizmoGroupType *gzgt);
|
||||
|
||||
/**
|
||||
* Unlike #WM_gizmomaptype_group_unlink this doesn't maintain correct state, simply free.
|
||||
*/
|
||||
void WM_gizmomaptype_group_free(wmGizmoGroupTypeRef *gzgt_ref);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #GizmoGroup. */
|
||||
|
||||
/* Add/Ensure/Remove (High level API). */
|
||||
|
||||
void WM_gizmo_group_type_add_ptr_ex(wmGizmoGroupType *gzgt, wmGizmoMapType *gzmap_type);
|
||||
void WM_gizmo_group_type_add_ptr(wmGizmoGroupType *gzgt);
|
||||
void WM_gizmo_group_type_add(StringRef idname);
|
||||
|
||||
bool WM_gizmo_group_type_ensure_ptr_ex(wmGizmoGroupType *gzgt, wmGizmoMapType *gzmap_type);
|
||||
bool WM_gizmo_group_type_ensure_ptr(wmGizmoGroupType *gzgt);
|
||||
bool WM_gizmo_group_type_ensure(StringRef idname);
|
||||
|
||||
/**
|
||||
* Call #WM_gizmo_group_type_free_ptr after to remove & free.
|
||||
*/
|
||||
void WM_gizmo_group_type_remove_ptr_ex(Main *bmain,
|
||||
wmGizmoGroupType *gzgt,
|
||||
wmGizmoMapType *gzmap_type);
|
||||
void WM_gizmo_group_type_remove_ptr(Main *bmain, wmGizmoGroupType *gzgt);
|
||||
void WM_gizmo_group_type_remove(Main *bmain, StringRef idname);
|
||||
|
||||
void WM_gizmo_group_type_unlink_delayed_ptr_ex(wmGizmoGroupType *gzgt, wmGizmoMapType *gzmap_type);
|
||||
void WM_gizmo_group_type_unlink_delayed_ptr(wmGizmoGroupType *gzgt);
|
||||
void WM_gizmo_group_type_unlink_delayed(StringRef idname);
|
||||
|
||||
void WM_gizmo_group_unlink_delayed_ptr_from_space(wmGizmoGroupType *gzgt,
|
||||
wmGizmoMapType *gzmap_type,
|
||||
ScrArea *area);
|
||||
|
||||
void WM_gizmo_group_type_free_ptr(wmGizmoGroupType *gzgt);
|
||||
bool WM_gizmo_group_type_free(StringRef idname);
|
||||
|
||||
/**
|
||||
* Has the result of unlinking and linking (re-initializes gizmo's).
|
||||
*/
|
||||
void WM_gizmo_group_type_reinit_ptr_ex(Main *bmain,
|
||||
wmGizmoGroupType *gzgt,
|
||||
wmGizmoMapType *gzmap_type);
|
||||
void WM_gizmo_group_type_reinit_ptr(Main *bmain, wmGizmoGroupType *gzgt);
|
||||
void WM_gizmo_group_type_reinit(Main *bmain, StringRef idname);
|
||||
|
||||
/* Utilities. */
|
||||
|
||||
bool WM_gizmo_group_is_modal(const wmGizmoGroup *gzgroup);
|
||||
|
||||
bool WM_gizmo_context_check_drawstep(const bContext *C, eWM_GizmoFlagMapDrawStep step);
|
||||
|
||||
void WM_gizmo_group_remove_by_tool(bContext *C,
|
||||
Main *bmain,
|
||||
const wmGizmoGroupType *gzgt,
|
||||
const bToolRef *tref);
|
||||
|
||||
void WM_gizmo_group_tag_remove(wmGizmoGroup *gzgroup);
|
||||
|
||||
/* Wrap Group Type Callbacks. */
|
||||
|
||||
bool WM_gizmo_group_type_poll(const bContext *C, const wmGizmoGroupType *gzgt);
|
||||
void WM_gizmo_group_refresh(const bContext *C, wmGizmoGroup *gzgroup);
|
||||
|
||||
} // namespace blender
|
||||
@@ -0,0 +1,535 @@
|
||||
/* SPDX-FileCopyrightText: 2016 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup wm
|
||||
*
|
||||
* \name Gizmo Types
|
||||
* \brief Gizmo defines for external use.
|
||||
*
|
||||
* Only included in WM_types.hh and lower level files.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_enum_flags.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#include "RNA_types.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
struct IDProperty;
|
||||
struct wmGizmo;
|
||||
struct wmGizmoType;
|
||||
struct wmGizmoGroup;
|
||||
struct wmGizmoGroupType;
|
||||
struct wmGizmoMap;
|
||||
struct wmGizmoMapType;
|
||||
struct wmGizmoProperty;
|
||||
struct wmGizmoPropertyType;
|
||||
struct wmKeyConfig;
|
||||
struct wmOperatorType;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Enum Typedef's. */
|
||||
|
||||
/**
|
||||
* #wmGizmo.state
|
||||
*/
|
||||
enum eWM_GizmoFlagState {
|
||||
/** While hovered. */
|
||||
WM_GIZMO_STATE_HIGHLIGHT = (1 << 0),
|
||||
/** While dragging. */
|
||||
WM_GIZMO_STATE_MODAL = (1 << 1),
|
||||
WM_GIZMO_STATE_SELECT = (1 << 2),
|
||||
};
|
||||
ENUM_OPERATORS(eWM_GizmoFlagState)
|
||||
|
||||
/**
|
||||
* #wmGizmo.flag
|
||||
* Flags for individual gizmos.
|
||||
*/
|
||||
enum eWM_GizmoFlag {
|
||||
/** Draw *only* while hovering. */
|
||||
WM_GIZMO_DRAW_HOVER = (1 << 0),
|
||||
/** Draw while dragging. */
|
||||
WM_GIZMO_DRAW_MODAL = (1 << 1),
|
||||
/** Draw an indicator for the current value while dragging. */
|
||||
WM_GIZMO_DRAW_VALUE = (1 << 2),
|
||||
WM_GIZMO_HIDDEN = (1 << 3),
|
||||
WM_GIZMO_HIDDEN_SELECT = (1 << 4),
|
||||
/** Ignore the key-map for this gizmo. */
|
||||
WM_GIZMO_HIDDEN_KEYMAP = (1 << 5),
|
||||
/**
|
||||
* When set 'scale_final' value also scales the offset.
|
||||
* Use when offset is to avoid screen-space overlap instead of absolute positioning. */
|
||||
WM_GIZMO_DRAW_OFFSET_SCALE = (1 << 6),
|
||||
/**
|
||||
* User should still use 'scale_final' for any handles and UI elements.
|
||||
* This simply skips scale when calculating the final matrix.
|
||||
* Needed when the gizmo needs to align with the interface underneath it. */
|
||||
WM_GIZMO_DRAW_NO_SCALE = (1 << 7),
|
||||
/**
|
||||
* Hide the cursor and lock its position while interacting with this gizmo.
|
||||
*/
|
||||
WM_GIZMO_MOVE_CURSOR = (1 << 8),
|
||||
/** Don't write into the depth buffer when selecting. */
|
||||
WM_GIZMO_SELECT_BACKGROUND = (1 << 9),
|
||||
|
||||
/** Use the active tools operator properties when running as an operator. */
|
||||
WM_GIZMO_OPERATOR_TOOL_INIT = (1 << 10),
|
||||
|
||||
/** Don't pass through events to other handlers
|
||||
* (allows click/drag not to have its events stolen by press events in other keymaps). */
|
||||
WM_GIZMO_EVENT_HANDLE_ALL = (1 << 11),
|
||||
|
||||
/** Don't use tool-tips for this gizmo (can be distracting). */
|
||||
WM_GIZMO_NO_TOOLTIP = (1 << 12),
|
||||
/** Push an undo step after each use of the gizmo. */
|
||||
WM_GIZMO_NEEDS_UNDO = (1 << 13),
|
||||
|
||||
/** This gizmo should be visually distinct and not shown grouped with other gizmos. */
|
||||
WM_GIZMO_NO_GROUPING = (1 << 14),
|
||||
};
|
||||
ENUM_OPERATORS(eWM_GizmoFlag);
|
||||
|
||||
/**
|
||||
* #wmGizmoGroupType.flag
|
||||
* Flags that influence the behavior of all gizmos in the group.
|
||||
*/
|
||||
enum eWM_GizmoFlagGroupTypeFlag {
|
||||
/** Mark gizmo-group as being 3D. */
|
||||
WM_GIZMOGROUPTYPE_3D = (1 << 0),
|
||||
/** Scale gizmos as 3D object that respects zoom (otherwise zoom independent draw size).
|
||||
* NOTE: currently only for 3D views, 2D support needs adding. */
|
||||
WM_GIZMOGROUPTYPE_SCALE = (1 << 1),
|
||||
/** Gizmos can be depth culled with scene objects (covered by other geometry - TODO). */
|
||||
WM_GIZMOGROUPTYPE_DEPTH_3D = (1 << 2),
|
||||
/** Gizmos can be selected. */
|
||||
WM_GIZMOGROUPTYPE_SELECT = (1 << 3),
|
||||
/** The gizmo group is to be kept (not removed on loading a new file for eg). */
|
||||
WM_GIZMOGROUPTYPE_PERSISTENT = (1 << 4),
|
||||
/**
|
||||
* Show all other gizmos when interacting.
|
||||
* Also show this group when another group is being interacted with.
|
||||
*/
|
||||
WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL = (1 << 5),
|
||||
|
||||
/** Don't draw this gizmo group when it is modal. */
|
||||
WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE = (1 << 6),
|
||||
|
||||
/**
|
||||
* When used with tool, only run when activating the tool,
|
||||
* instead of linking the gizmo while the tool is active.
|
||||
*
|
||||
* \warning this option has some limitations, we might even re-implement this differently.
|
||||
* Currently it's quite minimal so we can see how it works out.
|
||||
* The main issue is controlling how a gizmo is activated with a tool
|
||||
* when a tool can activate multiple operators based on the key-map.
|
||||
* We could even move the options into the key-map item.
|
||||
* ~ campbell. */
|
||||
WM_GIZMOGROUPTYPE_TOOL_INIT = (1 << 7),
|
||||
|
||||
/**
|
||||
* This gizmo type supports using the fall back tools keymap.
|
||||
* #wmGizmoGroup.use_tool_fallback will need to be set too.
|
||||
*
|
||||
* Often useful in combination with #WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK
|
||||
*/
|
||||
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP = (1 << 8),
|
||||
|
||||
/**
|
||||
* Use this from a gizmos refresh callback so we can postpone the refresh operation
|
||||
* until the tweak operation is finished.
|
||||
* Only do this when the group doesn't have a highlighted gizmo.
|
||||
*
|
||||
* The result for the user is tweak events delay the gizmo from flashing under the users cursor,
|
||||
* for selection operations. This means gizmos that use this check don't interfere
|
||||
* with click-drag events by popping up under the cursor and catching the drag-drag event.
|
||||
*/
|
||||
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK = (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,
|
||||
* however for VR it's sometimes needed.
|
||||
*/
|
||||
WM_GIZMOGROUPTYPE_VR_REDRAWS = (1 << 10),
|
||||
};
|
||||
|
||||
ENUM_OPERATORS(eWM_GizmoFlagGroupTypeFlag);
|
||||
|
||||
/**
|
||||
* #wmGizmoGroup.init_flag
|
||||
*/
|
||||
enum eWM_GizmoFlagGroupInitFlag {
|
||||
/** Gizmo-group has been initialized. */
|
||||
WM_GIZMOGROUP_INIT_SETUP = (1 << 0),
|
||||
WM_GIZMOGROUP_INIT_REFRESH = (1 << 1),
|
||||
};
|
||||
ENUM_OPERATORS(eWM_GizmoFlagGroupInitFlag)
|
||||
|
||||
/**
|
||||
* #wmGizmoMapType.type_update_flag
|
||||
* Gizmo-map type update flag
|
||||
*/
|
||||
enum eWM_GizmoFlagMapTypeUpdateFlag {
|
||||
/** A new type has been added, needs to be initialized for all views. */
|
||||
WM_GIZMOMAPTYPE_UPDATE_INIT = (1 << 0),
|
||||
WM_GIZMOMAPTYPE_UPDATE_REMOVE = (1 << 1),
|
||||
|
||||
/** Needed because keymap may be registered before and after window initialization.
|
||||
* So we need to keep track of keymap initialization separately. */
|
||||
WM_GIZMOMAPTYPE_KEYMAP_INIT = (1 << 2),
|
||||
};
|
||||
ENUM_OPERATORS(eWM_GizmoFlagMapTypeUpdateFlag)
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmo. */
|
||||
|
||||
/**
|
||||
* \brief Gizmo tweak flag.
|
||||
* Bit-flag passed to gizmo while tweaking.
|
||||
*
|
||||
* \note Gizmos are responsible for handling this #wmGizmo.modal callback.
|
||||
*/
|
||||
enum eWM_GizmoFlagTweak {
|
||||
/** Drag with extra precision (Shift). */
|
||||
WM_GIZMO_TWEAK_PRECISE = (1 << 0),
|
||||
/** Drag with snap enabled (Control). */
|
||||
WM_GIZMO_TWEAK_SNAP = (1 << 1),
|
||||
};
|
||||
|
||||
} // namespace blender
|
||||
|
||||
#include "wm_gizmo_fn.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
struct wmGizmoOpElem {
|
||||
wmOperatorType *type = nullptr;
|
||||
/** Operator properties if gizmo spawns and controls an operator,
|
||||
* or owner pointer if gizmo spawns and controls a property. */
|
||||
PointerRNA ptr = {};
|
||||
|
||||
bool is_redo = false;
|
||||
};
|
||||
|
||||
/** Gizmos are set per region by registering them on gizmo-maps. */
|
||||
struct wmGizmo {
|
||||
wmGizmo *next, *prev;
|
||||
|
||||
/** While we don't have a real type, use this to put type-like vars. */
|
||||
const wmGizmoType *type;
|
||||
|
||||
/** Overrides 'type->modal' when set.
|
||||
* Note that this is a workaround, remove if we can. */
|
||||
wmGizmoFnModal custom_modal;
|
||||
|
||||
/** Pointer back to group this gizmo is in (just for quick access). */
|
||||
wmGizmoGroup *parent_gzgroup;
|
||||
|
||||
/** Optional keymap to use for this gizmo (overrides #wmGizmoGroupType.keymap). */
|
||||
wmKeyMap *keymap;
|
||||
|
||||
void *py_instance;
|
||||
|
||||
/** Rna pointer to access properties. */
|
||||
PointerRNA *ptr;
|
||||
|
||||
/** Flags that influence the behavior or how the gizmos are drawn. */
|
||||
eWM_GizmoFlag flag;
|
||||
/** State flags (active, highlighted, selected). */
|
||||
eWM_GizmoFlagState state;
|
||||
|
||||
/** Optional ID for highlighting different parts of this gizmo.
|
||||
* -1 when unset, otherwise a valid index. (Used as index to 'op_data'). */
|
||||
int highlight_part;
|
||||
|
||||
/**
|
||||
* For gizmos that differentiate between click & drag,
|
||||
* use a different part for any drag events, -1 when unused.
|
||||
*/
|
||||
int drag_part;
|
||||
|
||||
/** Distance to bias this gizmo above others when picking
|
||||
* (in world-space, scaled by the gizmo scale - when used). */
|
||||
float select_bias;
|
||||
|
||||
/* Transformation of the gizmo in 2d or 3d space.
|
||||
* - Matrix axis are expected to be unit length (scale is applied after).
|
||||
* - Behavior when axis aren't orthogonal depends on each gizmo.
|
||||
* - Typically the +Z is the primary axis for gizmos to use.
|
||||
* - 'matrix[3]' must be used for location,
|
||||
* besides this it's up to the gizmos internal code how the
|
||||
* rotation components are used for drawing and interaction. */
|
||||
|
||||
/** The space this gizmo is being modified in. */
|
||||
float matrix_space[4][4];
|
||||
/** Transformation of this gizmo. */
|
||||
float matrix_basis[4][4];
|
||||
/** Custom offset from origin. */
|
||||
float matrix_offset[4][4];
|
||||
/** Runtime property, set the scale while drawing on the viewport. */
|
||||
float scale_final;
|
||||
/** User defined scale, in addition to the original one. */
|
||||
float scale_basis;
|
||||
/** User defined width for line drawing. */
|
||||
float line_width;
|
||||
/** Gizmo colors (uses default fallbacks if not defined). */
|
||||
float color[4], color_hi[4];
|
||||
|
||||
/** Data used during interaction. */
|
||||
void *interaction_data;
|
||||
|
||||
/** Operator to spawn when activating the gizmo (overrides property editing),
|
||||
* an array of items (aligned with #wmGizmo.highlight_part). */
|
||||
Vector<wmGizmoOpElem, 4> op_data;
|
||||
|
||||
IDProperty *properties;
|
||||
|
||||
/* TODO: Once wmGizmo itself gets an actual constructor, this can most likely become a
|
||||
* `Array`, since length is defined by the gizmo type. */
|
||||
Vector<wmGizmoProperty, 0> target_properties;
|
||||
|
||||
/** Redraw tag. */
|
||||
bool do_draw;
|
||||
|
||||
/** Temporary data (assume dirty). */
|
||||
union {
|
||||
float f;
|
||||
} temp;
|
||||
};
|
||||
|
||||
/** Similar to #PropertyElemRNA, but has an identifier. */
|
||||
struct wmGizmoProperty {
|
||||
const wmGizmoPropertyType *type = nullptr;
|
||||
|
||||
PointerRNA ptr = PointerRNA_NULL;
|
||||
PropertyRNA *prop = nullptr;
|
||||
int index = -1;
|
||||
|
||||
/* Optional functions for converting to/from RNA. */
|
||||
struct {
|
||||
wmGizmoPropertyFnGet value_get_fn = nullptr;
|
||||
wmGizmoPropertyFnSet value_set_fn = nullptr;
|
||||
wmGizmoPropertyFnRangeGet range_get_fn = nullptr;
|
||||
wmGizmoPropertyFnFree free_fn = nullptr;
|
||||
wmGizmoPropertyFnForeachRNAProp foreach_rna_prop_fn = nullptr;
|
||||
void *user_data = nullptr;
|
||||
} custom_func = {};
|
||||
};
|
||||
|
||||
struct wmGizmoPropertyType {
|
||||
wmGizmoPropertyType *next, *prev;
|
||||
/** #PropertyType, typically #PROP_FLOAT. */
|
||||
int data_type;
|
||||
int array_length;
|
||||
|
||||
/** Index within #wmGizmoType. */
|
||||
int index_in_type;
|
||||
|
||||
/** Over allocate. */
|
||||
char idname[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple utility wrapper for storing a single gizmo as wmGizmoGroup.customdata (which gets freed).
|
||||
*/
|
||||
struct wmGizmoWrapper {
|
||||
wmGizmo *gizmo;
|
||||
};
|
||||
|
||||
struct wmGizmoMapType_Params {
|
||||
short spaceid;
|
||||
short regionid;
|
||||
};
|
||||
|
||||
struct wmGizmoType {
|
||||
|
||||
const char *idname; /* #MAX_NAME. */
|
||||
|
||||
/** Set to `sizeof(wmGizmo)` or larger for instances of this type,
|
||||
* use so we can cast to other types without the hassle of a custom-data pointer. */
|
||||
uint struct_size;
|
||||
|
||||
/** Initialize struct (calloc'd 'struct_size' region). */
|
||||
wmGizmoFnSetup setup;
|
||||
|
||||
/** Draw gizmo. */
|
||||
wmGizmoFnDraw draw;
|
||||
|
||||
/** Determines 3d intersection by rendering the gizmo in a selection routine. */
|
||||
wmGizmoFnDrawSelect draw_select;
|
||||
|
||||
/** Determine if the mouse intersects with the gizmo.
|
||||
* The calculation should be done in the callback itself, -1 for no selection. */
|
||||
wmGizmoFnTestSelect test_select;
|
||||
|
||||
/** Handler used by the gizmo. Usually handles interaction tied to a gizmo type. */
|
||||
wmGizmoFnModal modal;
|
||||
|
||||
/** Gizmo-specific handler to update gizmo attributes based on the property value. */
|
||||
wmGizmoFnPropertyUpdate property_update;
|
||||
|
||||
/**
|
||||
* Returns the final transformation which may be different from the 'matrix',
|
||||
* depending on the gizmo.
|
||||
* Notes:
|
||||
* - Scale isn't applied (wmGizmo.scale/user_scale).
|
||||
* - Offset isn't applied (wmGizmo.matrix_offset).
|
||||
*/
|
||||
wmGizmoFnMatrixBasisGet matrix_basis_get;
|
||||
|
||||
/**
|
||||
* Returns screen-space bounding box in the window space
|
||||
* (compatible with #wmEvent.xy).
|
||||
*
|
||||
* Used for tool-tip placement (otherwise the cursor location is used).
|
||||
*/
|
||||
wmGizmoFnScreenBoundsGet screen_bounds_get;
|
||||
|
||||
/** Activate a gizmo state when the user clicks on it. */
|
||||
wmGizmoFnInvoke invoke;
|
||||
|
||||
/** Called when gizmo tweaking is done - used to free data and reset property when canceling. */
|
||||
wmGizmoFnExit exit;
|
||||
|
||||
wmGizmoFnCursorGet cursor_get;
|
||||
|
||||
/** Called when gizmo selection state changes. */
|
||||
wmGizmoFnSelectRefresh select_refresh;
|
||||
|
||||
/** Free data (not the gizmo itself), use when the gizmo allocates its own members. */
|
||||
wmGizmoFnFree free;
|
||||
|
||||
/** RNA for properties. */
|
||||
StructRNA *srna;
|
||||
|
||||
/** RNA integration. */
|
||||
ExtensionRNA rna_ext;
|
||||
|
||||
ListBaseT<wmGizmoPropertyType> target_property_defs;
|
||||
int target_property_defs_len;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmoGroup. */
|
||||
|
||||
/** Factory class for a gizmo-group type, gets called every time a new area is spawned. */
|
||||
struct wmGizmoGroupTypeRef {
|
||||
wmGizmoGroupTypeRef *next, *prev;
|
||||
wmGizmoGroupType *type;
|
||||
};
|
||||
|
||||
/** Factory class for a gizmo-group type, gets called every time a new area is spawned. */
|
||||
struct wmGizmoGroupType {
|
||||
const char *idname; /* #MAX_NAME. */
|
||||
/** Gizmo-group name - displayed in UI (keymap editor). */
|
||||
const char *name;
|
||||
/** Optional, see: #wmOwnerID. */
|
||||
char owner_id[128];
|
||||
|
||||
/** Optional, used when drawing a group background with `draw_background`. */
|
||||
float4 background_color;
|
||||
float4 outline_color;
|
||||
|
||||
/** Poll if gizmo-map should be visible. */
|
||||
wmGizmoGroupFnPoll poll;
|
||||
/** Initially create gizmos and set permanent data - stuff you only need to do once. */
|
||||
wmGizmoGroupFnInit setup;
|
||||
/** Refresh data, only called if recreate flag is set (WM_gizmomap_tag_refresh). */
|
||||
wmGizmoGroupFnRefresh refresh;
|
||||
/** Refresh data for drawing, called before each redraw. */
|
||||
wmGizmoGroupFnDrawPrepare draw_prepare;
|
||||
/** Optionally draw the background of the group itself. */
|
||||
wmGizmoGroupFnDrawBackground draw_background;
|
||||
/** Initialize data for before invoke. */
|
||||
wmGizmoGroupFnInvokePrepare invoke_prepare;
|
||||
|
||||
/** Keymap init callback for this gizmo-group (optional),
|
||||
* will fall back to default tweak keymap when left NULL. */
|
||||
wmGizmoGroupFnSetupKeymap setup_keymap;
|
||||
|
||||
/** Optionally subscribe to wmMsgBus events,
|
||||
* these are calculated automatically from RNA properties,
|
||||
* only needed if gizmos depend indirectly on properties. */
|
||||
wmGizmoGroupFnMsgBusSubscribe message_subscribe;
|
||||
|
||||
/** Keymap created with callback from above. */
|
||||
wmKeyMap *keymap;
|
||||
/** Only for convenient removal. */
|
||||
wmKeyConfig *keyconf;
|
||||
|
||||
/* NOTE: currently gizmo-group instances don't store properties,
|
||||
* they're kept in the tool properties. */
|
||||
|
||||
/** RNA for properties. */
|
||||
StructRNA *srna;
|
||||
|
||||
/** RNA integration. */
|
||||
ExtensionRNA rna_ext;
|
||||
|
||||
eWM_GizmoFlagGroupTypeFlag flag;
|
||||
|
||||
/** So we know which group type to update. */
|
||||
eWM_GizmoFlagMapTypeUpdateFlag type_update_flag;
|
||||
|
||||
/** Same as gizmo-maps, so registering/unregistering goes to the correct region. */
|
||||
wmGizmoMapType_Params gzmap_params;
|
||||
|
||||
/**
|
||||
* Number of #wmGizmoGroup instances.
|
||||
* Decremented when 'tag_remove' is set, or when removed.
|
||||
*/
|
||||
int users;
|
||||
};
|
||||
|
||||
struct wmGizmoGroup {
|
||||
wmGizmoGroup *next, *prev;
|
||||
|
||||
wmGizmoGroupType *type;
|
||||
ListBaseT<wmGizmo> gizmos;
|
||||
|
||||
wmGizmoMap *parent_gzmap;
|
||||
|
||||
/** Python stores the class instance here. */
|
||||
void *py_instance;
|
||||
|
||||
/** Has the same result as hiding all gizmos individually. */
|
||||
union {
|
||||
/** Reasons for hiding. */
|
||||
struct {
|
||||
uint delay_refresh_for_tweak : 1;
|
||||
};
|
||||
/** All, when we only want to check if any are hidden. */
|
||||
uint any;
|
||||
} hide;
|
||||
|
||||
bool tag_remove;
|
||||
|
||||
void *customdata;
|
||||
/** For freeing customdata from above. */
|
||||
void (*customdata_free)(void *);
|
||||
eWM_GizmoFlagGroupInitFlag init_flag;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmoMap. */
|
||||
|
||||
/**
|
||||
* Pass a value of this enum to #WM_gizmomap_draw to tell it what to draw.
|
||||
*/
|
||||
enum eWM_GizmoFlagMapDrawStep {
|
||||
/** Draw 2D gizmo-groups (#WM_GIZMOGROUPTYPE_3D not set). */
|
||||
WM_GIZMOMAP_DRAWSTEP_2D = 0,
|
||||
/** Draw 3D gizmo-groups (#WM_GIZMOGROUPTYPE_3D set). */
|
||||
WM_GIZMOMAP_DRAWSTEP_3D,
|
||||
};
|
||||
#define WM_GIZMOMAP_DRAWSTEP_MAX 2
|
||||
|
||||
} // namespace blender
|
||||
@@ -0,0 +1,744 @@
|
||||
/* SPDX-FileCopyrightText: 2014 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup wm
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_define.hh"
|
||||
#include "RNA_prototypes.hh"
|
||||
|
||||
#include "BKE_global.hh"
|
||||
#include "BKE_idprop.hh"
|
||||
#include "BKE_main.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_toolsystem.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "ED_screen.hh"
|
||||
#include "ED_view3d.hh"
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
# include "BPY_extern.hh"
|
||||
#endif
|
||||
|
||||
/* Own includes. */
|
||||
#include "wm_gizmo_intern.hh"
|
||||
#include "wm_gizmo_wmapi.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
static void wm_gizmo_register(wmGizmoGroup *gzgroup, wmGizmo *gz);
|
||||
|
||||
/**
|
||||
* \note Follow #wm_operator_create convention.
|
||||
*/
|
||||
static wmGizmo *wm_gizmo_create(const wmGizmoType *gzt, PointerRNA *properties)
|
||||
{
|
||||
BLI_assert(gzt != nullptr);
|
||||
BLI_assert(gzt->struct_size >= sizeof(wmGizmo));
|
||||
|
||||
/* FIXME: Old C-style allocation is not trivial to port to C++ here, because actual allocation
|
||||
* depends on the 'subtype' of gizmo. The whole gizmo type hierarchy should probably be moved to
|
||||
* proper C++ virtual inheritance at some point. */
|
||||
wmGizmo *gz = static_cast<wmGizmo *>(MEM_new_zeroed(gzt->struct_size, __func__));
|
||||
new (gz) wmGizmo();
|
||||
gz->type = gzt;
|
||||
|
||||
/* Initialize properties, either copy or create. */
|
||||
gz->ptr = MEM_new<PointerRNA>("wmGizmoPtrRNA");
|
||||
if (properties && properties->data) {
|
||||
gz->properties = IDP_CopyProperty(static_cast<const IDProperty *>(properties->data));
|
||||
}
|
||||
else {
|
||||
gz->properties = bke::idprop::create_group("wmGizmoProperties").release();
|
||||
}
|
||||
*gz->ptr = RNA_pointer_create_discrete(
|
||||
static_cast<ID *>(G_MAIN->wm.first), gzt->srna, gz->properties);
|
||||
|
||||
WM_gizmo_properties_sanitize(gz->ptr, false);
|
||||
|
||||
unit_m4(gz->matrix_space);
|
||||
unit_m4(gz->matrix_basis);
|
||||
unit_m4(gz->matrix_offset);
|
||||
|
||||
gz->drag_part = -1;
|
||||
|
||||
/* Only ensure expected size for the target properties array. Actual initialization of these
|
||||
* happen separately (see e.g. #WM_gizmo_target_property_def_rna and related). */
|
||||
gz->target_properties.resize(gzt->target_property_defs_len);
|
||||
|
||||
return gz;
|
||||
}
|
||||
|
||||
wmGizmo *WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties)
|
||||
{
|
||||
wmGizmo *gz = wm_gizmo_create(gzt, properties);
|
||||
|
||||
wm_gizmo_register(gzgroup, gz);
|
||||
|
||||
if (gz->type->setup != nullptr) {
|
||||
gz->type->setup(gz);
|
||||
}
|
||||
|
||||
return gz;
|
||||
}
|
||||
|
||||
wmGizmo *WM_gizmo_new(const StringRef idname, wmGizmoGroup *gzgroup, PointerRNA *properties)
|
||||
{
|
||||
const wmGizmoType *gzt = WM_gizmotype_find(idname, false);
|
||||
return WM_gizmo_new_ptr(gzt, gzgroup, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize default values and allocate needed memory for members.
|
||||
*/
|
||||
static void gizmo_init(wmGizmo *gz)
|
||||
{
|
||||
const float color_default[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
gz->scale_basis = 1.0f;
|
||||
gz->line_width = 1.0f;
|
||||
|
||||
/* Defaults. */
|
||||
copy_v4_v4(gz->color, color_default);
|
||||
copy_v4_v4(gz->color_hi, color_default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register \a gizmo.
|
||||
*
|
||||
* \note Not to be confused with type registration from RNA.
|
||||
*/
|
||||
static void wm_gizmo_register(wmGizmoGroup *gzgroup, wmGizmo *gz)
|
||||
{
|
||||
gizmo_init(gz);
|
||||
wm_gizmogroup_gizmo_register(gzgroup, gz);
|
||||
}
|
||||
|
||||
void WM_gizmo_free(wmGizmo *gz)
|
||||
{
|
||||
if (gz->type->free != nullptr) {
|
||||
gz->type->free(gz);
|
||||
}
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
if (gz->py_instance) {
|
||||
/* Do this first in case there are any `__del__` functions or
|
||||
* similar that use properties. */
|
||||
BPY_DECREF_RNA_INVALIDATE(gz->py_instance);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (wmGizmoOpElem &gzop : gz->op_data) {
|
||||
WM_operator_properties_free(&gzop.ptr);
|
||||
}
|
||||
|
||||
if (gz->ptr != nullptr) {
|
||||
WM_gizmo_properties_free(gz->ptr);
|
||||
MEM_delete(gz->ptr);
|
||||
}
|
||||
|
||||
for (wmGizmoProperty &gz_prop : gz->target_properties) {
|
||||
if (gz_prop.custom_func.free_fn) {
|
||||
gz_prop.custom_func.free_fn(gz, &gz_prop);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_delete(gz);
|
||||
}
|
||||
|
||||
void WM_gizmo_unlink(ListBaseT<wmGizmo> *gizmolist, wmGizmoMap *gzmap, wmGizmo *gz, bContext *C)
|
||||
{
|
||||
if (gz->state & WM_GIZMO_STATE_HIGHLIGHT) {
|
||||
wm_gizmomap_highlight_set(gzmap, C, nullptr, 0);
|
||||
}
|
||||
if (gz->state & WM_GIZMO_STATE_MODAL) {
|
||||
wm_gizmomap_modal_set(gzmap, C, gz, nullptr, false);
|
||||
}
|
||||
/* Unlink instead of setting so we don't run callbacks. */
|
||||
if (gz->state & WM_GIZMO_STATE_SELECT) {
|
||||
WM_gizmo_select_unlink(gzmap, gz);
|
||||
}
|
||||
|
||||
if (gizmolist) {
|
||||
BLI_remlink(gizmolist, gz);
|
||||
}
|
||||
|
||||
BLI_assert(gzmap->gzmap_context.highlight != gz);
|
||||
BLI_assert(gzmap->gzmap_context.modal != gz);
|
||||
|
||||
WM_gizmo_free(gz);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gizmo Creation API
|
||||
*
|
||||
* API for defining data on gizmo creation.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
wmGizmoOpElem *WM_gizmo_operator_get(wmGizmo *gz, int part_index)
|
||||
{
|
||||
if ((part_index >= 0) && (part_index < gz->op_data.size())) {
|
||||
return &gz->op_data[part_index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PointerRNA *WM_gizmo_operator_set(wmGizmo *gz,
|
||||
int part_index,
|
||||
wmOperatorType *ot,
|
||||
IDProperty *properties)
|
||||
{
|
||||
BLI_assert(part_index < 255);
|
||||
if (part_index >= gz->op_data.size()) {
|
||||
gz->op_data.resize(part_index + 1);
|
||||
}
|
||||
wmGizmoOpElem &gzop = gz->op_data[part_index];
|
||||
gzop.type = ot;
|
||||
|
||||
if (gzop.ptr.data) {
|
||||
WM_operator_properties_free(&gzop.ptr);
|
||||
}
|
||||
gzop.ptr = WM_operator_properties_create_ptr(ot);
|
||||
|
||||
if (properties) {
|
||||
gzop.ptr.data = properties;
|
||||
}
|
||||
|
||||
return &gzop.ptr;
|
||||
}
|
||||
|
||||
wmOperatorStatus WM_gizmo_operator_invoke(bContext *C,
|
||||
wmGizmo *gz,
|
||||
wmGizmoOpElem *gzop,
|
||||
const wmEvent *event)
|
||||
{
|
||||
if (gz->flag & WM_GIZMO_OPERATOR_TOOL_INIT) {
|
||||
/* Merge tool-settings into the gizmo properties. */
|
||||
PointerRNA tref_ptr;
|
||||
bToolRef *tref = WM_toolsystem_ref_from_context(C);
|
||||
if (tref && WM_toolsystem_ref_properties_get_from_operator(tref, gzop->type, &tref_ptr)) {
|
||||
if (gzop->ptr.data == nullptr) {
|
||||
gzop->ptr.data = bke::idprop::create_group("wmOperatorProperties").release();
|
||||
}
|
||||
IDP_MergeGroup(static_cast<IDProperty *>(gzop->ptr.data),
|
||||
static_cast<const IDProperty *>(tref_ptr.data),
|
||||
false);
|
||||
}
|
||||
}
|
||||
return WM_operator_name_call_ptr(
|
||||
C, gzop->type, wm::OpCallContext::InvokeDefault, &gzop->ptr, event);
|
||||
}
|
||||
|
||||
static void wm_gizmo_set_matrix_rotation_from_z_axis__internal(float matrix[4][4],
|
||||
const float z_axis[3])
|
||||
{
|
||||
/* Old code, seems we can use simpler method. */
|
||||
#if 0
|
||||
const float z_global[3] = {0.0f, 0.0f, 1.0f};
|
||||
float rot[3][3];
|
||||
|
||||
rotation_between_vecs_to_mat3(rot, z_global, z_axis);
|
||||
copy_v3_v3(matrix[0], rot[0]);
|
||||
copy_v3_v3(matrix[1], rot[1]);
|
||||
copy_v3_v3(matrix[2], rot[2]);
|
||||
#else
|
||||
normalize_v3_v3(matrix[2], z_axis);
|
||||
ortho_basis_v3v3_v3(matrix[0], matrix[1], matrix[2]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void wm_gizmo_set_matrix_rotation_from_yz_axis__internal(float matrix[4][4],
|
||||
const float y_axis[3],
|
||||
const float z_axis[3])
|
||||
{
|
||||
normalize_v3_v3(matrix[1], y_axis);
|
||||
normalize_v3_v3(matrix[2], z_axis);
|
||||
cross_v3_v3v3(matrix[0], matrix[1], matrix[2]);
|
||||
normalize_v3(matrix[0]);
|
||||
}
|
||||
|
||||
void WM_gizmo_set_matrix_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
|
||||
{
|
||||
wm_gizmo_set_matrix_rotation_from_z_axis__internal(gz->matrix_basis, z_axis);
|
||||
}
|
||||
void WM_gizmo_set_matrix_rotation_from_yz_axis(wmGizmo *gz,
|
||||
const float y_axis[3],
|
||||
const float z_axis[3])
|
||||
{
|
||||
wm_gizmo_set_matrix_rotation_from_yz_axis__internal(gz->matrix_basis, y_axis, z_axis);
|
||||
}
|
||||
void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3])
|
||||
{
|
||||
copy_v3_v3(gz->matrix_basis[3], origin);
|
||||
}
|
||||
|
||||
void WM_gizmo_set_matrix_offset_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
|
||||
{
|
||||
wm_gizmo_set_matrix_rotation_from_z_axis__internal(gz->matrix_offset, z_axis);
|
||||
}
|
||||
void WM_gizmo_set_matrix_offset_rotation_from_yz_axis(wmGizmo *gz,
|
||||
const float y_axis[3],
|
||||
const float z_axis[3])
|
||||
{
|
||||
wm_gizmo_set_matrix_rotation_from_yz_axis__internal(gz->matrix_offset, y_axis, z_axis);
|
||||
}
|
||||
void WM_gizmo_set_matrix_offset_location(wmGizmo *gz, const float offset[3])
|
||||
{
|
||||
copy_v3_v3(gz->matrix_offset[3], offset);
|
||||
}
|
||||
|
||||
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
gz->flag |= eWM_GizmoFlag(flag);
|
||||
}
|
||||
else {
|
||||
gz->flag &= ~eWM_GizmoFlag(flag);
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmo_set_scale(wmGizmo *gz, const float scale)
|
||||
{
|
||||
gz->scale_basis = scale;
|
||||
}
|
||||
|
||||
void WM_gizmo_set_line_width(wmGizmo *gz, const float line_width)
|
||||
{
|
||||
gz->line_width = line_width;
|
||||
}
|
||||
|
||||
void WM_gizmo_get_color(const wmGizmo *gz, float color[4])
|
||||
{
|
||||
copy_v4_v4(color, gz->color);
|
||||
}
|
||||
void WM_gizmo_set_color(wmGizmo *gz, const float color[4])
|
||||
{
|
||||
copy_v4_v4(gz->color, color);
|
||||
}
|
||||
|
||||
void WM_gizmo_get_color_highlight(const wmGizmo *gz, float color_hi[4])
|
||||
{
|
||||
copy_v4_v4(color_hi, gz->color_hi);
|
||||
}
|
||||
void WM_gizmo_set_color_highlight(wmGizmo *gz, const float color_hi[4])
|
||||
{
|
||||
copy_v4_v4(gz->color_hi, color_hi);
|
||||
}
|
||||
|
||||
/** \} */ /* Gizmo Creation API. */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gizmo Callback Assignment
|
||||
* \{ */
|
||||
|
||||
void WM_gizmo_set_fn_custom_modal(wmGizmo *gz, wmGizmoFnModal fn)
|
||||
{
|
||||
gz->custom_modal = fn;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
bool wm_gizmo_select_set_ex(
|
||||
wmGizmoMap *gzmap, wmGizmo *gz, bool select, bool use_array, bool use_callback)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (select) {
|
||||
if ((gz->state & WM_GIZMO_STATE_SELECT) == 0) {
|
||||
if (use_array) {
|
||||
wm_gizmomap_select_array_push_back(gzmap, gz);
|
||||
}
|
||||
gz->state |= WM_GIZMO_STATE_SELECT;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (gz->state & WM_GIZMO_STATE_SELECT) {
|
||||
if (use_array) {
|
||||
wm_gizmomap_select_array_remove(gzmap, gz);
|
||||
}
|
||||
gz->state &= ~WM_GIZMO_STATE_SELECT;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* In the case of unlinking we only want to remove from the array
|
||||
* and not write to the external state. */
|
||||
if (use_callback && changed) {
|
||||
if (gz->type->select_refresh) {
|
||||
gz->type->select_refresh(gz);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool WM_gizmo_select_unlink(wmGizmoMap *gzmap, wmGizmo *gz)
|
||||
{
|
||||
return wm_gizmo_select_set_ex(gzmap, gz, false, true, false);
|
||||
}
|
||||
|
||||
bool WM_gizmo_select_set(wmGizmoMap *gzmap, wmGizmo *gz, bool select)
|
||||
{
|
||||
return wm_gizmo_select_set_ex(gzmap, gz, select, true, true);
|
||||
}
|
||||
|
||||
bool WM_gizmo_highlight_set(wmGizmoMap *gzmap, wmGizmo *gz)
|
||||
{
|
||||
return wm_gizmomap_highlight_set(gzmap, nullptr, gz, gz ? gz->highlight_part : 0);
|
||||
}
|
||||
|
||||
bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz)
|
||||
{
|
||||
if (WM_gizmo_select_set(gzmap, gz, true)) {
|
||||
wm_gizmomap_highlight_set(gzmap, C, gz, gz->highlight_part);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WM_gizmo_modal_set_from_setup(
|
||||
wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, int part_index, const wmEvent *event)
|
||||
{
|
||||
gz->highlight_part = part_index;
|
||||
WM_gizmo_highlight_set(gzmap, gz);
|
||||
if (false) {
|
||||
wm_gizmomap_modal_set(gzmap, C, gz, event, true);
|
||||
}
|
||||
else {
|
||||
/* WEAK: but it works. */
|
||||
WM_operator_name_call(
|
||||
C, "GIZMOGROUP_OT_gizmo_tweak", wm::OpCallContext::InvokeDefault, nullptr, event);
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmo_modal_set_while_modal(wmGizmoMap *gzmap,
|
||||
bContext *C,
|
||||
wmGizmo *gz,
|
||||
const wmEvent *event)
|
||||
{
|
||||
if (gzmap->gzmap_context.modal) {
|
||||
wm_gizmomap_modal_set(gzmap, C, gzmap->gzmap_context.modal, event, false);
|
||||
}
|
||||
|
||||
if (gz) {
|
||||
wm_gizmo_calculate_scale(gz, C);
|
||||
|
||||
/* Set `highlight_part` to -1 to skip operator invocation. */
|
||||
const int highlight_part = gz->highlight_part;
|
||||
gz->highlight_part = -1;
|
||||
wm_gizmomap_modal_set(gzmap, C, gz, event, true);
|
||||
gz->highlight_part = highlight_part;
|
||||
}
|
||||
}
|
||||
|
||||
void wm_gizmo_calculate_scale(wmGizmo *gz, const bContext *C)
|
||||
{
|
||||
const RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
float scale = UI_SCALE_FAC;
|
||||
|
||||
if ((gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_SCALE) == 0) {
|
||||
scale *= U.gizmo_size;
|
||||
if (rv3d) {
|
||||
/* #ED_view3d_pixel_size includes #U.pixelsize, remove it. */
|
||||
float matrix_world[4][4];
|
||||
if (gz->type->matrix_basis_get) {
|
||||
float matrix_basis[4][4];
|
||||
gz->type->matrix_basis_get(gz, matrix_basis);
|
||||
mul_m4_m4m4(matrix_world, gz->matrix_space, matrix_basis);
|
||||
}
|
||||
else {
|
||||
mul_m4_m4m4(matrix_world, gz->matrix_space, gz->matrix_basis);
|
||||
}
|
||||
|
||||
/* Exclude matrix_offset from scale. */
|
||||
scale *= ED_view3d_pixel_size_no_ui_scale(rv3d, matrix_world[3]);
|
||||
}
|
||||
}
|
||||
|
||||
gz->scale_final = gz->scale_basis * scale;
|
||||
}
|
||||
|
||||
static void gizmo_update_prop_data(wmGizmo *gz)
|
||||
{
|
||||
/* Gizmo property might have been changed, so update gizmo. */
|
||||
if (gz->type->property_update) {
|
||||
for (wmGizmoProperty &gz_prop : gz->target_properties) {
|
||||
if (WM_gizmo_target_property_is_valid(&gz_prop)) {
|
||||
gz->type->property_update(gz, &gz_prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wm_gizmo_update(wmGizmo *gz, const bContext *C, const bool refresh_map)
|
||||
{
|
||||
if (refresh_map) {
|
||||
gizmo_update_prop_data(gz);
|
||||
}
|
||||
wm_gizmo_calculate_scale(gz, C);
|
||||
}
|
||||
|
||||
int wm_gizmo_is_visible(wmGizmo *gz)
|
||||
{
|
||||
if (gz->flag & WM_GIZMO_HIDDEN) {
|
||||
return 0;
|
||||
}
|
||||
if ((gz->state & WM_GIZMO_STATE_MODAL) &&
|
||||
!(gz->flag & (WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_VALUE)))
|
||||
{
|
||||
/* Don't draw while modal (dragging). */
|
||||
return 0;
|
||||
}
|
||||
if ((gz->flag & WM_GIZMO_DRAW_HOVER) && !(gz->state & WM_GIZMO_STATE_HIGHLIGHT) &&
|
||||
!(gz->state & WM_GIZMO_STATE_SELECT)) /* Still draw selected gizmos. */
|
||||
{
|
||||
/* Update but don't draw. */
|
||||
return WM_GIZMO_IS_VISIBLE_UPDATE;
|
||||
}
|
||||
|
||||
return WM_GIZMO_IS_VISIBLE_UPDATE | WM_GIZMO_IS_VISIBLE_DRAW;
|
||||
}
|
||||
|
||||
void WM_gizmo_calc_matrix_final_params(const wmGizmo *gz,
|
||||
const wmGizmoMatrixParams *params,
|
||||
float r_mat[4][4])
|
||||
{
|
||||
const float (*const matrix_space)[4] = params->matrix_space ? params->matrix_space :
|
||||
gz->matrix_space;
|
||||
const float (*const matrix_basis)[4] = params->matrix_basis ? params->matrix_basis :
|
||||
gz->matrix_basis;
|
||||
const float (*const matrix_offset)[4] = params->matrix_offset ? params->matrix_offset :
|
||||
gz->matrix_offset;
|
||||
const float *scale_final = params->scale_final ? params->scale_final : &gz->scale_final;
|
||||
|
||||
float final_matrix[4][4];
|
||||
if (params->matrix_basis == nullptr && gz->type->matrix_basis_get) {
|
||||
gz->type->matrix_basis_get(gz, final_matrix);
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(final_matrix, matrix_basis);
|
||||
}
|
||||
|
||||
if (gz->flag & WM_GIZMO_DRAW_NO_SCALE) {
|
||||
mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
|
||||
}
|
||||
else {
|
||||
if (gz->flag & WM_GIZMO_DRAW_OFFSET_SCALE) {
|
||||
mul_mat3_m4_fl(final_matrix, *scale_final);
|
||||
mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
|
||||
}
|
||||
else {
|
||||
mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
|
||||
mul_mat3_m4_fl(final_matrix, *scale_final);
|
||||
}
|
||||
}
|
||||
|
||||
mul_m4_m4m4(r_mat, matrix_space, final_matrix);
|
||||
}
|
||||
|
||||
void WM_gizmo_calc_matrix_final_no_offset(const wmGizmo *gz, float r_mat[4][4])
|
||||
{
|
||||
float mat_identity[4][4];
|
||||
unit_m4(mat_identity);
|
||||
|
||||
wmGizmoMatrixParams params{};
|
||||
params.matrix_space = nullptr;
|
||||
params.matrix_basis = nullptr;
|
||||
params.matrix_offset = mat_identity;
|
||||
params.scale_final = nullptr;
|
||||
WM_gizmo_calc_matrix_final_params(gz, ¶ms, r_mat);
|
||||
}
|
||||
|
||||
void WM_gizmo_calc_matrix_final(const wmGizmo *gz, float r_mat[4][4])
|
||||
{
|
||||
wmGizmoMatrixParams params{};
|
||||
params.matrix_space = nullptr;
|
||||
params.matrix_basis = nullptr;
|
||||
params.matrix_offset = nullptr;
|
||||
params.scale_final = nullptr;
|
||||
WM_gizmo_calc_matrix_final_params(gz, ¶ms, r_mat);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gizmo Property Access
|
||||
*
|
||||
* Matches `WM_operator_properties` conventions.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
void WM_gizmo_properties_create_ptr(PointerRNA *ptr, wmGizmoType *gzt)
|
||||
{
|
||||
*ptr = RNA_pointer_create_discrete(nullptr, gzt->srna, nullptr);
|
||||
}
|
||||
|
||||
void WM_gizmo_properties_create(PointerRNA *ptr, const StringRef gtstring)
|
||||
{
|
||||
const wmGizmoType *gzt = WM_gizmotype_find(gtstring, false);
|
||||
|
||||
if (gzt) {
|
||||
WM_gizmo_properties_create_ptr(ptr, const_cast<wmGizmoType *>(gzt));
|
||||
}
|
||||
else {
|
||||
*ptr = RNA_pointer_create_discrete(nullptr, RNA_GizmoProperties, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmo_properties_alloc(PointerRNA **ptr, IDProperty **properties, const StringRef gtstring)
|
||||
{
|
||||
if (*properties == nullptr) {
|
||||
*properties = bke::idprop::create_group("wmOpItemProp").release();
|
||||
}
|
||||
|
||||
if (*ptr == nullptr) {
|
||||
*ptr = MEM_new<PointerRNA>("wmOpItemPtr");
|
||||
WM_gizmo_properties_create(*ptr, gtstring);
|
||||
}
|
||||
|
||||
(*ptr)->data = *properties;
|
||||
}
|
||||
|
||||
void WM_gizmo_properties_sanitize(PointerRNA *ptr, const bool no_context)
|
||||
{
|
||||
RNA_STRUCT_BEGIN (ptr, prop) {
|
||||
switch (RNA_property_type(prop)) {
|
||||
case PROP_ENUM:
|
||||
if (no_context) {
|
||||
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
|
||||
}
|
||||
else {
|
||||
RNA_def_property_clear_flag(prop, PROP_ENUM_NO_CONTEXT);
|
||||
}
|
||||
break;
|
||||
case PROP_POINTER: {
|
||||
StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
|
||||
|
||||
/* Recurse into gizmo properties. */
|
||||
if (RNA_struct_is_a(ptype, RNA_GizmoProperties)) {
|
||||
PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
|
||||
WM_gizmo_properties_sanitize(&opptr, no_context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
RNA_STRUCT_END;
|
||||
}
|
||||
|
||||
bool WM_gizmo_properties_default(PointerRNA *ptr, const bool do_update)
|
||||
{
|
||||
bool changed = false;
|
||||
RNA_STRUCT_BEGIN (ptr, prop) {
|
||||
switch (RNA_property_type(prop)) {
|
||||
case PROP_POINTER: {
|
||||
StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
|
||||
if (ptype != RNA_Struct) {
|
||||
PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
|
||||
changed |= WM_gizmo_properties_default(&opptr, do_update);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if ((do_update == false) || (RNA_property_is_set(ptr, prop) == false)) {
|
||||
if (RNA_property_reset(ptr, prop, -1)) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
RNA_STRUCT_END;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void WM_gizmo_properties_reset(wmGizmo *gz)
|
||||
{
|
||||
if (gz->ptr->data) {
|
||||
PropertyRNA *iterprop;
|
||||
iterprop = RNA_struct_iterator_property(gz->type->srna);
|
||||
|
||||
RNA_PROP_BEGIN (gz->ptr, itemptr, iterprop) {
|
||||
PropertyRNA *prop = static_cast<PropertyRNA *>(itemptr.data);
|
||||
|
||||
if ((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) {
|
||||
const char *identifier = RNA_property_identifier(prop);
|
||||
RNA_struct_system_idprops_unset(gz->ptr, identifier);
|
||||
}
|
||||
}
|
||||
RNA_PROP_END;
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmo_properties_clear(PointerRNA *ptr)
|
||||
{
|
||||
IDProperty *properties = static_cast<IDProperty *>(ptr->data);
|
||||
|
||||
if (properties) {
|
||||
IDP_ClearProperty(properties);
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmo_properties_free(PointerRNA *ptr)
|
||||
{
|
||||
IDProperty *properties = static_cast<IDProperty *>(ptr->data);
|
||||
|
||||
if (properties) {
|
||||
IDP_FreeProperty(properties);
|
||||
ptr->data = nullptr; /* Just in case. */
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name General Utilities
|
||||
* \{ */
|
||||
|
||||
bool WM_gizmo_group_is_modal(const wmGizmoGroup *gzgroup)
|
||||
{
|
||||
wmGizmo *gz = WM_gizmomap_get_modal(gzgroup->parent_gzmap);
|
||||
if (gz && gz->parent_gzgroup == gzgroup) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WM_gizmo_context_check_drawstep(const bContext *C, eWM_GizmoFlagMapDrawStep step)
|
||||
{
|
||||
switch (step) {
|
||||
case WM_GIZMOMAP_DRAWSTEP_2D: {
|
||||
break;
|
||||
}
|
||||
case WM_GIZMOMAP_DRAWSTEP_3D: {
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
if (ED_screen_animation_playing(wm)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,178 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup wm
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "BLI_vector_set.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_define.hh"
|
||||
#include "RNA_prototypes.hh"
|
||||
|
||||
#include "WM_types.hh"
|
||||
|
||||
/* Own includes. */
|
||||
#include "wm_gizmo_intern.hh"
|
||||
#include "wm_gizmo_wmapi.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name GizmoGroup Type Append
|
||||
*
|
||||
* \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends.
|
||||
* \{ */
|
||||
|
||||
static auto &get_gizmo_group_type_map()
|
||||
{
|
||||
struct IDNameGetter {
|
||||
StringRef operator()(const wmGizmoGroupType *value) const
|
||||
{
|
||||
return StringRef(value->idname);
|
||||
}
|
||||
};
|
||||
static CustomIDVectorSet<wmGizmoGroupType *, IDNameGetter> map;
|
||||
return map;
|
||||
}
|
||||
|
||||
wmGizmoGroupType *WM_gizmogrouptype_find(const StringRef idname, bool quiet)
|
||||
{
|
||||
if (!idname.is_empty()) {
|
||||
if (wmGizmoGroupType *const *gzgt = get_gizmo_group_type_map().lookup_key_ptr_as(idname)) {
|
||||
return *gzgt;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
printf("search for unknown gizmo group '%s'\n", std::string(idname).c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!quiet) {
|
||||
printf("search for empty gizmo group\n");
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static wmGizmoGroupType *wm_gizmogrouptype_append__begin()
|
||||
{
|
||||
wmGizmoGroupType *gzgt = MEM_new_zeroed<wmGizmoGroupType>("gizmogrouptype");
|
||||
gzgt->srna = RNA_def_struct_ptr(&RNA_blender_rna_get(), "", RNA_GizmoGroupProperties);
|
||||
#if 0
|
||||
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
|
||||
RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
|
||||
ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
|
||||
#endif
|
||||
return gzgt;
|
||||
}
|
||||
static void wm_gizmogrouptype_append__end(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
BLI_assert(gzgt->name != nullptr);
|
||||
BLI_assert(gzgt->idname != nullptr);
|
||||
|
||||
RNA_def_struct_identifier(&RNA_blender_rna_get(), gzgt->srna, gzgt->idname);
|
||||
|
||||
gzgt->type_update_flag |= WM_GIZMOMAPTYPE_KEYMAP_INIT;
|
||||
|
||||
/* If not set, use default. */
|
||||
if (gzgt->setup_keymap == nullptr) {
|
||||
if (gzgt->flag & WM_GIZMOGROUPTYPE_SELECT) {
|
||||
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_select;
|
||||
}
|
||||
else {
|
||||
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic;
|
||||
}
|
||||
}
|
||||
|
||||
get_gizmo_group_type_map().add(gzgt);
|
||||
}
|
||||
|
||||
wmGizmoGroupType *WM_gizmogrouptype_append(void (*wtfunc)(wmGizmoGroupType *))
|
||||
{
|
||||
wmGizmoGroupType *gzgt = wm_gizmogrouptype_append__begin();
|
||||
wtfunc(gzgt);
|
||||
wm_gizmogrouptype_append__end(gzgt);
|
||||
return gzgt;
|
||||
}
|
||||
|
||||
wmGizmoGroupType *WM_gizmogrouptype_append_ptr(void (*wtfunc)(wmGizmoGroupType *, void *),
|
||||
void *userdata)
|
||||
{
|
||||
wmGizmoGroupType *gzgt = wm_gizmogrouptype_append__begin();
|
||||
wtfunc(gzgt, userdata);
|
||||
wm_gizmogrouptype_append__end(gzgt);
|
||||
return gzgt;
|
||||
}
|
||||
|
||||
wmGizmoGroupTypeRef *WM_gizmogrouptype_append_and_link(wmGizmoMapType *gzmap_type,
|
||||
void (*wtfunc)(wmGizmoGroupType *))
|
||||
{
|
||||
wmGizmoGroupType *gzgt = WM_gizmogrouptype_append(wtfunc);
|
||||
|
||||
gzgt->gzmap_params.spaceid = gzmap_type->spaceid;
|
||||
gzgt->gzmap_params.regionid = gzmap_type->regionid;
|
||||
|
||||
return WM_gizmomaptype_group_link_ptr(gzmap_type, gzgt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free but don't remove from the global list.
|
||||
*/
|
||||
static void gizmogrouptype_free(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
/* Python gizmo group, allocates its own string. */
|
||||
if (gzgt->rna_ext.srna) {
|
||||
MEM_delete(gzgt->idname);
|
||||
}
|
||||
|
||||
MEM_delete(gzgt);
|
||||
}
|
||||
|
||||
void WM_gizmo_group_type_free_ptr(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
BLI_assert(gzgt == WM_gizmogrouptype_find(gzgt->idname, false));
|
||||
|
||||
get_gizmo_group_type_map().remove(gzgt);
|
||||
|
||||
gizmogrouptype_free(gzgt);
|
||||
|
||||
/* XXX, TODO: update the world! */
|
||||
}
|
||||
|
||||
bool WM_gizmo_group_type_free(const StringRef idname)
|
||||
{
|
||||
wmGizmoGroupType *const *gzgt = get_gizmo_group_type_map().lookup_key_ptr_as(idname);
|
||||
if (gzgt == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WM_gizmo_group_type_free_ptr(*gzgt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wm_gizmogrouptype_free()
|
||||
{
|
||||
for (wmGizmoGroupType *gzgt : get_gizmo_group_type_map()) {
|
||||
gizmogrouptype_free(gzgt);
|
||||
}
|
||||
get_gizmo_group_type_map().clear();
|
||||
}
|
||||
|
||||
void wm_gizmogrouptype_init()
|
||||
{
|
||||
/* Reserve size is set based on blender default setup. */
|
||||
get_gizmo_group_type_map().reserve(128);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
@@ -0,0 +1,164 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup wm
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#include "WM_gizmo_types.hh"
|
||||
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
struct wmGizmoMap;
|
||||
struct wmGizmoGroupType;
|
||||
struct wmGizmoMapType;
|
||||
struct wmGizmoType;
|
||||
struct wmKeyConfig;
|
||||
struct wmWindowManager;
|
||||
|
||||
#include "wm_gizmo_fn.hh"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmo. */
|
||||
|
||||
/**
|
||||
* Add/Remove \a gizmo to selection.
|
||||
* Reallocates memory for selected gizmos so better not call for selecting multiple ones.
|
||||
*
|
||||
* \return if the selection has changed.
|
||||
*/
|
||||
bool wm_gizmo_select_set_ex(
|
||||
wmGizmoMap *gzmap, wmGizmo *gz, bool select, bool use_array, bool use_callback);
|
||||
bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz);
|
||||
|
||||
void wm_gizmo_calculate_scale(wmGizmo *gz, const bContext *C);
|
||||
void wm_gizmo_update(wmGizmo *gz, const bContext *C, bool refresh_map);
|
||||
|
||||
int wm_gizmo_is_visible(wmGizmo *gz);
|
||||
enum {
|
||||
WM_GIZMO_IS_VISIBLE_UPDATE = (1 << 0),
|
||||
WM_GIZMO_IS_VISIBLE_DRAW = (1 << 1),
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmoGroup. */
|
||||
|
||||
enum {
|
||||
TWEAK_MODAL_CANCEL = 1,
|
||||
TWEAK_MODAL_CONFIRM,
|
||||
TWEAK_MODAL_PRECISION_ON,
|
||||
TWEAK_MODAL_PRECISION_OFF,
|
||||
TWEAK_MODAL_SNAP_ON,
|
||||
TWEAK_MODAL_SNAP_OFF,
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new gizmo-group from \a gzgt.
|
||||
*/
|
||||
wmGizmoGroup *wm_gizmogroup_new_from_type(wmGizmoMap *gzmap, wmGizmoGroupType *gzgt);
|
||||
void wm_gizmogroup_free(bContext *C, wmGizmoGroup *gzgroup);
|
||||
/**
|
||||
* Add \a gizmo to \a gzgroup and make sure its name is unique within the group.
|
||||
*/
|
||||
void wm_gizmogroup_gizmo_register(wmGizmoGroup *gzgroup, wmGizmo *gz);
|
||||
wmGizmoGroup *wm_gizmogroup_find_by_type(const wmGizmoMap *gzmap, const wmGizmoGroupType *gzgt);
|
||||
wmGizmo *wm_gizmogroup_find_intersected_gizmo(wmWindowManager *wm,
|
||||
const wmGizmoGroup *gzgroup,
|
||||
bContext *C,
|
||||
int event_modifier,
|
||||
const int mval[2],
|
||||
int *r_part);
|
||||
/**
|
||||
* Adds all gizmos of \a gzgroup that can be selected to the head of \a listbase.
|
||||
* Added items need freeing!
|
||||
*/
|
||||
void wm_gizmogroup_intersectable_gizmos_to_list(wmWindowManager *wm,
|
||||
wmGizmoGroup *gzgroup,
|
||||
int event_modifier,
|
||||
Vector<wmGizmo *, 128> *r_visible_gizmos);
|
||||
bool wm_gizmogroup_is_visible_in_drawstep(const wmGizmoGroup *gzgroup,
|
||||
eWM_GizmoFlagMapDrawStep drawstep);
|
||||
|
||||
void wm_gizmogrouptype_setup_keymap(wmGizmoGroupType *gzgt, wmKeyConfig *keyconf);
|
||||
|
||||
wmKeyMap *wm_gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* #wmGizmoMap. */
|
||||
|
||||
struct wmGizmoMapSelectState {
|
||||
struct wmGizmo **items;
|
||||
int len, len_alloc;
|
||||
};
|
||||
|
||||
struct wmGizmoMap {
|
||||
wmGizmoMapType *type;
|
||||
ListBaseT<wmGizmoGroup> groups;
|
||||
|
||||
/* Private, update tagging (enum defined in C source). */
|
||||
char update_flag[WM_GIZMOMAP_DRAWSTEP_MAX];
|
||||
|
||||
/** Private, true when not yet used. */
|
||||
bool is_init;
|
||||
|
||||
/** When set, one of the items in 'groups' has #wmGizmoGroup.tag_remove set. */
|
||||
bool tag_remove_group;
|
||||
|
||||
/** When set, the event system re-calculates highlight even without cursor motion. */
|
||||
bool tag_highlight_pending;
|
||||
|
||||
/**
|
||||
* \brief Gizmo map runtime context
|
||||
*
|
||||
* Contains information about this gizmo-map. Currently
|
||||
* highlighted gizmo, currently selected gizmos, ...
|
||||
*/
|
||||
struct {
|
||||
/** We redraw the gizmo-map when this changes. */
|
||||
wmGizmo *highlight;
|
||||
/** User has clicked this gizmo and it gets all input. */
|
||||
wmGizmo *modal;
|
||||
/** Array for all selected gizmos. */
|
||||
wmGizmoMapSelectState select;
|
||||
/** Cursor location at point of entering modal (see: #WM_GIZMO_MOVE_CURSOR). */
|
||||
int event_xy[2];
|
||||
short event_grabcursor;
|
||||
/** Until we have nice cursor push/pop API. */
|
||||
int last_cursor;
|
||||
} gzmap_context;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a container for all gizmo types that can be instantiated in a region.
|
||||
* (similar to drop-boxes).
|
||||
*
|
||||
* \note There is only ever one of these for every (area, region) combination.
|
||||
*/
|
||||
struct wmGizmoMapType {
|
||||
wmGizmoMapType *next, *prev;
|
||||
short spaceid, regionid;
|
||||
/* Types of gizmo-groups for this gizmo-map type. */
|
||||
ListBaseT<wmGizmoGroupTypeRef> grouptype_refs;
|
||||
|
||||
/* #eGizmoMapTypeUpdateFlags. */
|
||||
eWM_GizmoFlagMapTypeUpdateFlag type_update_flag;
|
||||
};
|
||||
|
||||
void wm_gizmomap_select_array_clear(wmGizmoMap *gzmap);
|
||||
/**
|
||||
* Deselect all selected gizmos in \a gzmap.
|
||||
* \return if selection has changed.
|
||||
*/
|
||||
bool wm_gizmomap_deselect_all(wmGizmoMap *gzmap);
|
||||
void wm_gizmomap_select_array_shrink(wmGizmoMap *gzmap, int len_subtract);
|
||||
void wm_gizmomap_select_array_push_back(wmGizmoMap *gzmap, wmGizmo *gz);
|
||||
void wm_gizmomap_select_array_remove(wmGizmoMap *gzmap, wmGizmo *gz);
|
||||
|
||||
} // namespace blender
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,332 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup wm
|
||||
*/
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
|
||||
#include "WM_message.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "ED_keyframes_edit.hh"
|
||||
#include "ED_screen.hh"
|
||||
|
||||
#include "ANIM_keyframing.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/* Own includes. */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Property Definition
|
||||
* \{ */
|
||||
|
||||
wmGizmoProperty *WM_gizmo_target_property_find(wmGizmo *gz, const char *idname)
|
||||
{
|
||||
int index = BLI_findstringindex(
|
||||
&gz->type->target_property_defs, idname, offsetof(wmGizmoPropertyType, idname));
|
||||
if (index != -1) {
|
||||
return &gz->target_properties[index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_def_rna_ptr(wmGizmo *gz,
|
||||
const wmGizmoPropertyType *gz_prop_type,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int index)
|
||||
{
|
||||
wmGizmoProperty *gz_prop = &gz->target_properties[gz_prop_type->index_in_type];
|
||||
|
||||
/* If gizmo evokes an operator we cannot use it for property manipulation. */
|
||||
BLI_assert(gz->op_data.is_empty());
|
||||
BLI_assert(prop != nullptr);
|
||||
|
||||
gz_prop->type = gz_prop_type;
|
||||
|
||||
gz_prop->ptr = *ptr;
|
||||
gz_prop->prop = prop;
|
||||
gz_prop->index = index;
|
||||
|
||||
if (gz->type->property_update) {
|
||||
gz->type->property_update(gz, gz_prop);
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_def_rna(
|
||||
wmGizmo *gz, const char *idname, PointerRNA *ptr, const char *propname, int index)
|
||||
{
|
||||
const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(gz->type, idname);
|
||||
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
||||
if (prop == nullptr) {
|
||||
RNA_warning("%s: %s.%s not found", __func__, RNA_struct_identifier(ptr->type), propname);
|
||||
}
|
||||
WM_gizmo_target_property_def_rna_ptr(gz, gz_prop_type, ptr, prop, index);
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_def_func_ptr(wmGizmo *gz,
|
||||
const wmGizmoPropertyType *gz_prop_type,
|
||||
const wmGizmoPropertyFnParams *params)
|
||||
{
|
||||
wmGizmoProperty *gz_prop = &gz->target_properties[gz_prop_type->index_in_type];
|
||||
|
||||
/* If gizmo evokes an operator we cannot use it for property manipulation. */
|
||||
BLI_assert(gz->op_data.is_empty());
|
||||
|
||||
gz_prop->type = gz_prop_type;
|
||||
|
||||
gz_prop->custom_func.value_get_fn = params->value_get_fn;
|
||||
gz_prop->custom_func.value_set_fn = params->value_set_fn;
|
||||
gz_prop->custom_func.range_get_fn = params->range_get_fn;
|
||||
gz_prop->custom_func.free_fn = params->free_fn;
|
||||
gz_prop->custom_func.foreach_rna_prop_fn = params->foreach_rna_prop_fn;
|
||||
gz_prop->custom_func.user_data = params->user_data;
|
||||
|
||||
if (gz->type->property_update) {
|
||||
gz->type->property_update(gz, gz_prop);
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_def_func(wmGizmo *gz,
|
||||
const char *idname,
|
||||
const wmGizmoPropertyFnParams *params)
|
||||
{
|
||||
const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(gz->type, idname);
|
||||
WM_gizmo_target_property_def_func_ptr(gz, gz_prop_type, params);
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_clear_rna_ptr(wmGizmo *gz, const wmGizmoPropertyType *gz_prop_type)
|
||||
{
|
||||
wmGizmoProperty *gz_prop = &gz->target_properties[gz_prop_type->index_in_type];
|
||||
|
||||
/* If gizmo evokes an operator we cannot use it for property manipulation. */
|
||||
BLI_assert(gz->op_data.is_empty());
|
||||
|
||||
*gz_prop = {};
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_clear_rna(wmGizmo *gz, const char *idname)
|
||||
{
|
||||
const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(gz->type, idname);
|
||||
WM_gizmo_target_property_clear_rna_ptr(gz, gz_prop_type);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Property Access
|
||||
* \{ */
|
||||
|
||||
bool WM_gizmo_target_property_is_valid_any(const wmGizmo *gz)
|
||||
{
|
||||
for (const wmGizmoProperty &gz_prop : gz->target_properties) {
|
||||
if (WM_gizmo_target_property_is_valid(&gz_prop)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WM_gizmo_target_property_is_valid(const wmGizmoProperty *gz_prop)
|
||||
{
|
||||
return ((gz_prop->prop != nullptr) ||
|
||||
(gz_prop->custom_func.value_get_fn && gz_prop->custom_func.value_set_fn));
|
||||
}
|
||||
|
||||
float WM_gizmo_target_property_float_get(const wmGizmo *gz, wmGizmoProperty *gz_prop)
|
||||
{
|
||||
if (gz_prop->custom_func.value_get_fn) {
|
||||
float value = 0.0f;
|
||||
BLI_assert(gz_prop->type->array_length == 1);
|
||||
gz_prop->custom_func.value_get_fn(gz, gz_prop, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
if (gz_prop->index == -1) {
|
||||
return RNA_property_float_get(&gz_prop->ptr, gz_prop->prop);
|
||||
}
|
||||
return RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index);
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_float_set(bContext *C,
|
||||
const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop,
|
||||
const float value)
|
||||
{
|
||||
if (gz_prop->custom_func.value_set_fn) {
|
||||
BLI_assert(gz_prop->type->array_length == 1);
|
||||
gz_prop->custom_func.value_set_fn(gz, gz_prop, &value);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset property. */
|
||||
if (gz_prop->index == -1) {
|
||||
RNA_property_float_set(&gz_prop->ptr, gz_prop->prop, value);
|
||||
}
|
||||
else {
|
||||
RNA_property_float_set_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index, value);
|
||||
}
|
||||
RNA_property_update(C, &gz_prop->ptr, gz_prop->prop);
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_float_get_array(const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop,
|
||||
float *value)
|
||||
{
|
||||
if (gz_prop->custom_func.value_get_fn) {
|
||||
gz_prop->custom_func.value_get_fn(gz, gz_prop, value);
|
||||
return;
|
||||
}
|
||||
RNA_property_float_get_array(&gz_prop->ptr, gz_prop->prop, value);
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_float_set_array(bContext *C,
|
||||
const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop,
|
||||
const float *value)
|
||||
{
|
||||
if (gz_prop->custom_func.value_set_fn) {
|
||||
gz_prop->custom_func.value_set_fn(gz, gz_prop, value);
|
||||
return;
|
||||
}
|
||||
RNA_property_float_set_array(&gz_prop->ptr, gz_prop->prop, value);
|
||||
|
||||
RNA_property_update(C, &gz_prop->ptr, gz_prop->prop);
|
||||
}
|
||||
|
||||
bool WM_gizmo_target_property_float_range_get(const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop,
|
||||
float range[2])
|
||||
{
|
||||
if (gz_prop->custom_func.value_get_fn) {
|
||||
if (gz_prop->custom_func.range_get_fn) {
|
||||
gz_prop->custom_func.range_get_fn(gz, gz_prop, range);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float step, precision;
|
||||
RNA_property_float_ui_range(
|
||||
&gz_prop->ptr, gz_prop->prop, &range[0], &range[1], &step, &precision);
|
||||
return true;
|
||||
}
|
||||
|
||||
int WM_gizmo_target_property_array_length(const wmGizmo * /*gz*/, wmGizmoProperty *gz_prop)
|
||||
{
|
||||
if (gz_prop->custom_func.value_get_fn) {
|
||||
return gz_prop->type->array_length;
|
||||
}
|
||||
return RNA_property_array_length(&gz_prop->ptr, gz_prop->prop);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Property Define
|
||||
* \{ */
|
||||
|
||||
const wmGizmoPropertyType *WM_gizmotype_target_property_find(const wmGizmoType *gzt,
|
||||
const char *idname)
|
||||
{
|
||||
return static_cast<const wmGizmoPropertyType *>(
|
||||
BLI_findstring(&gzt->target_property_defs, idname, offsetof(wmGizmoPropertyType, idname)));
|
||||
}
|
||||
|
||||
void WM_gizmotype_target_property_def(wmGizmoType *gzt,
|
||||
const char *idname,
|
||||
int data_type,
|
||||
int array_length)
|
||||
{
|
||||
|
||||
BLI_assert(WM_gizmotype_target_property_find(gzt, idname) == nullptr);
|
||||
|
||||
const uint idname_size = strlen(idname) + 1;
|
||||
wmGizmoPropertyType *gz_prop_type = static_cast<wmGizmoPropertyType *>(
|
||||
MEM_new_zeroed(sizeof(wmGizmoPropertyType) + idname_size, __func__));
|
||||
memcpy(gz_prop_type->idname, idname, idname_size);
|
||||
gz_prop_type->data_type = data_type;
|
||||
gz_prop_type->array_length = array_length;
|
||||
gz_prop_type->index_in_type = gzt->target_property_defs_len;
|
||||
gzt->target_property_defs_len += 1;
|
||||
BLI_addtail(&gzt->target_property_defs, gz_prop_type);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Property Utilities
|
||||
* \{ */
|
||||
|
||||
void WM_gizmo_do_msg_notify_tag_refresh(bContext * /*C*/,
|
||||
wmMsgSubscribeKey * /*msg_key*/,
|
||||
wmMsgSubscribeValue *msg_val)
|
||||
{
|
||||
ARegion *region = static_cast<ARegion *>(msg_val->owner);
|
||||
wmGizmoMap *gzmap = static_cast<wmGizmoMap *>(msg_val->user_data);
|
||||
|
||||
/* Could possibly avoid a full redraw and only tag for editor overlays
|
||||
* redraw in some cases, see #ED_region_tag_redraw_editor_overlays(). */
|
||||
ED_region_tag_redraw(region);
|
||||
|
||||
WM_gizmomap_tag_refresh(gzmap);
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_subscribe_all(wmGizmo *gz, wmMsgBus *mbus, ARegion *region)
|
||||
{
|
||||
for (wmGizmoProperty &gz_prop : gz->target_properties) {
|
||||
if (WM_gizmo_target_property_is_valid(&gz_prop)) {
|
||||
if (gz_prop.prop) {
|
||||
{
|
||||
wmMsgSubscribeValue value{};
|
||||
value.owner = region;
|
||||
value.user_data = region;
|
||||
value.notify = ED_region_do_msg_notify_tag_redraw;
|
||||
WM_msg_subscribe_rna(mbus, &gz_prop.ptr, gz_prop.prop, &value, __func__);
|
||||
}
|
||||
{
|
||||
wmMsgSubscribeValue value{};
|
||||
value.owner = region;
|
||||
value.user_data = gz->parent_gzgroup->parent_gzmap;
|
||||
value.notify = WM_gizmo_do_msg_notify_tag_refresh;
|
||||
WM_msg_subscribe_rna(mbus, &gz_prop.ptr, gz_prop.prop, &value, __func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_anim_autokey(bContext *C,
|
||||
const wmGizmo * /*gz*/,
|
||||
wmGizmoProperty *gz_prop)
|
||||
{
|
||||
if (gz_prop->prop != nullptr) {
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const float cfra = float(scene->r.cfra);
|
||||
ANIM_deselect_keys_in_animation_editors(C);
|
||||
animrig::autokeyframe_property(
|
||||
C, scene, &gz_prop->ptr, gz_prop->prop, gz_prop->index, cfra, false);
|
||||
}
|
||||
else if (gz_prop->custom_func.foreach_rna_prop_fn) {
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
auto autokey_fn = [C, scene](PointerRNA &ptr, PropertyRNA *prop, int index) {
|
||||
animrig::autokeyframe_property(C, scene, &ptr, prop, index, float(scene->r.cfra), false);
|
||||
};
|
||||
ANIM_deselect_keys_in_animation_editors(C);
|
||||
gz_prop->custom_func.foreach_rna_prop_fn(gz_prop, autokey_fn);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
@@ -0,0 +1,190 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup wm
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_vector_set.hh"
|
||||
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_screen.hh"
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_define.hh"
|
||||
#include "RNA_prototypes.hh"
|
||||
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "ED_screen.hh"
|
||||
|
||||
/* Own includes. */
|
||||
#include "wm_gizmo_intern.hh"
|
||||
#include "wm_gizmo_wmapi.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gizmo Type Append
|
||||
*
|
||||
* \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends.
|
||||
* \{ */
|
||||
|
||||
static auto &get_gizmo_type_map()
|
||||
{
|
||||
struct IDNameGetter {
|
||||
StringRef operator()(const wmGizmoType *value) const
|
||||
{
|
||||
return StringRef(value->idname);
|
||||
}
|
||||
};
|
||||
static CustomIDVectorSet<wmGizmoType *, IDNameGetter> map;
|
||||
return map;
|
||||
}
|
||||
|
||||
const wmGizmoType *WM_gizmotype_find(const StringRef idname, bool quiet)
|
||||
{
|
||||
if (!idname.is_empty()) {
|
||||
if (wmGizmoType *const *gzt = get_gizmo_type_map().lookup_key_ptr_as(idname)) {
|
||||
return *gzt;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
printf("search for unknown gizmo '%s'\n", std::string(idname).c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!quiet) {
|
||||
printf("search for empty gizmo\n");
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static wmGizmoType *wm_gizmotype_append__begin()
|
||||
{
|
||||
wmGizmoType *gzt = MEM_new_zeroed<wmGizmoType>("gizmotype");
|
||||
gzt->srna = RNA_def_struct_ptr(&RNA_blender_rna_get(), "", RNA_GizmoProperties);
|
||||
#if 0
|
||||
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
|
||||
RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
|
||||
ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
|
||||
#endif
|
||||
return gzt;
|
||||
}
|
||||
static void wm_gizmotype_append__end(wmGizmoType *gzt)
|
||||
{
|
||||
BLI_assert(gzt->struct_size >= sizeof(wmGizmo));
|
||||
|
||||
RNA_def_struct_identifier(&RNA_blender_rna_get(), gzt->srna, gzt->idname);
|
||||
|
||||
get_gizmo_type_map().add(gzt);
|
||||
}
|
||||
|
||||
void WM_gizmotype_append(void (*gtfunc)(wmGizmoType *))
|
||||
{
|
||||
wmGizmoType *gzt = wm_gizmotype_append__begin();
|
||||
gtfunc(gzt);
|
||||
wm_gizmotype_append__end(gzt);
|
||||
}
|
||||
|
||||
void WM_gizmotype_append_ptr(void (*gtfunc)(wmGizmoType *, void *), void *userdata)
|
||||
{
|
||||
wmGizmoType *mt = wm_gizmotype_append__begin();
|
||||
gtfunc(mt, userdata);
|
||||
wm_gizmotype_append__end(mt);
|
||||
}
|
||||
|
||||
void WM_gizmotype_free_ptr(wmGizmoType *gzt)
|
||||
{
|
||||
/* Python gizmo, allocates its own string. */
|
||||
if (gzt->rna_ext.srna) {
|
||||
MEM_delete(gzt->idname);
|
||||
}
|
||||
|
||||
gzt->target_property_defs.free_no_destruct();
|
||||
MEM_delete(gzt);
|
||||
}
|
||||
|
||||
/**
|
||||
* \param C: May be nullptr.
|
||||
*/
|
||||
static void gizmotype_unlink(bContext *C, Main *bmain, wmGizmoType *gzt)
|
||||
{
|
||||
/* Free instances. */
|
||||
for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
|
||||
screen = static_cast<bScreen *>(screen->id.next))
|
||||
{
|
||||
for (ScrArea &area : screen->areabase) {
|
||||
for (SpaceLink &sl : area.spacedata) {
|
||||
ListBaseT<ARegion> *lb = (&sl == area.spacedata.first) ? &area.regionbase : &sl.regionbase;
|
||||
for (ARegion ®ion : *lb) {
|
||||
wmGizmoMap *gzmap = region.runtime->gizmo_map;
|
||||
if (gzmap) {
|
||||
for (wmGizmoGroup &gzgroup : gzmap->groups) {
|
||||
for (wmGizmo *gz = static_cast<wmGizmo *>(gzgroup.gizmos.first), *gz_next; gz;
|
||||
gz = gz_next)
|
||||
{
|
||||
gz_next = gz->next;
|
||||
BLI_assert(gzgroup.parent_gzmap == gzmap);
|
||||
if (gz->type == gzt) {
|
||||
WM_gizmo_unlink(&gzgroup.gizmos, gzgroup.parent_gzmap, gz, C);
|
||||
ED_region_tag_redraw_editor_overlays(®ion);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmotype_remove_ptr(bContext *C, Main *bmain, wmGizmoType *gzt)
|
||||
{
|
||||
BLI_assert(gzt == WM_gizmotype_find(gzt->idname, false));
|
||||
|
||||
get_gizmo_type_map().remove(gzt);
|
||||
|
||||
gizmotype_unlink(C, bmain, gzt);
|
||||
}
|
||||
|
||||
bool WM_gizmotype_remove(bContext *C, Main *bmain, const StringRef idname)
|
||||
{
|
||||
wmGizmoType *const *gzt = get_gizmo_type_map().lookup_key_ptr_as(idname);
|
||||
if (gzt == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WM_gizmotype_remove_ptr(C, bmain, *gzt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wm_gizmotype_free()
|
||||
{
|
||||
for (wmGizmoType *gzt : get_gizmo_type_map()) {
|
||||
WM_gizmotype_free_ptr(gzt);
|
||||
}
|
||||
get_gizmo_type_map().clear();
|
||||
}
|
||||
|
||||
void wm_gizmotype_init()
|
||||
{
|
||||
/* Reserve size is set based on blender default setup. */
|
||||
get_gizmo_type_map().reserve(128);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
@@ -0,0 +1,97 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup wm
|
||||
*
|
||||
* Callback function definitions, needed for both Types & API headers.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DNA_windowmanager_enums.h" /* For `wmOperatorStatus`. */
|
||||
|
||||
namespace blender {
|
||||
|
||||
struct bContext;
|
||||
struct rcti;
|
||||
struct wmEvent;
|
||||
struct wmGizmo;
|
||||
struct wmGizmoGroup;
|
||||
struct wmGizmoGroupType;
|
||||
struct wmGizmoProperty;
|
||||
struct wmKeyConfig;
|
||||
struct wmKeyMap;
|
||||
struct wmMsgBus;
|
||||
|
||||
/* #wmGizmoGroup. */
|
||||
using wmGizmoGroupFnPoll = bool (*)(const bContext *, wmGizmoGroupType *);
|
||||
using wmGizmoGroupFnInit = void (*)(const bContext *, wmGizmoGroup *);
|
||||
using wmGizmoGroupFnRefresh = void (*)(const bContext *, wmGizmoGroup *);
|
||||
using wmGizmoGroupFnDrawPrepare = void (*)(const bContext *, wmGizmoGroup *);
|
||||
using wmGizmoGroupFnDrawBackground = void (*)(const bContext *, wmGizmoGroup *);
|
||||
using wmGizmoGroupFnInvokePrepare = void (*)(const bContext *,
|
||||
wmGizmoGroup *,
|
||||
wmGizmo *,
|
||||
const wmEvent *);
|
||||
using wmGizmoGroupFnSetupKeymap = wmKeyMap *(*)(const wmGizmoGroupType *, wmKeyConfig *);
|
||||
using wmGizmoGroupFnMsgBusSubscribe = void (*)(const bContext *, wmGizmoGroup *, wmMsgBus *);
|
||||
|
||||
/* #wmGizmo. */
|
||||
/* See: wmGizmoType for docs on each type. */
|
||||
|
||||
using wmGizmoFnSetup = void (*)(wmGizmo *);
|
||||
using wmGizmoFnDraw = void (*)(const bContext *, wmGizmo *);
|
||||
using wmGizmoFnDrawSelect = void (*)(const bContext *, wmGizmo *, int);
|
||||
using wmGizmoFnTestSelect = int (*)(bContext *, wmGizmo *, const int mval[2]);
|
||||
using wmGizmoFnModal = wmOperatorStatus (*)(bContext *,
|
||||
wmGizmo *,
|
||||
const wmEvent *,
|
||||
eWM_GizmoFlagTweak);
|
||||
using wmGizmoFnPropertyUpdate = void (*)(wmGizmo *, wmGizmoProperty *);
|
||||
using wmGizmoFnMatrixBasisGet = void (*)(const wmGizmo *, float[4][4]);
|
||||
using wmGizmoFnInvoke = wmOperatorStatus (*)(bContext *, wmGizmo *, const wmEvent *);
|
||||
using wmGizmoFnExit = void (*)(bContext *, wmGizmo *, const bool);
|
||||
using wmGizmoFnCursorGet = int (*)(wmGizmo *);
|
||||
using wmGizmoFnScreenBoundsGet = bool (*)(const bContext *, wmGizmo *, rcti *r_bounding_box);
|
||||
using wmGizmoFnSelectRefresh = void (*)(wmGizmo *);
|
||||
using wmGizmoFnFree = void (*)(wmGizmo *);
|
||||
|
||||
/* #wmGizmoProperty ('value' type defined by 'wmGizmoProperty.data_type'). */
|
||||
using wmGizmoPropertyFnGet = void (*)(const wmGizmo *,
|
||||
wmGizmoProperty *,
|
||||
/* Typically `float *`. */
|
||||
void *value);
|
||||
using wmGizmoPropertyFnSet = void (*)(const wmGizmo *,
|
||||
wmGizmoProperty *,
|
||||
/* Typically `const float *`. */
|
||||
const void *value);
|
||||
using wmGizmoPropertyFnRangeGet = void (*)(const wmGizmo *,
|
||||
wmGizmoProperty *,
|
||||
/* Typically `float[2]`. */
|
||||
void *range);
|
||||
/**
|
||||
* To inspect the RNA properties gizmos are manipulating (can be multiple).
|
||||
* Used e.g. for auto-keying.
|
||||
*
|
||||
* \param gz_prop: The gizmo property to inspect.
|
||||
* \param callback: Called for each RNA property being manipulated.
|
||||
* - `index`: Property element index (-1 for all items).
|
||||
*/
|
||||
using wmGizmoPropertyFnForeachRNAProp =
|
||||
void (*)(wmGizmoProperty *,
|
||||
const FunctionRef<void(PointerRNA &ptr, PropertyRNA *prop, int index)> callback);
|
||||
|
||||
using wmGizmoPropertyFnFree = void (*)(const wmGizmo *, wmGizmoProperty *);
|
||||
|
||||
struct wmGizmoPropertyFnParams {
|
||||
wmGizmoPropertyFnGet value_get_fn;
|
||||
wmGizmoPropertyFnSet value_set_fn;
|
||||
wmGizmoPropertyFnRangeGet range_get_fn;
|
||||
wmGizmoPropertyFnFree free_fn;
|
||||
wmGizmoPropertyFnForeachRNAProp foreach_rna_prop_fn;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
} // namespace blender
|
||||
@@ -0,0 +1,116 @@
|
||||
/* SPDX-FileCopyrightText: 2016 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup wm
|
||||
*
|
||||
* \name Gizmos Window Manager API
|
||||
* API for usage in window manager code only. It should contain all functionality
|
||||
* needed to hook up the gizmo system with Blender's window manager. It's
|
||||
* mostly the event system that needs to communicate with gizmo code.
|
||||
*
|
||||
* Only included in `wm.hh` and lower level files.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
struct bContext;
|
||||
struct wmEvent;
|
||||
struct wmEventHandler_Gizmo;
|
||||
struct wmEventHandler_Op;
|
||||
struct wmGizmo;
|
||||
struct wmGizmoGroup;
|
||||
struct wmGizmoMap;
|
||||
struct wmKeyConfig;
|
||||
struct wmOperatorType;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name #wmGizmo
|
||||
* \{ */
|
||||
|
||||
/* `wm_gizmo_type.cc`, for init/exit. */
|
||||
|
||||
void wm_gizmotype_free();
|
||||
/**
|
||||
* Called on initialize #WM_init().
|
||||
*/
|
||||
void wm_gizmotype_init();
|
||||
|
||||
/* `wm_gizmogroup_type.cc`, for init/exit. */
|
||||
|
||||
void wm_gizmogrouptype_free();
|
||||
/**
|
||||
* Called on initialize #WM_init().
|
||||
*/
|
||||
void wm_gizmogrouptype_init();
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name #wmGizmoGroup
|
||||
* \{ */
|
||||
|
||||
void GIZMOGROUP_OT_gizmo_select(wmOperatorType *ot);
|
||||
void GIZMOGROUP_OT_gizmo_tweak(wmOperatorType *ot);
|
||||
|
||||
bool wm_gizmogroup_is_any_selected(const wmGizmoGroup *gzgroup);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name #wmGizmoMap
|
||||
* \{ */
|
||||
|
||||
void wm_gizmomap_remove(wmGizmoMap *gzmap);
|
||||
|
||||
/**
|
||||
* Initialize key-maps for all existing gizmo-groups
|
||||
*/
|
||||
void wm_gizmos_keymap(wmKeyConfig *keyconf);
|
||||
|
||||
void wm_gizmomaps_handled_modal_update(bContext *C, wmEvent *event, wmEventHandler_Op *handler);
|
||||
/**
|
||||
* Prepare context for gizmo handling (but only if area/region is
|
||||
* part of screen). Version of #wm_handler_op_context for gizmos.
|
||||
*/
|
||||
void wm_gizmomap_handler_context_op(bContext *C, wmEventHandler_Op *handler);
|
||||
void wm_gizmomap_handler_context_gizmo(bContext *C, wmEventHandler_Gizmo *handler);
|
||||
|
||||
bool wm_gizmomap_highlight_pending(const wmGizmoMap *gzmap);
|
||||
bool wm_gizmomap_highlight_handled(wmGizmoMap *gzmap);
|
||||
/**
|
||||
* Try to find a gizmo under the mouse position. 2D intersections have priority over
|
||||
* 3D ones (could check for smallest screen-space distance but not needed right now).
|
||||
*/
|
||||
wmGizmo *wm_gizmomap_highlight_find(wmGizmoMap *gzmap,
|
||||
bContext *C,
|
||||
const wmEvent *event,
|
||||
int *r_part);
|
||||
bool wm_gizmomap_highlight_set(wmGizmoMap *gzmap, const bContext *C, wmGizmo *gz, int part);
|
||||
wmGizmo *wm_gizmomap_highlight_get(wmGizmoMap *gzmap);
|
||||
/**
|
||||
* Caller should call exit when (enable == False).
|
||||
*/
|
||||
void wm_gizmomap_modal_set(
|
||||
wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, const wmEvent *event, bool enable);
|
||||
|
||||
wmGizmo *wm_gizmomap_modal_get(wmGizmoMap *gzmap);
|
||||
wmGizmo **wm_gizmomap_selected_get(wmGizmoMap *gzmap, int *r_selected_len);
|
||||
ListBaseT<wmGizmoGroup> *wm_gizmomap_groups_get(wmGizmoMap *gzmap);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name #wmGizmoMapType
|
||||
* \{ */
|
||||
|
||||
void wm_gizmomaptypes_free();
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
Reference in New Issue
Block a user