diff options
Diffstat (limited to 'source/blender/editors/include')
27 files changed, 729 insertions, 405 deletions
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index 3f1b8d6ecda..84512653a24 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -55,17 +55,17 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin); * finished. */ void immDrawPixelsTexScaledFullSize(const IMMDrawPixelsTexState *state, - const float x, - const float y, - const int img_w, - const int img_h, - const eGPUTextureFormat gpu_format, - const bool use_filter, + float x, + float y, + int img_w, + int img_h, + eGPUTextureFormat gpu_format, + bool use_filter, const void *rect, - const float scaleX, - const float scaleY, - const float xzoom, - const float yzoom, + float scaleX, + float scaleY, + float xzoom, + float yzoom, const float color[4]); /** diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index da40eef87fd..cc3c68abc55 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -324,11 +324,15 @@ typedef enum eAnimFilter_Flags { /** duplicate entries for animation data attached to multi-user blocks must not occur */ ANIMFILTER_NODUPLIS = (1 << 11), + /** avoid channel that does not have any F-curve data */ + ANIMFILTER_FCURVESONLY = (1 << 12), + /** for checking if we should keep some collapsed channel around (internal use only!) */ ANIMFILTER_TMP_PEEK = (1 << 30), /** Ignore ONLYSEL flag from #bDopeSheet.filterflag (internal use only!) */ ANIMFILTER_TMP_IGNORE_ONLYSEL = (1u << 31), + } eAnimFilter_Flags; /** \} */ @@ -1042,6 +1046,8 @@ void ED_keymap_anim(struct wmKeyConfig *keyconf); void ED_operatormacros_graph(void); /* space_action */ void ED_operatormacros_action(void); +/* space_nla*/ +void ED_operatormacros_nla(void); /** \} */ diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 2c67b02611b..0f981e270a0 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -22,15 +22,53 @@ struct bScreen; /* ** clip_editor.c ** */ -/* common poll functions */ +/* Returns true when the following conditions are met: + * - Current space is Space Clip. + * - There is a movie clip opened in it. */ bool ED_space_clip_poll(struct bContext *C); +/* Returns true when the following conditions are met: + * - Current space is Space Clip. + * - It is set to Clip view. + * + * It is not required to have movie clip opened for editing. */ bool ED_space_clip_view_clip_poll(struct bContext *C); +/* Returns true when the following conditions are met: + * - Current space is Space Clip. + * - It is set to Tracking mode. + * + * It is not required to have movie clip opened for editing. */ bool ED_space_clip_tracking_poll(struct bContext *C); + +/* Returns true when the following conditions are met: + * - Current space is Space Clip. + * - It is set to Mask mode. + * + * It is not required to have mask opened for editing. */ bool ED_space_clip_maskedit_poll(struct bContext *C); + +/* Returns true when the following conditions are met: + * - Current space is Space Clip. + * - It is set to Mask mode. + * - Mask has visible and editable splines. + * + * It is not required to have mask opened for editing. */ +bool ED_space_clip_maskedit_visible_splines_poll(struct bContext *C); + +/* Returns true when the following conditions are met: + * - Current space is Space Clip. + * - It is set to Mask mode. + * - The space has mask opened. */ bool ED_space_clip_maskedit_mask_poll(struct bContext *C); +/* Returns true when the following conditions are met: + * - Current space is Space Clip. + * - It is set to Mask mode. + * - The space has mask opened. + * - Mask has visible and editable splines. */ +bool ED_space_clip_maskedit_mask_visible_splines_poll(struct bContext *C); + void ED_space_clip_get_size(struct SpaceClip *sc, int *width, int *height); void ED_space_clip_get_size_fl(struct SpaceClip *sc, float size[2]); void ED_space_clip_get_zoom(struct SpaceClip *sc, @@ -60,7 +98,7 @@ bool ED_space_clip_get_position(struct SpaceClip *sc, */ bool ED_space_clip_color_sample(struct SpaceClip *sc, struct ARegion *region, - int mval[2], + const int mval[2], float r_col[3]); void ED_clip_update_frame(const struct Main *mainp, int cfra); diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index 9f4833bf1d7..061b783797d 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -49,10 +49,12 @@ void ED_curve_editnurb_free(struct Object *obedit); /** * \param dist_px: Maximum distance to pick (in pixels). + * \param vert_without_handles: When true, selecting the knot doesn't select the handles. */ bool ED_curve_editnurb_select_pick(struct bContext *C, const int mval[2], int dist_px, + bool vert_without_handles, const struct SelectPick_Params *params); struct Nurb *ED_curve_add_nurbs_primitive( diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index 9233b65b2ce..0817241a5c2 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -6,6 +6,8 @@ #pragma once +struct bContext; + #ifdef __cplusplus extern "C" { #endif @@ -19,10 +21,15 @@ void ED_operatortypes_curves(void); #ifdef __cplusplus # include "BKE_curves.hh" +# include "BLI_vector_set.hh" namespace blender::ed::curves { bke::CurvesGeometry primitive_random_sphere(int curves_size, int points_per_curve); +bool selection_operator_poll(bContext *C); +bool has_anything_selected(const Curves &curves_id); +VectorSet<Curves *> get_unique_editable_curves(const bContext &C); +void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob); -} +} // namespace blender::ed::curves #endif diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h index c3a66e4a7dd..e3b091430e8 100644 --- a/source/blender/editors/include/ED_datafiles.h +++ b/source/blender/editors/include/ED_datafiles.h @@ -103,6 +103,9 @@ extern const char datatoc_multiply_png[]; extern int datatoc_nudge_png_size; extern const char datatoc_nudge_png[]; +extern int datatoc_paint_select_png_size; +extern const char datatoc_paint_select_png[]; + extern int datatoc_pinch_png_size; extern const char datatoc_pinch_png[]; @@ -284,6 +287,41 @@ extern const char datatoc_gp_brush_erase_hard_png[]; extern int datatoc_gp_brush_erase_stroke_png_size; extern const char datatoc_gp_brush_erase_stroke_png[]; +/* curves sculpt brushes files */ + +extern int datatoc_curves_sculpt_add_png_size; +extern const char datatoc_curves_sculpt_add_png[]; + +extern int datatoc_curves_sculpt_comb_png_size; +extern const char datatoc_curves_sculpt_comb_png[]; + +extern int datatoc_curves_sculpt_cut_png_size; +extern const char datatoc_curves_sculpt_cut_png[]; + +extern int datatoc_curves_sculpt_delete_png_size; +extern const char datatoc_curves_sculpt_delete_png[]; + +extern int datatoc_curves_sculpt_density_png_size; +extern const char datatoc_curves_sculpt_density_png[]; + +extern int datatoc_curves_sculpt_grow_shrink_png_size; +extern const char datatoc_curves_sculpt_grow_shrink_png[]; + +extern int datatoc_curves_sculpt_pinch_png_size; +extern const char datatoc_curves_sculpt_pinch_png[]; + +extern int datatoc_curves_sculpt_puff_png_size; +extern const char datatoc_curves_sculpt_puff_png[]; + +extern int datatoc_curves_sculpt_slide_png_size; +extern const char datatoc_curves_sculpt_slide_png[]; + +extern int datatoc_curves_sculpt_smooth_png_size; +extern const char datatoc_curves_sculpt_smooth_png[]; + +extern int datatoc_curves_sculpt_snake_hook_png_size; +extern const char datatoc_curves_sculpt_snake_hook_png[]; + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_geometry.h b/source/blender/editors/include/ED_geometry.h index 74ff968828c..4620181894a 100644 --- a/source/blender/editors/include/ED_geometry.h +++ b/source/blender/editors/include/ED_geometry.h @@ -7,12 +7,22 @@ #pragma once +#include "BKE_attribute.h" +#include "DNA_customdata_types.h" + #ifdef __cplusplus extern "C" { #endif -void ED_operatortypes_geometry(void); +struct Mesh; +void ED_operatortypes_geometry(void); +bool ED_geometry_attribute_convert(struct Mesh *mesh, + const char *layer_name, + eCustomDataType old_type, + eAttrDomain old_domain, + eCustomDataType new_type, + eAttrDomain new_domain); #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h index 067e5ba4d7f..31c1f93f5bc 100644 --- a/source/blender/editors/include/ED_gizmo_library.h +++ b/source/blender/editors/include/ED_gizmo_library.h @@ -14,6 +14,8 @@ extern "C" { #endif +#include "DNA_scene_types.h" + /* initialize gizmos */ void ED_gizmotypes_arrow_3d(void); void ED_gizmotypes_button_2d(void); @@ -223,24 +225,6 @@ enum { /* -------------------------------------------------------------------- */ /* Specific gizmos utils */ -/* dial3d_gizmo.c */ - -struct Dial3dParams { - int draw_options; - float angle_ofs; - float angle_delta; - float angle_increment; - float arc_partial_angle; - float arc_inner_factor; - float *clip_plane; -}; -void ED_gizmotypes_dial_3d_draw_util(const float matrix_basis[4][4], - const float matrix_final[4][4], - float line_width, - const float color[4], - bool select, - struct Dial3dParams *params); - /* snap3d_gizmo.c */ struct SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(struct Scene *scene, @@ -258,7 +242,7 @@ void ED_gizmotypes_snap_3d_data_get(const struct bContext *C, float r_loc[3], float r_nor[3], int r_elem_index[3], - int *r_snap_elem); + eSnapMode *r_snap_elem); #ifdef __cplusplus } diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 01f60a81288..b6488d6da56 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -239,7 +239,7 @@ void ED_annotation_draw_ex( /* ----------- Grease-Pencil AnimEdit API ------------------ */ /** - * Loops over the gp-frames for a gp-layer, and applies the given callback. + * Loops over the GP-frames for a GP-layer, and applies the given callback. */ bool ED_gpencil_layer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene, @@ -281,6 +281,11 @@ void ED_gpencil_select_frames(struct bGPDlayer *gpl, short select_mode); void ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode); /** + * Set the layer's channel as active + */ +void ED_gpencil_set_active_channel(struct bGPdata *gpd, struct bGPDlayer *gpl); + +/** * Delete selected frames. */ bool ED_gpencil_layer_frames_delete(struct bGPDlayer *gpl); @@ -579,7 +584,7 @@ void ED_gpencil_init_random_settings(struct Brush *brush, */ bool ED_gpencil_stroke_check_collision(const struct GP_SpaceConversion *gsc, struct bGPDstroke *gps, - const float mouse[2], + const float mval[2], int radius, const float diff_mat[4][4]); /** @@ -587,13 +592,13 @@ bool ED_gpencil_stroke_check_collision(const struct GP_SpaceConversion *gsc, * * \param gps: Stroke to check. * \param gsc: Space conversion data. - * \param mouse: Mouse position. + * \param mval: Region relative cursor position. * \param diff_mat: View matrix. * \return True if the point is inside. */ bool ED_gpencil_stroke_point_is_inside(const struct bGPDstroke *gps, const struct GP_SpaceConversion *gsc, - const int mouse[2], + const int mval[2], const float diff_mat[4][4]); /** * Get the bigger 2D bound box points. diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index f79d3ce205d..91ae8286531 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -24,6 +24,7 @@ struct Scene; struct SpaceImage; struct View2D; struct bContext; +struct Paint; struct wmOperator; struct wmWindowManager; @@ -63,8 +64,11 @@ bool ED_space_image_get_position(struct SpaceImage *sima, /** * Returns color in linear space, matching #ED_space_node_color_sample(). */ -bool ED_space_image_color_sample( - struct SpaceImage *sima, struct ARegion *region, int mval[2], float r_col[3], bool *r_is_data); +bool ED_space_image_color_sample(struct SpaceImage *sima, + struct ARegion *region, + const int mval[2], + float r_col[3], + bool *r_is_data); struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **r_lock, int tile); /** * Get the #SpaceImage flag that is valid for the given ibuf. @@ -133,8 +137,39 @@ bool ED_space_image_paint_curve(const struct bContext *C); * Matches clip function. */ bool ED_space_image_check_show_maskedit(struct SpaceImage *sima, struct Object *obedit); + +/* Returns true when the following conditions are met: + * - Current space is Image Editor. + * - The image editor is not a UV Editor. + * - It is set to Mask mode. + * + * It is not required to have mask opened for editing. */ bool ED_space_image_maskedit_poll(struct bContext *C); + +/* Returns true when the following conditions are met: + * - Current space is Image Editor. + * - The image editor is not a UV Editor. + * - It is set to Mask mode. + * - Mask has visible and editable splines. + * + * It is not required to have mask opened for editing. */ +bool ED_space_image_maskedit_visible_splines_poll(struct bContext *C); + +/* Returns true when the following conditions are met: + * - Current space is Image Editor. + * - The image editor is not an UV Editor. + * - It is set to Mask mode. + * - The space has mask opened. */ bool ED_space_image_maskedit_mask_poll(struct bContext *C); + +/* Returns true when the following conditions are met: + * - Current space is Image Editor. + * - The image editor is not an UV Editor. + * - It is set to Mask mode. + * - The space has mask opened. + * - Mask has visible and editable splines. */ +bool ED_space_image_maskedit_mask_visible_splines_poll(struct bContext *C); + bool ED_space_image_cursor_poll(struct bContext *C); /** @@ -173,6 +208,7 @@ typedef struct ImageFrameRange { int length; int offset; /* UDIM tiles. */ + bool udims_detected; ListBase udim_tiles; /* Temporary data. */ @@ -186,6 +222,9 @@ ListBase ED_image_filesel_detect_sequences(struct Main *bmain, struct wmOperator *op, bool detect_udim); +bool ED_image_tools_paint_poll(struct bContext *C); +void ED_paint_cursor_start(struct Paint *p, bool (*poll)(struct bContext *C)); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 163797d395d..1d63e01c84b 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -229,6 +229,16 @@ typedef enum eKeyMergeMode { KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL, } eKeyMergeMode; +/* Possible errors occurring while pasting keys. */ +typedef enum eKeyPasteError { + /* No errors occurred */ + KEYFRAME_PASTE_OK, + /* Nothing was copied */ + KEYFRAME_PASTE_NOTHING_TO_PASTE, + /* No F-curves was selected to paste into*/ + KEYFRAME_PASTE_NOWHERE_TO_PASTE +} eKeyPasteError; + /** \} */ /* -------------------------------------------------------------------- */ @@ -378,9 +388,6 @@ bool keyframe_region_circle_test(const KeyframeEdit_CircleData *data_circle, con /* ************************************************ */ /* Destructive Editing API (keyframes_general.c) */ -void delete_fcurve_key(struct FCurve *fcu, int index, bool do_recalc); -bool delete_fcurve_keys(struct FCurve *fcu); -void clear_fcurve_keys(struct FCurve *fcu); bool duplicate_fcurve_keys(struct FCurve *fcu); float get_default_rna_value(struct FCurve *fcu, struct PropertyRNA *prop, struct PointerRNA *ptr); @@ -416,11 +423,11 @@ void sample_fcurve(struct FCurve *fcu); void ANIM_fcurves_copybuf_free(void); short copy_animedit_keys(struct bAnimContext *ac, ListBase *anim_data); -short paste_animedit_keys(struct bAnimContext *ac, - ListBase *anim_data, - eKeyPasteOffset offset_mode, - eKeyMergeMode merge_mode, - bool flip); +eKeyPasteError paste_animedit_keys(struct bAnimContext *ac, + ListBase *anim_data, + eKeyPasteOffset offset_mode, + eKeyMergeMode merge_mode, + bool flip); /* ************************************************ */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 8c0147612fb..a53042b70d6 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -658,15 +658,20 @@ bool ED_autokeyframe_pchan(struct bContext *C, struct Object *ob, struct bPoseChannel *pchan, struct KeyingSet *ks); + /** - * Use for auto-key-framing from the UI. + * Use for auto-key-framing + * \param only_if_property_keyed: if true, auto-key-framing only creates keyframes on already keyed + * properties. This is by design when using buttons. For other callers such as gizmos or VSE + * preview transform, creating new animation/keyframes also on non-keyed properties is desired. */ bool ED_autokeyframe_property(struct bContext *C, struct Scene *scene, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, - float cfra); + float cfra, + bool only_if_property_keyed); /* Names for builtin keying sets so we don't confuse these with labels/text, * defined in python script: `keyingsets_builtins.py`. */ diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index 7039d6d9fc7..8cadbfde185 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -22,6 +22,34 @@ struct wmKeyConfig; /* mask_edit.c */ +/* Returns true when the following conditions are met: + * - Current space supports mask editing. + * - The space is configured to interact with mask. + * + * It is not required to have mask opened for editing. */ +bool ED_maskedit_poll(struct bContext *C); + +/* Returns true when the following conditions are met: + * - Current space supports mask editing. + * - The space is configured to interact with mask. + * - Mask has visible and editable splines. + * + * It is not required to have mask opened for editing. */ +bool ED_maskedit_visible_splines_poll(struct bContext *C); + +/* Returns true when the following conditions are met: + * - Current space supports mask editing. + * - The space is configured to interact with mask. + * - The space has mask open for editing. */ +bool ED_maskedit_mask_poll(struct bContext *C); + +/* Returns true when the following conditions are met: + * - Current space supports mask editing. + * - The space is configured to interact with mask. + * - The space has mask opened. + * - Mask has visible and editable splines. */ +bool ED_maskedit_mask_visible_splines_poll(struct bContext *C); + void ED_mask_deselect_all(const struct bContext *C); void ED_operatortypes_mask(void); @@ -73,6 +101,7 @@ void ED_mask_draw_region(struct Depsgraph *depsgraph, char draw_flag, char draw_type, eMaskOverlayMode overlay_mode, + float blend_factor, int width_i, int height_i, float aspx, diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 30a98129ee6..b73b62d5a9d 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -137,7 +137,6 @@ void EDBM_update_extern(struct Mesh *me, bool do_tessellation, bool is_destructi */ struct UvElementMap *BM_uv_element_map_create(struct BMesh *bm, const struct Scene *scene, - bool face_selected, bool uv_selected, bool use_winding, bool do_islands); @@ -425,6 +424,9 @@ void paintvert_select_ungrouped(struct Object *ob, bool extend, bool flush_flags void paintvert_flush_flags(struct Object *ob); void paintvert_tag_select_update(struct bContext *C, struct Object *ob); +void paintvert_hide(struct bContext *C, struct Object *ob, bool unselected); +void paintvert_reveal(struct bContext *C, struct Object *ob, bool select); + /* mirrtopo */ typedef struct MirrTopoStore_t { intptr_t *index_lookup; diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 0078c1087a0..39c7ad3556c 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -536,12 +536,12 @@ bool ED_object_modifier_move_to_index(struct ReportList *reports, struct ModifierData *md, int index); -bool ED_object_modifier_convert(struct ReportList *reports, - struct Main *bmain, - struct Depsgraph *depsgraph, - struct ViewLayer *view_layer, - struct Object *ob, - struct ModifierData *md); +bool ED_object_modifier_convert_psys_to_mesh(struct ReportList *reports, + struct Main *bmain, + struct Depsgraph *depsgraph, + struct ViewLayer *view_layer, + struct Object *ob, + struct ModifierData *md); bool ED_object_modifier_apply(struct Main *bmain, struct ReportList *reports, struct Depsgraph *depsgraph, diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index f909a13c2cb..a24c8625a63 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -595,8 +595,7 @@ bool ED_operator_object_active_local_editable_posemode_exclusive(struct bContext bool ED_operator_posemode_context(struct bContext *C); bool ED_operator_posemode(struct bContext *C); bool ED_operator_posemode_local(struct bContext *C); -bool ED_operator_mask(struct bContext *C); -bool ED_operator_camera(struct bContext *C); +bool ED_operator_camera_poll(struct bContext *C); /* screen_user_menu.c */ diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index 54d67c50d5c..550040d2bc6 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -51,7 +51,7 @@ void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, int new_id); int ED_sculpt_face_sets_active_update_and_get(struct bContext *C, struct Object *ob, - const float mval[2]); + const float mval_fl[2]); /* Undo for changes happening on a base mesh for multires sculpting. * if there is no multi-res sculpt active regular undo is used. */ diff --git a/source/blender/editors/include/ED_select_utils.h b/source/blender/editors/include/ED_select_utils.h index fa02ebe18f6..8c856794ec8 100644 --- a/source/blender/editors/include/ED_select_utils.h +++ b/source/blender/editors/include/ED_select_utils.h @@ -40,11 +40,11 @@ typedef enum { } eSelectOp; /* Select Similar */ -enum { +typedef enum { SIM_CMP_EQ = 0, SIM_CMP_GT, SIM_CMP_LT, -}; +} eSimilarCmp; #define SEL_OP_USE_OUTSIDE(sel_op) (ELEM(sel_op, SEL_OP_AND)) #define SEL_OP_USE_PRE_DESELECT(sel_op) (ELEM(sel_op, SEL_OP_SET)) @@ -63,11 +63,11 @@ int ED_select_op_action(eSelectOp sel_op, bool is_select, bool is_inside); */ int ED_select_op_action_deselected(eSelectOp sel_op, bool is_select, bool is_inside); -int ED_select_similar_compare_float(float delta, float thresh, int compare); +bool ED_select_similar_compare_float(float delta, float thresh, eSimilarCmp compare); bool ED_select_similar_compare_float_tree(const struct KDTree_1d *tree, float length, float thresh, - int compare); + eSimilarCmp compare); /** * Utility to use for selection operations that run multiple times (circle select). diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h index 2919001c5ce..db44d9af706 100644 --- a/source/blender/editors/include/ED_transform_snap_object_context.h +++ b/source/blender/editors/include/ED_transform_snap_object_context.h @@ -6,6 +6,8 @@ #pragma once +#include "DNA_scene_types.h" + #ifdef __cplusplus extern "C" { #endif @@ -25,14 +27,6 @@ struct View3D; /* ED_transform_snap_object_*** API */ -typedef enum eSnapSelect { - SNAP_ALL = 0, - SNAP_NOT_SELECTED = 1, - SNAP_NOT_ACTIVE = 2, - SNAP_NOT_EDITED = 3, - SNAP_SELECTABLE = 4, -} eSnapSelect; - typedef enum eSnapEditType { SNAP_GEOM_FINAL = 0, SNAP_GEOM_CAGE = 1, @@ -59,13 +53,17 @@ struct SnapObjectHitDepth { /** parameters that define which objects will be used to snap. */ struct SnapObjectParams { /* Special context sensitive handling for the active or selected object. */ - eSnapSelect snap_select; + eSnapTargetSelect snap_target_select; /* Geometry for snapping in edit mode. */ eSnapEditType edit_mode_type; /* snap to the closest element, use when using more than one snap type */ bool use_occlusion_test : true; /* exclude back facing geometry from snapping */ bool use_backface_culling : true; + /* Break nearest face snapping into steps to improve transformations across U-shaped targets. */ + short face_nearest_steps; + /* Enable to force nearest face snapping to snap to target the source was initially near. */ + bool keep_on_same_target; }; typedef struct SnapObjectContext SnapObjectContext; @@ -120,46 +118,71 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx, bool sort, struct ListBase *r_hit_list); -short ED_transform_snap_object_project_view3d_ex(struct SnapObjectContext *sctx, - struct Depsgraph *depsgraph, - const ARegion *region, - const View3D *v3d, - unsigned short snap_to, - const struct SnapObjectParams *params, - const float mval[2], - const float prev_co[3], - float *dist_px, - float r_loc[3], - float r_no[3], - int *r_index, - struct Object **r_ob, - float r_obmat[4][4], - float r_face_nor[3]); +/** + * Perform snapping. + * + * Given a 2D region value, snap to vert/edge/face/grid. + * + * \param sctx: Snap context. + * \param snap_to: Target elements to snap source to. + * \param params: Addition snapping options. + * \param init_co: Initial world-space coordinate of source (optional). + * \param mval: Current transformed screen-space coordinate or mouse position (optional). + * \param prev_co: Current transformed world-space coordinate of source (optional). + * \param dist_px: Maximum distance to snap (in pixels). + * \param r_loc: Snapped world-space coordinate. + * \param r_no: Snapped world-space normal (optional). + * \param r_index: Index of snapped-to target element (optional). + * \param r_ob: Snapped-to target object (optional). + * \param r_obmat: Matrix of snapped-to target object (optional). + * \param r_face_nor: World-space normal of snapped-to target face (optional). + * \return Snapped-to element, #eSnapMode. + */ +eSnapMode ED_transform_snap_object_project_view3d_ex(struct SnapObjectContext *sctx, + struct Depsgraph *depsgraph, + const ARegion *region, + const View3D *v3d, + const eSnapMode snap_to, + const struct SnapObjectParams *params, + const float init_co[3], + const float mval[2], + const float prev_co[3], + float *dist_px, + float r_loc[3], + float r_no[3], + int *r_index, + struct Object **r_ob, + float r_obmat[4][4], + float r_face_nor[3]); /** * Convenience function for performing snapping. * * Given a 2D region value, snap to vert/edge/face. * * \param sctx: Snap context. - * \param mval: Screenspace coordinate. - * \param prev_co: Coordinate for perpendicular point calculation (optional). + * \param snap_to: Target elements to snap source to. + * \param params: Addition snapping options. + * \param init_co: Initial world-space coordinate of source (optional). + * \param mval: Current transformed screen-space coordinate or mouse position (optional). + * \param prev_co: Current transformed world-space coordinate of source (optional). * \param dist_px: Maximum distance to snap (in pixels). - * \param r_loc: hit location. - * \param r_no: hit normal (optional). - * \return Snap success. + * \param r_loc: Snapped world-space coordinate. + * \param r_no: Snapped world-space normal (optional). + * \return Snapped-to element, #eSnapMode. */ -short ED_transform_snap_object_project_view3d(struct SnapObjectContext *sctx, - struct Depsgraph *depsgraph, - const ARegion *region, - const View3D *v3d, - unsigned short snap_to, - const struct SnapObjectParams *params, - const float mval[2], - const float prev_co[3], - float *dist_px, - /* return args */ - float r_loc[3], - float r_no[3]); +eSnapMode ED_transform_snap_object_project_view3d(struct SnapObjectContext *sctx, + struct Depsgraph *depsgraph, + const ARegion *region, + const View3D *v3d, + const eSnapMode snap_to, + const struct SnapObjectParams *params, + const float init_co[3], + const float mval[2], + const float prev_co[3], + float *dist_px, + /* return args */ + float r_loc[3], + float r_no[3]); /** * see: #ED_transform_snap_object_project_ray_all diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 8695e03a57f..0298983ed26 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -8,6 +8,7 @@ #pragma once #include "BLI_utildefines.h" +#include "DNA_scene_types.h" #ifdef __cplusplus extern "C" { @@ -299,7 +300,7 @@ typedef enum { } eV3DPlaceOrient; typedef struct V3DSnapCursorData { - short snap_elem; + eSnapMode snap_elem; float loc[3]; float nor[3]; float obmat[4][4]; @@ -322,7 +323,7 @@ typedef struct V3DSnapCursorState { struct wmGizmoGroupType *gzgrp_type; /* Force cursor to be drawn only when gizmo is available. */ float *prevpoint; float box_dimensions[3]; - short snap_elem_force; /* If zero, use scene settings. */ + eSnapMode snap_elem_force; /* If SCE_SNAP_MODE_NONE, use scene settings. */ short plane_axis; bool use_plane_axis_auto; bool draw_point; @@ -347,7 +348,7 @@ void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d, const float normal[3], const uchar color_line[4], const uchar color_point[4], - short snap_elem_type); + eSnapMode snap_elem_type); /* view3d_iterators.c */ diff --git a/source/blender/editors/include/UI_abstract_view.hh b/source/blender/editors/include/UI_abstract_view.hh new file mode 100644 index 00000000000..dfddace8899 --- /dev/null +++ b/source/blender/editors/include/UI_abstract_view.hh @@ -0,0 +1,280 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup editorui + * + * Base class for all views (UIs to display data sets) and view items, supporting common features. + * https://wiki.blender.org/wiki/Source/Interface/Views + * + * One of the most important responsibilities of the base class is managing reconstruction, + * enabling state that is persistent over reconstructions/redraws. Other features: + * - Renaming + * - Custom context menus + * - Notifier listening + * - Drag controllers (dragging view items) + * - Drop controllers (dropping onto/into view items) + */ + +#pragma once + +#include <array> +#include <memory> + +#include "DNA_defs.h" + +#include "BLI_span.hh" +#include "BLI_string_ref.hh" + +struct bContext; +struct uiBlock; +struct uiBut; +struct uiLayout; +struct uiViewItemHandle; +struct wmDrag; +struct wmNotifier; + +namespace blender::ui { + +class AbstractViewItem; +class AbstractViewItemDropController; +class AbstractViewItemDragController; + +class AbstractView { + friend class AbstractViewItem; + + bool is_reconstructed_ = false; + /** + * Only one item can be renamed at a time. So rather than giving each item an own rename buffer + * (which just adds unused memory in most cases), have one here that is managed by the view. + * + * This fixed-size buffer is needed because that's what the rename button requires. In future we + * may be able to bind the button to a `std::string` or similar. + */ + std::unique_ptr<std::array<char, MAX_NAME>> rename_buffer_; + + public: + virtual ~AbstractView() = default; + + /** Listen to a notifier, returning true if a redraw is needed. */ + virtual bool listen(const wmNotifier &) const; + + /** + * Makes \a item valid for display in this view. Behavior is undefined for items not registered + * with this. + */ + void register_item(AbstractViewItem &item); + + /** Only one item can be renamed at a time. */ + bool is_renaming() const; + /** \return If renaming was started successfully. */ + bool begin_renaming(); + void end_renaming(); + Span<char> get_rename_buffer() const; + MutableSpan<char> get_rename_buffer(); + + protected: + AbstractView() = default; + + virtual void update_children_from_old(const AbstractView &old_view) = 0; + + /** + * Match the view and its items against an earlier version of itself (if any) and copy the old UI + * state (e.g. collapsed, active, selected, renaming, etc.) to the new one. See + * #AbstractViewItem.update_from_old(). + * After this, reconstruction is complete (see #is_reconstructed()). + */ + void update_from_old(uiBlock &new_block); + /** + * Check if the view is fully (re-)constructed. That means, both the build function and + * #update_from_old() have finished. + */ + bool is_reconstructed() const; +}; + +class AbstractViewItem { + friend class AbstractView; + friend class ViewItemAPIWrapper; + + protected: + /** + * The view this item is a part of, and was registered for using #AbstractView::register_item(). + * If this wasn't done, the behavior of items is undefined. + */ + AbstractView *view_ = nullptr; + bool is_active_ = false; + bool is_renaming_ = false; + + public: + virtual ~AbstractViewItem() = default; + + virtual void build_context_menu(bContext &C, uiLayout &column) const; + + /** + * Queries if the view item supports renaming in principle. Renaming may still fail, e.g. if + * another item is already being renamed. + */ + virtual bool supports_renaming() const; + /** + * Try renaming the item, or the data it represents. Can assume + * #AbstractViewItem::supports_renaming() returned true. Sub-classes that override this should + * usually call this, unless they have a custom #AbstractViewItem.matches() implementation. + * + * \return True if the renaming was successful. + */ + virtual bool rename(StringRefNull new_name); + /** + * Get the string that should be used for renaming, typically the item's label. This string will + * not be modified, but if the renaming is canceled, the value will be reset to this. + */ + virtual StringRef get_rename_string() const; + + /** + * If an item wants to support being dragged, it has to return a drag controller here. + * That is an object implementing #AbstractViewItemDragController. + */ + virtual std::unique_ptr<AbstractViewItemDragController> create_drag_controller() const; + /** + * If an item wants to support dropping data into it, it has to return a drop controller here. + * That is an object implementing #AbstractViewItemDropController. + * + * \note This drop controller may be requested for each event. The view doesn't keep a drop + * controller around currently. So it can not contain persistent state. + */ + virtual std::unique_ptr<AbstractViewItemDropController> create_drop_controller() const; + + /** Get the view this item is registered for using #AbstractView::register_item(). */ + AbstractView &get_view() const; + + /** + * Requires the view to have completed reconstruction, see #is_reconstructed(). Otherwise we + * can't be sure about the item state. + */ + bool is_active() const; + + bool is_renaming() const; + void begin_renaming(); + void end_renaming(); + void rename_apply(); + + template<typename ToType = AbstractViewItem> + static ToType *from_item_handle(uiViewItemHandle *handle); + + protected: + AbstractViewItem() = default; + + /** + * Compare this item's identity to \a other to check if they represent the same data. + * Implementations can assume that the types match already (caller must check). + * + * Used to recognize an item from a previous redraw, to be able to keep its state (e.g. active, + * renaming, etc.). + */ + virtual bool matches(const AbstractViewItem &other) const = 0; + + /** + * Copy persistent state (e.g. active, selection, etc.) from a matching item of + * the last redraw to this item. If sub-classes introduce more advanced state they should + * override this and make it update their state accordingly. + * + * \note Always call the base class implementation when overriding this! + */ + virtual void update_from_old(const AbstractViewItem &old); + + /** + * Add a text button for renaming the item to \a block. This must be used for the built-in + * renaming to work. This button is meant to appear temporarily. It is removed when renaming is + * done. + */ + void add_rename_button(uiBlock &block); +}; + +template<typename ToType> ToType *AbstractViewItem::from_item_handle(uiViewItemHandle *handle) +{ + static_assert(std::is_base_of<AbstractViewItem, ToType>::value, + "Type must derive from and implement the AbstractViewItem interface"); + + return dynamic_cast<ToType *>(reinterpret_cast<AbstractViewItem *>(handle)); +} + +/* ---------------------------------------------------------------------- */ +/** \name Drag 'n Drop + * \{ */ + +/** + * Class to enable dragging a view item. An item can return a drop controller for itself by + * implementing #AbstractViewItem::create_drag_controller(). + */ +class AbstractViewItemDragController { + protected: + AbstractView &view_; + + public: + AbstractViewItemDragController(AbstractView &view); + virtual ~AbstractViewItemDragController() = default; + + virtual int get_drag_type() const = 0; + virtual void *create_drag_data() const = 0; + virtual void on_drag_start(); + + /** Request the view the item is registered for as type #ViewType. Throws a `std::bad_cast` + * exception if the view is not of the requested type. */ + template<class ViewType> inline ViewType &get_view() const; +}; + +/** + * Class to define the behavior when dropping something onto/into a view item, plus the behavior + * when dragging over this item. An item can return a drop controller for itself via a custom + * implementation of #AbstractViewItem::create_drop_controller(). + */ +class AbstractViewItemDropController { + protected: + AbstractView &view_; + + public: + AbstractViewItemDropController(AbstractView &view); + virtual ~AbstractViewItemDropController() = default; + + /** + * Check if the data dragged with \a drag can be dropped on the item this controller is for. + * \param r_disabled_hint: Return a static string to display to the user, explaining why dropping + * isn't possible on this item. Shouldn't be done too aggressively, e.g. + * don't set this if the drag-type can't be dropped here; only if it can + * but there's another reason it can't be dropped. + * Can assume this is a non-null pointer. + */ + virtual bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const = 0; + /** + * Custom text to display when dragging over a view item. Should explain what happens when + * dropping the data onto this item. Will only be used if #AbstractViewItem::can_drop() + * returns true, so the implementing override doesn't have to check that again. + * The returned value must be a translated string. + */ + virtual std::string drop_tooltip(const wmDrag &drag) const = 0; + /** + * Execute the logic to apply a drop of the data dragged with \a drag onto/into the item this + * controller is for. + */ + virtual bool on_drop(struct bContext *C, const wmDrag &drag) = 0; + + /** Request the view the item is registered for as type #ViewType. Throws a `std::bad_cast` + * exception if the view is not of the requested type. */ + template<class ViewType> inline ViewType &get_view() const; +}; + +template<class ViewType> ViewType &AbstractViewItemDragController::get_view() const +{ + static_assert(std::is_base_of<AbstractView, ViewType>::value, + "Type must derive from and implement the ui::AbstractView interface"); + return dynamic_cast<ViewType &>(view_); +} + +template<class ViewType> ViewType &AbstractViewItemDropController::get_view() const +{ + static_assert(std::is_base_of<AbstractView, ViewType>::value, + "Type must derive from and implement the ui::AbstractView interface"); + return dynamic_cast<ViewType &>(view_); +} + +/** \} */ + +} // namespace blender::ui diff --git a/source/blender/editors/include/UI_grid_view.hh b/source/blender/editors/include/UI_grid_view.hh index 6f553f4fad1..402c0c8512f 100644 --- a/source/blender/editors/include/UI_grid_view.hh +++ b/source/blender/editors/include/UI_grid_view.hh @@ -13,12 +13,13 @@ #include "BLI_map.hh" #include "BLI_vector.hh" +#include "UI_abstract_view.hh" #include "UI_resources.h" struct bContext; struct PreviewImage; struct uiBlock; -struct uiButGridTile; +struct uiButViewItem; struct uiLayout; struct View2D; struct wmNotifier; @@ -31,43 +32,29 @@ class AbstractGridView; /** \name Grid-View Item Type * \{ */ -class AbstractGridViewItem { +class AbstractGridViewItem : public AbstractViewItem { friend class AbstractGridView; friend class GridViewLayoutBuilder; - const AbstractGridView *view_; - - bool is_active_ = false; - protected: /** Reference to a string that uniquely identifies this item in the view. */ StringRef identifier_{}; - /** Every visible item gets a button of type #UI_BTYPE_GRID_TILE during the layout building. */ - uiButGridTile *grid_tile_but_ = nullptr; + /** Every visible item gets a button of type #UI_BTYPE_VIEW_ITEM during the layout building. */ + uiButViewItem *view_item_but_ = nullptr; public: virtual ~AbstractGridViewItem() = default; virtual void build_grid_tile(uiLayout &layout) const = 0; - /** - * Compare this item's identifier to \a other to check if they represent the same data. - * Used to recognize an item from a previous redraw, to be able to keep its state (e.g. active, - * renaming, etc.). - */ - bool matches(const AbstractGridViewItem &other) const; - const AbstractGridView &get_view() const; - /** - * Requires the tree to have completed reconstruction, see #is_reconstructed(). Otherwise we - * can't be sure about the item state. - */ - bool is_active() const; - protected: AbstractGridViewItem(StringRef identifier); + /** See AbstractViewItem::matches(). */ + virtual bool matches(const AbstractViewItem &other) const override; + /** Called when the item's state changes from inactive to active. */ virtual void on_activate(); /** @@ -77,13 +64,6 @@ class AbstractGridViewItem { virtual std::optional<bool> should_be_active() const; /** - * Copy persistent state (e.g. active, selection, etc.) from a matching item of - * the last redraw to this item. If sub-classes introduce more advanced state they should - * override this and make it update their state accordingly. - */ - virtual void update_from_old(const AbstractGridViewItem &old); - - /** * Activates this item, deactivates other items, and calls the * #AbstractGridViewItem::on_activate() function. * Requires the tree to have completed reconstruction, see #is_reconstructed(). Otherwise the @@ -111,7 +91,7 @@ struct GridViewStyle { int tile_height = 0; }; -class AbstractGridView { +class AbstractGridView : public AbstractView { friend class AbstractGridViewItem; friend class GridViewBuilder; friend class GridViewLayoutBuilder; @@ -122,7 +102,6 @@ class AbstractGridView { * #update_from_old(). */ Map<StringRef, AbstractGridViewItem *> item_map_; GridViewStyle style_; - bool is_reconstructed_ = false; public: AbstractGridView(); @@ -131,9 +110,6 @@ class AbstractGridView { using ItemIterFn = FunctionRef<void(AbstractGridViewItem &)>; void foreach_item(ItemIterFn iter_fn) const; - /** Listen to a notifier, returning true if a redraw is needed. */ - virtual bool listen(const wmNotifier &) const; - /** * Convenience wrapper constructing the item by forwarding given arguments to the constructor of * the type (\a ItemT). @@ -154,19 +130,8 @@ class AbstractGridView { protected: virtual void build_items() = 0; - /** - * Check if the view is fully (re-)constructed. That means, both #build_items() and - * #update_from_old() have finished. - */ - bool is_reconstructed() const; - private: - /** - * Match the grid-view against an earlier version of itself (if any) and copy the old UI state - * (e.g. active, selected, renaming, etc.) to the new one. See - * #AbstractGridViewItem.update_from_old(). - */ - void update_from_old(uiBlock &new_block); + void update_children_from_old(const AbstractView &old_view) override; AbstractGridViewItem *find_matching_item(const AbstractGridViewItem &item_to_match, const AbstractGridView &view_to_search_in) const; /** diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index ea1095b26ff..09057fd846e 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -652,7 +652,7 @@ DEF_ICON(PARTICLE_TIP) DEF_ICON(PARTICLE_PATH) /* EDITING */ -DEF_ICON_BLANK(669) +DEF_ICON(SNAP_FACE_NEAREST) DEF_ICON(SNAP_FACE_CENTER) DEF_ICON(SNAP_PERPENDICULAR) DEF_ICON(SNAP_MIDPOINT) @@ -891,6 +891,7 @@ DEF_ICON_COLOR(BRUSH_LAYER) DEF_ICON_COLOR(BRUSH_MASK) DEF_ICON_COLOR(BRUSH_MIX) DEF_ICON_COLOR(BRUSH_NUDGE) +DEF_ICON_COLOR(BRUSH_PAINT_SELECT) DEF_ICON_COLOR(BRUSH_PINCH) DEF_ICON_COLOR(BRUSH_SCRAPE) DEF_ICON_COLOR(BRUSH_SCULPT_DRAW) @@ -903,7 +904,6 @@ DEF_ICON_COLOR(BRUSH_TEXFILL) DEF_ICON_COLOR(BRUSH_TEXMASK) DEF_ICON_COLOR(BRUSH_THUMB) DEF_ICON_COLOR(BRUSH_ROTATE) -DEF_ICON_COLOR(BRUSH_PAINT) /* grease pencil sculpt */ DEF_ICON_COLOR(GPBRUSH_SMOOTH) @@ -929,6 +929,19 @@ DEF_ICON_COLOR(GPBRUSH_ERASE_SOFT) DEF_ICON_COLOR(GPBRUSH_ERASE_HARD) DEF_ICON_COLOR(GPBRUSH_ERASE_STROKE) +/* Curves sculpt. */ +DEF_ICON_COLOR(BRUSH_CURVES_ADD) +DEF_ICON_COLOR(BRUSH_CURVES_COMB) +DEF_ICON_COLOR(BRUSH_CURVES_CUT) +DEF_ICON_COLOR(BRUSH_CURVES_DELETE) +DEF_ICON_COLOR(BRUSH_CURVES_DENSITY) +DEF_ICON_COLOR(BRUSH_CURVES_GROW_SHRINK) +DEF_ICON_COLOR(BRUSH_CURVES_PINCH) +DEF_ICON_COLOR(BRUSH_CURVES_PUFF) +DEF_ICON_COLOR(BRUSH_CURVES_SLIDE) +DEF_ICON_COLOR(BRUSH_CURVES_SMOOTH) +DEF_ICON_COLOR(BRUSH_CURVES_SNAKE_HOOK) + /* Vector icons. */ DEF_ICON_VECTOR(KEYTYPE_KEYFRAME_VEC) DEF_ICON_VECTOR(KEYTYPE_BREAKDOWN_VEC) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 8503779f629..a8d25b75036 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -72,14 +72,10 @@ typedef struct uiBut uiBut; typedef struct uiButExtraOpIcon uiButExtraOpIcon; typedef struct uiLayout uiLayout; typedef struct uiPopupBlockHandle uiPopupBlockHandle; -/* C handle for C++ #ui::AbstractTreeView type. */ -typedef struct uiTreeViewHandle uiTreeViewHandle; -/* C handle for C++ #ui::AbstractTreeViewItem type. */ -typedef struct uiTreeViewItemHandle uiTreeViewItemHandle; -/* C handle for C++ #ui::AbstractGridView type. */ -typedef struct uiGridViewHandle uiGridViewHandle; -/* C handle for C++ #ui::AbstractGridViewItem type. */ -typedef struct uiGridViewItemHandle uiGridViewItemHandle; +/* C handle for C++ #ui::AbstractView type. */ +typedef struct uiViewHandle uiViewHandle; +/* C handle for C++ #ui::AbstractViewItem type. */ +typedef struct uiViewItemHandle uiViewItemHandle; /* Defines */ @@ -393,10 +389,8 @@ typedef enum { /** Resize handle (resize uilist). */ UI_BTYPE_GRIP = 57 << 9, UI_BTYPE_DECORATOR = 58 << 9, - /* An item in a tree view. Parent items may be collapsible. */ - UI_BTYPE_TREEROW = 59 << 9, - /* An item in a grid view. */ - UI_BTYPE_GRID_TILE = 60 << 9, + /* An item a view (see #ui::AbstractViewItem). */ + UI_BTYPE_VIEW_ITEM = 59 << 9, } eButType; #define BUTTYPE (63 << 9) @@ -858,33 +852,6 @@ void UI_block_translate(uiBlock *block, int x, int y); int UI_but_return_value_get(uiBut *but); -void UI_but_drag_set_id(uiBut *but, struct ID *id); -/** - * Set an image to display while dragging. This works for any drag type (`WM_DRAG_XXX`). - * Not to be confused with #UI_but_drag_set_image(), which sets up dragging of an image. - */ -void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, float scale); -/** - * \param asset: May be passed from a temporary variable, drag data only stores a copy of this. - */ -void UI_but_drag_set_asset(uiBut *but, - const struct AssetHandle *asset, - const char *path, - struct AssetMetaData *metadata, - int import_type, /* eFileAssetImportType */ - int icon, - struct ImBuf *imb, - float scale); -void UI_but_drag_set_rna(uiBut *but, struct PointerRNA *ptr); -void UI_but_drag_set_path(uiBut *but, const char *path, bool use_free); -void UI_but_drag_set_name(uiBut *but, const char *name); -/** - * Value from button itself. - */ -void UI_but_drag_set_value(uiBut *but); -void UI_but_drag_set_image( - uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale, bool use_free); - uiBut *UI_but_active_drop_name_button(const struct bContext *C); /** * Returns true if highlighted button allows drop of names. @@ -1714,8 +1681,6 @@ int UI_search_items_find_index(uiSearchItems *items, const char *name); */ void UI_but_hint_drawstr_set(uiBut *but, const char *string); -void UI_but_treerow_indentation_set(uiBut *but, int indentation); - void UI_but_node_link_set(uiBut *but, struct bNodeSocket *socket, const float draw_color[4]); void UI_but_number_step_size_set(uiBut *but, float step_size); @@ -1774,6 +1739,14 @@ struct PointerRNA *UI_but_extra_operator_icon_add(uiBut *but, struct wmOperatorType *UI_but_extra_operator_icon_optype_get(struct uiButExtraOpIcon *extra_icon); struct PointerRNA *UI_but_extra_operator_icon_opptr_get(struct uiButExtraOpIcon *extra_icon); +/** + * A decent size for a button (typically #UI_BTYPE_PREVIEW_TILE) to display a nicely readable + * preview with label in. + */ +int UI_preview_tile_size_x(void); +int UI_preview_tile_size_y(void); +int UI_preview_tile_size_y_no_label(void); + /* Autocomplete * * Tab complete helper functions, for use in uiButCompleteFunc callbacks. @@ -1790,13 +1763,37 @@ AutoComplete *UI_autocomplete_begin(const char *startname, size_t maxlen); void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name); int UI_autocomplete_end(AutoComplete *autocpl, char *autoname); +/* Button drag-data (interface_drag.cc). + * + * Functions to set drag data for buttons. This enables dragging support, whereby the drag data is + * "dragged", not the button itself. */ + +void UI_but_drag_set_id(uiBut *but, struct ID *id); /** - * A decent size for a button (typically #UI_BTYPE_PREVIEW_TILE) to display a nicely readable - * preview with label in. + * Set an image to display while dragging. This works for any drag type (`WM_DRAG_XXX`). + * Not to be confused with #UI_but_drag_set_image(), which sets up dragging of an image. */ -int UI_preview_tile_size_x(void); -int UI_preview_tile_size_y(void); -int UI_preview_tile_size_y_no_label(void); +void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, float scale); +/** + * \param asset: May be passed from a temporary variable, drag data only stores a copy of this. + */ +void UI_but_drag_set_asset(uiBut *but, + const struct AssetHandle *asset, + const char *path, + struct AssetMetaData *metadata, + int import_type, /* eFileAssetImportType */ + int icon, + struct ImBuf *imb, + float scale); +void UI_but_drag_set_rna(uiBut *but, struct PointerRNA *ptr); +void UI_but_drag_set_path(uiBut *but, const char *path, bool use_free); +void UI_but_drag_set_name(uiBut *but, const char *name); +/** + * Value from button itself. + */ +void UI_but_drag_set_value(uiBut *but); +void UI_but_drag_set_image( + uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale, bool use_free); /* Panels * @@ -1881,7 +1878,7 @@ struct PointerRNA *UI_region_panel_custom_data_under_cursor(const struct bContex const struct wmEvent *event); void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_data); -/* Polyinstantiated panels for representing a list of data. */ +/* Poly-instantiated panels for representing a list of data. */ /** * Called in situations where panels need to be added dynamically rather than * having only one panel corresponding to each #PanelType. @@ -3198,54 +3195,44 @@ void UI_interface_tag_script_reload(void); void UI_block_views_listen(const uiBlock *block, const struct wmRegionListenerParams *listener_params); -bool UI_grid_view_item_is_active(const uiGridViewItemHandle *item_handle); -bool UI_tree_view_item_is_active(const uiTreeViewItemHandle *item); -bool UI_grid_view_item_matches(const uiGridViewItemHandle *a, const uiGridViewItemHandle *b); -bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a, const uiTreeViewItemHandle *b); +bool UI_view_item_is_active(const uiViewItemHandle *item_handle); +bool UI_view_item_matches(const uiViewItemHandle *a_handle, const uiViewItemHandle *b_handle); /** - * Attempt to start dragging the tree-item \a item_. This will not work if the tree item doesn't - * support dragging, i.e. it won't create a drag-controller upon request. - * \return True if dragging started successfully, otherwise false. - */ -bool UI_tree_view_item_drag_start(struct bContext *C, uiTreeViewItemHandle *item_); -bool UI_tree_view_item_can_drop(const uiTreeViewItemHandle *item_, - const struct wmDrag *drag, - const char **r_disabled_hint); -char *UI_tree_view_item_drop_tooltip(const uiTreeViewItemHandle *item, const struct wmDrag *drag); -/** - * Let a tree-view item handle a drop event. - * \return True if the drop was handled by the tree-view item. - */ -bool UI_tree_view_item_drop_handle(struct bContext *C, - const uiTreeViewItemHandle *item_, - const struct ListBase *drags); -/** - * Can \a item_handle be renamed right now? Not that this isn't just a mere wrapper around - * #AbstractTreeViewItem::can_rename(). This also checks if there is another item being renamed, + * Can \a item_handle be renamed right now? Note that this isn't just a mere wrapper around + * #AbstractViewItem::supports_renaming(). This also checks if there is another item being renamed, * and returns false if so. */ -bool UI_tree_view_item_can_rename(const uiTreeViewItemHandle *item_handle); -void UI_tree_view_item_begin_rename(uiTreeViewItemHandle *item_handle); +bool UI_view_item_can_rename(const uiViewItemHandle *item_handle); +void UI_view_item_begin_rename(uiViewItemHandle *item_handle); -void UI_tree_view_item_context_menu_build(struct bContext *C, - const uiTreeViewItemHandle *item, - uiLayout *column); +void UI_view_item_context_menu_build(struct bContext *C, + const uiViewItemHandle *item_handle, + uiLayout *column); /** - * \param xy: Coordinate to find a tree-row item at, in window space. + * Attempt to start dragging \a item_. This will not work if the view item doesn't + * support dragging, i.e. if it won't create a drag-controller upon request. + * \return True if dragging started successfully, otherwise false. */ -uiTreeViewItemHandle *UI_block_tree_view_find_item_at(const struct ARegion *region, - const int xy[2]) ATTR_NONNULL(1, 2); -uiTreeViewItemHandle *UI_block_tree_view_find_active_item(const struct ARegion *region); - +bool UI_view_item_drag_start(struct bContext *C, const uiViewItemHandle *item_); +bool UI_view_item_can_drop(const uiViewItemHandle *item_, + const struct wmDrag *drag, + const char **r_disabled_hint); +char *UI_view_item_drop_tooltip(const uiViewItemHandle *item, const struct wmDrag *drag); /** - * Listen to \a notifier, returning true if the region should redraw. + * Let a view item handle a drop event. + * \return True if the drop was handled by the view item. */ -bool UI_tree_view_listen_should_redraw(const uiTreeViewHandle *view, const wmNotifier *notifier); +bool UI_view_item_drop_handle(struct bContext *C, + const uiViewItemHandle *item_, + const struct ListBase *drags); + /** - * Listen to \a notifier, returning true if the region should redraw. + * \param xy: Coordinate to find a view item at, in window space. */ -bool UI_grid_view_listen_should_redraw(const uiGridViewHandle *view, const wmNotifier *notifier); +uiViewItemHandle *UI_region_views_find_item_at(const struct ARegion *region, const int xy[2]) + ATTR_NONNULL(); +uiViewItemHandle *UI_region_views_find_active_item(const struct ARegion *region); #ifdef __cplusplus } diff --git a/source/blender/editors/include/UI_interface.hh b/source/blender/editors/include/UI_interface.hh index 3dc56b01993..82bfdd7e212 100644 --- a/source/blender/editors/include/UI_interface.hh +++ b/source/blender/editors/include/UI_interface.hh @@ -46,7 +46,7 @@ void template_breadcrumbs(uiLayout &layout, Span<ContextPathItem> context_path); void attribute_search_add_items( StringRefNull str, - bool is_output, + bool can_create_attribute, Span<const nodes::geometry_nodes_eval_log::GeometryAttributeInfo *> infos, uiSearchItems *items, bool is_first); @@ -54,12 +54,12 @@ void attribute_search_add_items( } // namespace blender::ui /** - * Override this for all available tree types. + * Override this for all available view types. */ blender::ui::AbstractGridView *UI_block_add_view( uiBlock &block, blender::StringRef idname, - std::unique_ptr<blender::ui::AbstractGridView> tree_view); + std::unique_ptr<blender::ui::AbstractGridView> grid_view); blender::ui::AbstractTreeView *UI_block_add_view( uiBlock &block, blender::StringRef idname, diff --git a/source/blender/editors/include/UI_tree_view.hh b/source/blender/editors/include/UI_tree_view.hh index 1aeb13ca5cc..872a6085060 100644 --- a/source/blender/editors/include/UI_tree_view.hh +++ b/source/blender/editors/include/UI_tree_view.hh @@ -9,7 +9,6 @@ #pragma once -#include <array> #include <functional> #include <memory> #include <string> @@ -19,23 +18,19 @@ #include "BLI_function_ref.hh" #include "BLI_vector.hh" +#include "UI_abstract_view.hh" #include "UI_resources.h" struct bContext; struct uiBlock; struct uiBut; -struct uiButTreeRow; +struct uiButViewItem; struct uiLayout; -struct wmDrag; -struct wmEvent; -struct wmNotifier; namespace blender::ui { class AbstractTreeView; class AbstractTreeViewItem; -class AbstractTreeViewItemDropController; -class AbstractTreeViewItemDragController; /* ---------------------------------------------------------------------- */ /** \name Tree-View Item Container @@ -112,45 +107,20 @@ using TreeViewOrItem = TreeViewItemContainer; /** \name Tree-View Base Class * \{ */ -class AbstractTreeView : public TreeViewItemContainer { +class AbstractTreeView : public AbstractView, public TreeViewItemContainer { friend class AbstractTreeViewItem; friend class TreeViewBuilder; - /** - * Only one item can be renamed at a time. So the tree is informed about the renaming state to - * enforce that. - */ - std::unique_ptr<std::array<char, MAX_NAME>> rename_buffer_; - - bool is_reconstructed_ = false; - public: virtual ~AbstractTreeView() = default; void foreach_item(ItemIterFn iter_fn, IterOptions options = IterOptions::None) const; - /** Listen to a notifier, returning true if a redraw is needed. */ - virtual bool listen(const wmNotifier &) const; - - /** Only one item can be renamed at a time. */ - bool is_renaming() const; - protected: virtual void build_tree() = 0; - /** - * Check if the tree is fully (re-)constructed. That means, both #build_tree() and - * #update_from_old() have finished. - */ - bool is_reconstructed() const; - private: - /** - * Match the tree-view against an earlier version of itself (if any) and copy the old UI state - * (e.g. collapsed, active, selected, renaming, etc.) to the new one. See - * #AbstractTreeViewItem.update_from_old(). - */ - void update_from_old(uiBlock &new_block); + void update_children_from_old(const AbstractView &old_view) override; static void update_children_from_old_recursive(const TreeViewOrItem &new_items, const TreeViewOrItem &old_items); static AbstractTreeViewItem *find_matching_child(const AbstractTreeViewItem &lookup_item, @@ -177,7 +147,7 @@ class AbstractTreeView : public TreeViewItemContainer { * It also stores state information that needs to be persistent over redraws, like the collapsed * state. */ -class AbstractTreeViewItem : public TreeViewItemContainer { +class AbstractTreeViewItem : public AbstractViewItem, public TreeViewItemContainer { friend class AbstractTreeView; friend class TreeViewLayoutBuilder; /* Higher-level API. */ @@ -185,20 +155,17 @@ class AbstractTreeViewItem : public TreeViewItemContainer { private: bool is_open_ = false; - bool is_active_ = false; - bool is_renaming_ = false; protected: /** This label is used as the default way to identifying an item within its parent. */ std::string label_{}; - /** Every visible item gets a button of type #UI_BTYPE_TREEROW during the layout building. */ - uiButTreeRow *tree_row_but_ = nullptr; + /** Every visible item gets a button of type #UI_BTYPE_VIEW_ITEM during the layout building. */ + uiButViewItem *view_item_but_ = nullptr; public: virtual ~AbstractTreeViewItem() = default; virtual void build_row(uiLayout &row) = 0; - virtual void build_context_menu(bContext &C, uiLayout &column) const; AbstractTreeView &get_tree_view() const; @@ -210,11 +177,6 @@ class AbstractTreeViewItem : public TreeViewItemContainer { * can't be sure about the item state. */ bool is_collapsed() const; - /** - * Requires the tree to have completed reconstruction, see #is_reconstructed(). Otherwise we - * can't be sure about the item state. - */ - bool is_active() const; protected: /** @@ -227,31 +189,21 @@ class AbstractTreeViewItem : public TreeViewItemContainer { */ virtual std::optional<bool> should_be_active() const; - /** - * Queries if the tree-view item supports renaming in principle. Renaming may still fail, e.g. if - * another item is already being renamed. - */ - virtual bool supports_renaming() const; - /** - * Try renaming the item, or the data it represents. Can assume - * #AbstractTreeViewItem::supports_renaming() returned true. Sub-classes that override this - * should usually call this, unless they have a custom #AbstractTreeViewItem.matches(). - * - * \return True if the renaming was successful. - */ - virtual bool rename(StringRefNull new_name); + /** See AbstractViewItem::get_rename_string(). */ + virtual StringRef get_rename_string() const override; + /** See AbstractViewItem::rename(). */ + virtual bool rename(StringRefNull new_name) override; /** * Return whether the item can be collapsed. Used to disable collapsing for items with children. */ virtual bool supports_collapsing() const; - /** - * Copy persistent state (e.g. is-collapsed flag, selection, etc.) from a matching item of - * the last redraw to this item. If sub-classes introduce more advanced state they should - * override this and make it update their state accordingly. - */ - virtual void update_from_old(const AbstractTreeViewItem &old); + /** See #AbstractViewItem::matches(). */ + virtual bool matches(const AbstractViewItem &other) const override; + + /** See #AbstractViewItem::update_from_old(). */ + virtual void update_from_old(const AbstractViewItem &old) override; /** * Compare this item to \a other to check if they represent the same data. @@ -259,22 +211,11 @@ class AbstractTreeViewItem : public TreeViewItemContainer { * open/closed, active, etc.). Items are only matched if their parents also match. * By default this just matches the item's label (if the parents match!). If that isn't * good enough for a sub-class, that can override it. - */ - virtual bool matches(const AbstractTreeViewItem &other) const; - - /** - * If an item wants to support being dragged, it has to return a drag controller here. - * That is an object implementing #AbstractTreeViewItemDragController. - */ - virtual std::unique_ptr<AbstractTreeViewItemDragController> create_drag_controller() const; - /** - * If an item wants to support dropping data into it, it has to return a drop controller here. - * That is an object implementing #AbstractTreeViewItemDropController. * - * \note This drop controller may be requested for each event. The tree-view doesn't keep a drop - * controller around currently. So it can not contain persistent state. + * TODO #matches_single() is a rather temporary name, used to indicate that this only compares + * the item itself, not the parents. Item matching is expected to change quite a bit anyway. */ - virtual std::unique_ptr<AbstractTreeViewItemDropController> create_drop_controller() const; + virtual bool matches_single(const AbstractTreeViewItem &other) const; /** * Activates this item, deactivates other items, calls the #AbstractTreeViewItem::on_activate() @@ -292,29 +233,24 @@ class AbstractTreeViewItem : public TreeViewItemContainer { */ bool is_hovered() const; bool is_collapsible() const; - bool is_renaming() const; void ensure_parents_uncollapsed(); - uiButTreeRow *tree_row_button(); + uiButViewItem *view_item_button(); private: - static void rename_button_fn(bContext *, void *, char *); - static AbstractTreeViewItem *find_tree_item_from_rename_button(const uiBut &but); static void tree_row_click_fn(struct bContext *, void *, void *); static void collapse_chevron_click_fn(bContext *, void *but_arg1, void *); static bool is_collapse_chevron_but(const uiBut *but); /** See #AbstractTreeView::change_state_delayed() */ void change_state_delayed(); - void end_renaming(); void add_treerow_button(uiBlock &block); void add_indent(uiLayout &row) const; void add_collapse_chevron(uiBlock &block) const; void add_rename_button(uiLayout &row); - bool matches_including_parents(const AbstractTreeViewItem &other) const; bool has_active_child() const; int count_parents() const; }; @@ -322,69 +258,6 @@ class AbstractTreeViewItem : public TreeViewItemContainer { /** \} */ /* ---------------------------------------------------------------------- */ -/** \name Drag 'n Drop - * \{ */ - -/** - * Class to enable dragging a tree-item. An item can return a drop controller for itself via a - * custom implementation of #AbstractTreeViewItem::create_drag_controller(). - */ -class AbstractTreeViewItemDragController { - protected: - AbstractTreeView &tree_view_; - - public: - AbstractTreeViewItemDragController(AbstractTreeView &tree_view); - virtual ~AbstractTreeViewItemDragController() = default; - - virtual int get_drag_type() const = 0; - virtual void *create_drag_data() const = 0; - virtual void on_drag_start(); - - template<class TreeViewType> inline TreeViewType &tree_view() const; -}; - -/** - * Class to customize the drop behavior of a tree-item, plus the behavior when dragging over this - * item. An item can return a drop controller for itself via a custom implementation of - * #AbstractTreeViewItem::create_drop_controller(). - */ -class AbstractTreeViewItemDropController { - protected: - AbstractTreeView &tree_view_; - - public: - AbstractTreeViewItemDropController(AbstractTreeView &tree_view); - virtual ~AbstractTreeViewItemDropController() = default; - - /** - * Check if the data dragged with \a drag can be dropped on the item this controller is for. - * \param r_disabled_hint: Return a static string to display to the user, explaining why dropping - * isn't possible on this item. Shouldn't be done too aggressively, e.g. - * don't set this if the drag-type can't be dropped here; only if it can - * but there's another reason it can't be dropped. - * Can assume this is a non-null pointer. - */ - virtual bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const = 0; - /** - * Custom text to display when dragging over a tree item. Should explain what happens when - * dropping the data onto this item. Will only be used if #AbstractTreeViewItem::can_drop() - * returns true, so the implementing override doesn't have to check that again. - * The returned value must be a translated string. - */ - virtual std::string drop_tooltip(const wmDrag &drag) const = 0; - /** - * Execute the logic to apply a drop of the data dragged with \a drag onto/into the item this - * controller is for. - */ - virtual bool on_drop(struct bContext *C, const wmDrag &drag) = 0; - - template<class TreeViewType> inline TreeViewType &tree_view() const; -}; - -/** \} */ - -/* ---------------------------------------------------------------------- */ /** \name Predefined Tree-View Item Types * * Common, Basic Tree-View Item Types. @@ -455,18 +328,4 @@ inline ItemT &TreeViewItemContainer::add_tree_item(Args &&...args) add_tree_item(std::make_unique<ItemT>(std::forward<Args>(args)...))); } -template<class TreeViewType> TreeViewType &AbstractTreeViewItemDragController::tree_view() const -{ - static_assert(std::is_base_of<AbstractTreeView, TreeViewType>::value, - "Type must derive from and implement the AbstractTreeView interface"); - return static_cast<TreeViewType &>(tree_view_); -} - -template<class TreeViewType> TreeViewType &AbstractTreeViewItemDropController::tree_view() const -{ - static_assert(std::is_base_of<AbstractTreeView, TreeViewType>::value, - "Type must derive from and implement the AbstractTreeView interface"); - return static_cast<TreeViewType &>(tree_view_); -} - } // namespace blender::ui diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 23dbd3ed36f..e508c96b4f1 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -49,8 +49,21 @@ enum eView2D_CommonViewTypes { /* ------ Defines for Scrollers ----- */ /** Scroll bar area. */ -#define V2D_SCROLL_HEIGHT (0.45f * U.widget_unit) -#define V2D_SCROLL_WIDTH (0.45f * U.widget_unit) + +/* Maximum has to include outline which varies with line width. */ +#define V2D_SCROLL_HEIGHT ((0.45f * U.widget_unit) + (2.0f * U.pixelsize)) +#define V2D_SCROLL_WIDTH ((0.45f * U.widget_unit) + (2.0f * U.pixelsize)) + +/* Alpha of scrollbar when at minimum size. */ +#define V2D_SCROLL_MIN_ALPHA (0.4f) + +/* Minimum size needs to include outline which varies with line width. */ +#define V2D_SCROLL_MIN_WIDTH ((5.0f * U.dpi_fac) + (2.0f * U.pixelsize)) + +/* When to start showing the full-width scroller. */ +#define V2D_SCROLL_HIDE_WIDTH (AREAMINX * U.dpi_fac) +#define V2D_SCROLL_HIDE_HEIGHT (HEADERY * U.dpi_fac) + /** Scroll bars with 'handles' used for scale (zoom). */ #define V2D_SCROLL_HANDLE_HEIGHT (0.6f * U.widget_unit) #define V2D_SCROLL_HANDLE_WIDTH (0.6f * U.widget_unit) @@ -236,9 +249,13 @@ void UI_view2d_draw_scale_x__frames_or_seconds(const struct ARegion *region, void UI_view2d_scrollers_calc(struct View2D *v2d, const struct rcti *mask_custom, struct View2DScrollers *r_scrollers); + /** * Draw scroll-bars in the given 2D-region. */ +void UI_view2d_scrollers_draw_ex(struct View2D *v2d, + const struct rcti *mask_custom, + bool use_full_hide); void UI_view2d_scrollers_draw(struct View2D *v2d, const struct rcti *mask_custom); /* List view tools. */ @@ -292,6 +309,12 @@ float UI_view2d_view_to_region_y(const struct View2D *v2d, float y); bool UI_view2d_view_to_region_clip( const struct View2D *v2d, float x, float y, int *r_region_x, int *r_region_y) ATTR_NONNULL(); +bool UI_view2d_view_to_region_segment_clip(const View2D *v2d, + const float xy_a[2], + const float xy_b[2], + int r_region_a[2], + int r_region_b[2]) ATTR_NONNULL(); + /** * Convert from 2d-view space to screen/region space * @@ -329,8 +352,10 @@ struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C); /** * Get scrollbar sizes of the current 2D view. * The size will be zero if the view has its scrollbars disabled. + * + * \param mapped: whether to use view2d_scroll_mapped which changes flags */ -void UI_view2d_scroller_size_get(const struct View2D *v2d, float *r_x, float *r_y); +void UI_view2d_scroller_size_get(const struct View2D *v2d, bool mapped, float *r_x, float *r_y); /** * Calculate the scale per-axis of the drawing-area * |