diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2015-04-22 20:34:37 +0300 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2015-04-22 20:34:37 +0300 |
commit | a6167306a29d1acf1a36539604612c98a7051273 (patch) | |
tree | 6c35087895b0ee0513b612734774f896b3b1bc7f /source/blender/editors | |
parent | d794ce627faab1f107ef8fd366294b9990cfe446 (diff) | |
parent | 3174cbe8f2d3fa384b644a62b3c265a946ab866f (diff) |
Merge branch 'master' into gooseberry
Conflicts:
source/blender/editors/interface/interface_handlers.c
source/blender/editors/space_sequencer/sequencer_draw.c
Diffstat (limited to 'source/blender/editors')
38 files changed, 1015 insertions, 407 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 4828343fa0e..67485248bf1 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -2496,12 +2496,13 @@ static void ANIM_OT_channels_select_border(wmOperatorType *ot) /* ******************* Rename Operator ***************************** */ /* Allow renaming some channels by clicking on them */ -static void rename_anim_channels(bAnimContext *ac, int channel_index) +static bool rename_anim_channels(bAnimContext *ac, int channel_index) { ListBase anim_data = {NULL, NULL}; const bAnimChannelType *acf; bAnimListElem *ale; int filter; + bool success = false; /* get the channel that was clicked on */ /* filter channels */ @@ -2516,7 +2517,7 @@ static void rename_anim_channels(bAnimContext *ac, int channel_index) printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n", channel_index); ANIM_animdata_freelist(&anim_data); - return; + return false; } /* check that channel can be renamed */ @@ -2536,6 +2537,7 @@ static void rename_anim_channels(bAnimContext *ac, int channel_index) */ if (ac->ads) { ac->ads->renameIndex = channel_index + 1; + success = true; } } } @@ -2543,22 +2545,18 @@ static void rename_anim_channels(bAnimContext *ac, int channel_index) /* free temp data and tag for refresh */ ANIM_animdata_freelist(&anim_data); ED_region_tag_redraw(ac->ar); + return success; } -static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +static int animchannels_channel_get(bAnimContext *ac, const int mval[2]) { - bAnimContext ac; ARegion *ar; View2D *v2d; int channel_index; float x, y; - /* get editor data */ - if (ANIM_animdata_get_context(C, &ac) == 0) - return OPERATOR_CANCELLED; - /* get useful pointers from animation context data */ - ar = ac.ar; + ar = ac->ar; v2d = &ar->v2d; /* figure out which channel user clicked in @@ -2566,20 +2564,36 @@ static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), const * so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use * ACHANNEL_HEIGHT_HALF. */ - UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y); + UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y); - if (ac.datatype == ANIMCONT_NLA) { - SpaceNla *snla = (SpaceNla *)ac.sl; + if (ac->datatype == ANIMCONT_NLA) { + SpaceNla *snla = (SpaceNla *)ac->sl; UI_view2d_listview_view_to_cell(v2d, NLACHANNEL_NAMEWIDTH, NLACHANNEL_STEP(snla), 0, (float)NLACHANNEL_HEIGHT_HALF(snla), x, y, NULL, &channel_index); } else { UI_view2d_listview_view_to_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP, 0, (float)ACHANNEL_HEIGHT_HALF, x, y, NULL, &channel_index); } - + + return channel_index; +} + +static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +{ + bAnimContext ac; + int channel_index; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + channel_index = animchannels_channel_get(&ac, event->mval); + /* handle click */ - rename_anim_channels(&ac, channel_index); - - return OPERATOR_FINISHED; + if (rename_anim_channels(&ac, channel_index)) + return OPERATOR_FINISHED; + else + /* allow event to be handled by selectall operator */ + return OPERATOR_PASS_THROUGH; } static void ANIM_OT_channels_rename(wmOperatorType *ot) @@ -3008,6 +3022,105 @@ static void ANIM_OT_channels_click(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } +static bool select_anim_channel_keys(bAnimContext *ac, int channel_index, bool extend) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + bool success = false; + FCurve *fcu; + int i; + + /* get the channel that was clicked on */ + /* filter channels */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* get channel from index */ + ale = BLI_findlink(&anim_data, channel_index); + if (ale == NULL) { + /* channel not found */ + if (G.debug & G_DEBUG) + printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n", channel_index); + + ANIM_animdata_freelist(&anim_data); + return false; + } + + fcu = (FCurve *)ale->key_data; + success = (fcu != NULL); + + ANIM_animdata_freelist(&anim_data); + + /* F-Curve may not have any keyframes */ + if (fcu->bezt) { + BezTriple *bezt; + + if (!extend) { + filter = (ANIMFILTER_DATA_VISIBLE); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + for (ale = anim_data.first; ale; ale = ale->next) { + FCurve *fcu_inner = (FCurve *)ale->key_data; + + if (fcu_inner) { + for (i = 0, bezt = fcu_inner->bezt; i < fcu_inner->totvert; i++, bezt++) { + bezt->f2 = bezt->f1 = bezt->f3 = 0; + } + } + } + + ANIM_animdata_freelist(&anim_data); + } + + for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { + bezt->f2 = bezt->f1 = bezt->f3 = SELECT; + } + } + + /* free temp data and tag for refresh */ + ED_region_tag_redraw(ac->ar); + return success; +} + +static int animchannels_channel_select_keys_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + bAnimContext ac; + int channel_index; + bool extend = RNA_boolean_get(op->ptr, "extend"); + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + channel_index = animchannels_channel_get(&ac, event->mval); + + /* handle click */ + if (select_anim_channel_keys(&ac, channel_index, extend)) { + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); + return OPERATOR_FINISHED; + } + else + /* allow event to be handled by selectall operator */ + return OPERATOR_PASS_THROUGH; +} + +static void ANIM_OT_channel_select_keys(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Select Channel keyframes"; + ot->idname = "ANIM_OT_channel_select_keys"; + ot->description = "Select all keyframes of channel under mouse"; + + /* api callbacks */ + ot->invoke = animchannels_channel_select_keys_invoke; + ot->poll = animedit_poll_channels_active; + + prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} + /* ************************************************************************** */ /* Operator Registration */ @@ -3017,8 +3130,9 @@ void ED_operatortypes_animchannels(void) WM_operatortype_append(ANIM_OT_channels_select_border); WM_operatortype_append(ANIM_OT_channels_click); + WM_operatortype_append(ANIM_OT_channel_select_keys); WM_operatortype_append(ANIM_OT_channels_rename); - + WM_operatortype_append(ANIM_OT_channels_find); WM_operatortype_append(ANIM_OT_channels_setting_enable); @@ -3058,7 +3172,9 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf) /* rename */ WM_keymap_add_item(keymap, "ANIM_OT_channels_rename", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "ANIM_OT_channels_rename", LEFTMOUSE, KM_DBL_CLICK, 0, 0); - + WM_keymap_add_item(keymap, "ANIM_OT_channel_select_keys", LEFTMOUSE, KM_DBL_CLICK, 0, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channel_select_keys", LEFTMOUSE, KM_DBL_CLICK, KM_SHIFT, 0)->ptr, "extend", true); + /* find (i.e. a shortcut for setting the name filter) */ WM_keymap_add_item(keymap, "ANIM_OT_channels_find", FKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index ba8ab636de0..c65f638e902 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -138,17 +138,18 @@ bool EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2] short xmin, short ymin, short xmax, short ymax); bool EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short rads); -struct BMVert *EDBM_vert_find_nearest_ex( - struct ViewContext *vc, float *r_dist, - const bool use_select_bias, const bool is_strict); +struct BMVert *EDBM_vert_find_nearest_ex(struct ViewContext *vc, float *r_dist, + const bool use_select_bias, bool use_cycle); struct BMVert *EDBM_vert_find_nearest( struct ViewContext *vc, float *r_dist); +struct BMEdge *EDBM_edge_find_nearest_ex(struct ViewContext *vc, float *r_dist, + const bool use_select_bias, const bool use_cycle); struct BMEdge *EDBM_edge_find_nearest( struct ViewContext *vc, float *r_dist); -struct BMFace *EDBM_face_find_nearest_ex( - struct ViewContext *vc, float *r_dist, +struct BMFace *EDBM_face_find_nearest_ex(struct ViewContext *vc, float *r_dist, + const bool use_select_bias, const bool use_cycle, struct BMFace **r_efa_zbuf); struct BMFace *EDBM_face_find_nearest( struct ViewContext *vc, float *r_dist); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index e23f1550bbe..b22221b017f 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -66,6 +66,7 @@ void ED_region_header_init(struct ARegion *ar); void ED_region_header(const struct bContext *C, struct ARegion *ar); void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar); void ED_region_info_draw(struct ARegion *ar, const char *text, int block, float fill_color[4]); +void ED_region_image_metadata_draw(struct ARegion *ar, struct ImBuf *ibuf, float zoomx, float zoomy); void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy); void ED_region_draw_backdrop_view3d(const struct bContext *C, struct Object *camera, const float alpha, const float width, const float height, const float x, const float y, diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 428baecb932..6e3c216e4cf 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -275,8 +275,7 @@ void ED_view3d_backbuf_validate(struct ViewContext *vc); struct ImBuf *ED_view3d_backbuf_read(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); unsigned int ED_view3d_backbuf_sample_rect( struct ViewContext *vc, const int mval[2], int size, - unsigned int min, unsigned int max, float *dist, const bool is_strict, - void *handle, bool (*indextest)(void *handle, unsigned int index)); + unsigned int min, unsigned int max, float *r_dist); int ED_view3d_backbuf_sample_size_clamp(struct ARegion *ar, const float dist); unsigned int ED_view3d_backbuf_sample(struct ViewContext *vc, int x, int y); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 717d5db6b66..cd08a397b70 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -679,6 +679,7 @@ void UI_but_func_drawextra_set( void *arg1, void *arg2); void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN); +void UI_but_tooltip_timer_remove(struct bContext *C, uiBut *but); bool UI_textbutton_activate_rna(const struct bContext *C, struct ARegion *ar, const void *rna_poin_data, const char *rna_prop_id); diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 3923c5c4432..2b19b6180e5 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -294,7 +294,10 @@ enum { TH_INFO_DEBUG_TEXT, TH_VIEW_OVERLAY, - TH_V3D_CLIPPING_BORDER + TH_V3D_CLIPPING_BORDER, + + TH_METADATA_BG, + TH_METADATA_TEXT }; /* XXX WARNING: previous is saved in file, so do not change order! */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 5714a40d508..5c548d3afd5 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -37,6 +37,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_userdef_types.h" @@ -1951,6 +1952,56 @@ uiBut *ui_but_drag_multi_edit_get(uiBut *but) return but_iter; } +/** \name Check to show extra icons + * + * Extra icons are shown on the right hand side of buttons. + * \{ */ + +static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but) +{ + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); + return ((but->editstr == NULL) && + (but->drawstr[0] != '\0') && + (but->flag & UI_BUT_SEARCH_UNLINK)); +} + +static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but) +{ + StructRNA *type; + short idcode; + + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_SEARCH_UNLINK)); + + if (but->rnaprop == NULL) { + return false; + } + + type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop); + idcode = RNA_type_to_ID_code(type); + + + return ((but->editstr == NULL) && + (idcode == ID_OB || OB_DATA_SUPPORT_ID(idcode))); +} + +uiButExtraIconType ui_but_icon_extra_get(uiBut *but) +{ + if ((but->flag & UI_BUT_SEARCH_UNLINK) == 0) { + /* pass */ + } + else if (ui_but_icon_extra_is_visible_search_unlink(but)) { + return UI_BUT_ICONEXTRA_UNLINK; + } + else if (ui_but_icon_extra_is_visible_eyedropper(but)) { + return UI_BUT_ICONEXTRA_EYEDROPPER; + } + + return UI_BUT_ICONEXTRA_NONE; +} + +/** \} */ + + static double ui_get_but_scale_unit(uiBut *but, double value) { UnitSettings *unit = but->block->unit; @@ -2714,11 +2765,11 @@ void ui_but_update(uiBut *but) } else { const int prec = ui_but_calc_float_precision(but, value); - slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%.*f", prec, value); + slen += BLI_snprintf_rlen(but->drawstr + slen, sizeof(but->drawstr) - slen, "%.*f", prec, value); } } else { - slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%d", (int)value); + slen += BLI_snprintf_rlen(but->drawstr + slen, sizeof(but->drawstr) - slen, "%d", (int)value); } if (but->rnaprop) { diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index f5847a9d701..80b01b69647 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -456,6 +456,8 @@ static void datadropper_exit(bContext *C, wmOperator *op) op->customdata = NULL; } + + WM_event_add_mousemove(C); } static void datadropper_cancel(bContext *C, wmOperator *op) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index d05f9beee0f..f02101a0446 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -332,7 +332,6 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da const bool mousemove, const bool onfree); static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *userdata); static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type); -static void button_timers_tooltip_remove(bContext *C, uiBut *but); #ifdef USE_DRAG_MULTINUM static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block); @@ -3303,9 +3302,11 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { + uiButExtraIconType extra_icon_type; + /* unlink icon is on right */ - if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS && - ui_but_is_search_unlink_visible(but)) + if ((ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY)) && + ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE)) { ARegion *ar = data->region; rcti rect; @@ -3316,14 +3317,29 @@ static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHa BLI_rcti_rctf_copy(&rect, &but->rect); rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect)); + /* handle click on unlink/eyedropper icon */ if (BLI_rcti_isect_pt(&rect, x, y)) { - /* most likely NULL, but let's check, and give it temp zero string */ - if (data->str == NULL) - data->str = MEM_callocN(1, "temp str"); - data->str[0] = 0; + /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */ + if (event->val == KM_RELEASE) { + /* unlink */ + if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) { + /* most likely NULL, but let's check, and give it temp zero string */ + if (data->str == NULL) { + data->str = MEM_callocN(1, "temp str"); + } + data->str[0] = 0; - ui_apply_but_TEX(C, but, data); - button_activate_state(C, but, BUTTON_STATE_EXIT); + ui_apply_but_TEX(C, but, data); + button_activate_state(C, but, BUTTON_STATE_EXIT); + } + /* eyedropper */ + else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) { + WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL); + } + else { + BLI_assert(0); + } + } return WM_UI_HANDLER_BREAK; } @@ -5941,7 +5957,7 @@ static void menu_add_shortcut_cancel(struct bContext *C, void *arg1) static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) { uiBut *but = (uiBut *)arg1; - button_timers_tooltip_remove(C, but); + UI_but_tooltip_timer_remove(C, but); UI_popup_block_invoke(C, menu_change_shortcut, but); } @@ -5962,7 +5978,7 @@ static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) { uiBut *but = (uiBut *)arg1; - button_timers_tooltip_remove(C, but); + UI_but_tooltip_timer_remove(C, but); UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but); } @@ -6888,14 +6904,6 @@ static bool ui_but_is_interactive(const uiBut *but, const bool labeledit) return true; } -bool ui_but_is_search_unlink_visible(const uiBut *but) -{ - BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); - return ((but->editstr == NULL) && - (but->drawstr[0] != '\0') && - (but->flag & UI_BUT_SEARCH_UNLINK)); -} - /* x and y are only used in case event is NULL... */ static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, const bool labeledit) { @@ -6983,7 +6991,8 @@ static bool button_modal_state(uiHandleButtonState state) BUTTON_STATE_MENU_OPEN); } -static void button_timers_tooltip_remove(bContext *C, uiBut *but) +/* removes tooltip timer from active but (meaning tooltip is disabled until it's reenabled again) */ +void UI_but_tooltip_timer_remove(bContext *C, uiBut *but) { uiHandleButtonData *data; @@ -7067,7 +7076,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s } else { but->flag |= UI_SELECT; - button_timers_tooltip_remove(C, but); + UI_but_tooltip_timer_remove(C, but); } /* text editing */ @@ -7696,7 +7705,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) case WHEELDOWNMOUSE: case MIDDLEMOUSE: case MOUSEPAN: - button_timers_tooltip_remove(C, but); + UI_but_tooltip_timer_remove(C, but); /* fall-through */ default: /* handle button type specific events */ @@ -8671,7 +8680,7 @@ static int ui_handle_menu_event( { if (!but || !ui_but_contains_point_px(ar, but, event->x, event->y)) { if (but) { - button_timers_tooltip_remove(C, but); + UI_but_tooltip_timer_remove(C, but); } menu->is_grab = true; diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 999b762f88e..4bf44d2b124 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -121,6 +121,14 @@ enum { /* warn: rest of uiBut->flag in UI_interface.h */ }; +/* some buttons display icons only under special conditions + * (e.g. 'x' icon in search menu) - used with ui_but_icon_extra_get */ +typedef enum uiButExtraIconType { + UI_BUT_ICONEXTRA_NONE = 1, + UI_BUT_ICONEXTRA_UNLINK, + UI_BUT_ICONEXTRA_EYEDROPPER, +} uiButExtraIconType; + /* but->pie_dir */ typedef enum RadialDirection { UI_RADIAL_NONE = -1, @@ -456,6 +464,7 @@ extern bool ui_but_string_set(struct bContext *C, uiBut *but, const char *str) A extern bool ui_but_string_set_eval_num(struct bContext *C, uiBut *but, const char *str, double *value) ATTR_NONNULL(); extern int ui_but_string_get_max_length(uiBut *but); extern uiBut *ui_but_drag_multi_edit_get(uiBut *but); +extern uiButExtraIconType ui_but_icon_extra_get(uiBut *but); extern void ui_but_default_set(struct bContext *C, const bool all, const bool use_afterfunc); @@ -466,7 +475,6 @@ extern bool ui_but_is_unit(const uiBut *but) ATTR_WARN_UNUSED_RESULT; extern bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b) ATTR_WARN_UNUSED_RESULT; extern bool ui_but_is_rna_valid(uiBut *but) ATTR_WARN_UNUSED_RESULT; extern bool ui_but_is_utf8(const uiBut *but) ATTR_WARN_UNUSED_RESULT; -extern bool ui_but_is_search_unlink_visible(const uiBut *but) ATTR_WARN_UNUSED_RESULT; extern int ui_but_is_pushed_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT; extern int ui_but_is_pushed(uiBut *but) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index b3c3d7f53a9..08bd2d3360c 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1501,6 +1501,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB const bool show_menu_icon = ui_but_draw_menu_icon(but); float alpha = (float)wcol->text[3] / 255.0f; char password_str[UI_MAX_DRAW_STR]; + uiButExtraIconType extra_icon_type; ui_but_text_password_hide(password_str, but, false); @@ -1540,11 +1541,23 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB } /* unlink icon for this button type */ - if ((but->type == UI_BTYPE_SEARCH_MENU) && ui_but_is_search_unlink_visible(but)) { + if ((but->type == UI_BTYPE_SEARCH_MENU) && + ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE)) + { rcti temp = *rect; temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f); - widget_draw_icon(but, ICON_X, alpha, &temp, false); + + if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) { + widget_draw_icon(but, ICON_X, alpha, &temp, false); + } + else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) { + widget_draw_icon(but, ICON_EYEDROPPER, alpha, &temp, false); + } + else { + BLI_assert(0); + } + rect->xmax -= ICON_SIZE_FROM_BUTRECT(rect); } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 15e742c930a..8e003e50df3 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -569,6 +569,13 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo cp = ts->paint_curve_pivot; break; + case TH_METADATA_BG: + cp = ts->metadatabg; + break; + case TH_METADATA_TEXT: + cp = ts->metadatatext; + break; + case TH_UV_OTHERS: cp = ts->uv_others; break; @@ -2602,6 +2609,15 @@ void init_userdef_do_versions(void) cp[3] = 255; } } + + if (U.versionfile < 274 || (U.versionfile == 274 && U.subversionfile < 5)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + copy_v4_v4_char(btheme->tima.metadatatext, btheme->tima.text_hi); + copy_v4_v4_char(btheme->tseq.metadatatext, btheme->tseq.text_hi); + } + } + if (U.pixelsize == 0.0f) U.pixelsize = 1.0f; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 5730c967880..58b51ef8e28 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -661,7 +661,9 @@ static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool const float zoomx = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur); /* only move view to mouse if zoom fac is inside minzoom/maxzoom */ - if (IN_RANGE_INCL(zoomx, v2d->minzoom, v2d->maxzoom)) { + if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) || + IN_RANGE_INCL(zoomx, v2d->minzoom, v2d->maxzoom)) + { float mval_fac = (vzd->mx_2d - cur_old.xmin) / BLI_rctf_size_x(&cur_old); float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dx) - (mval_faci * dx); @@ -692,7 +694,9 @@ static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool const float zoomy = (float)(BLI_rcti_size_y(&v2d->mask) + 1) / BLI_rctf_size_y(&v2d->cur); /* only move view to mouse if zoom fac is inside minzoom/maxzoom */ - if (IN_RANGE_INCL(zoomy, v2d->minzoom, v2d->maxzoom)) { + if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) || + IN_RANGE_INCL(zoomy, v2d->minzoom, v2d->maxzoom)) + { float mval_fac = (vzd->my_2d - cur_old.ymin) / BLI_rctf_size_y(&cur_old); float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dy) - (mval_faci * dy); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index a3a61c30aeb..90b683c5abd 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -36,6 +36,7 @@ #include "BLI_linklist.h" #include "BLI_linklist_stack.h" #include "BLI_math.h" +#include "BLI_math_bits.h" #include "BLI_rand.h" #include "BLI_array.h" @@ -354,60 +355,66 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads) /* -------------------------------------------------------------------- */ /** \name Find Nearest Vert/Edge/Face + * + * \note Screen-space manhatten distances are used here, + * since its faster and good enough for the purpose of selection. + * + * \note \a dist_bias is used so we can bias against selected items. + * when choosing between elements of a single type, but return the real distance + * to avoid the bias interfering with distance comparisons when mixing types. * \{ */ -#define FIND_NEAR_THRESHOLD_MIN 3 +#define FIND_NEAR_SELECT_BIAS 5 +#define FIND_NEAR_CYCLE_THRESHOLD_MIN 3 + +struct NearestVertUserData_Hit { + float dist; + float dist_bias; + int index; + BMVert *vert; +}; struct NearestVertUserData { float mval_fl[2]; - int pass; - char hflag_select; - bool is_strict; - float dist; - int index_last; - int index_nearest; - BMVert *vert_nearest; + bool use_select_bias; + bool use_cycle; + int cycle_index_prev; + + struct NearestVertUserData_Hit hit; + struct NearestVertUserData_Hit hit_cycle; }; static void findnearestvert__doClosest(void *userData, BMVert *eve, const float screen_co[2], int index) { struct NearestVertUserData *data = userData; + float dist_test, dist_test_bias; - if (data->pass == 0) { - if (index <= data->index_last) - return; - } - else { - if (index > data->index_last) - return; + dist_test = dist_test_bias = len_manhattan_v2v2(data->mval_fl, screen_co); + + if (data->use_select_bias && BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + dist_test_bias += FIND_NEAR_SELECT_BIAS; } - if (data->dist > FIND_NEAR_THRESHOLD_MIN) { - float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if (BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->hflag_select) { - if (data->is_strict == true) { - return; - } - else { - dist_test += 5; - } - } + if (dist_test_bias < data->hit.dist_bias) { + data->hit.dist_bias = dist_test_bias; + data->hit.dist = dist_test; + data->hit.index = index; + data->hit.vert = eve; + } - if (dist_test < data->dist) { - data->dist = dist_test; - data->vert_nearest = eve; - data->index_nearest = index; + if (data->use_cycle) { + if ((data->hit_cycle.vert == NULL) && + (index > data->cycle_index_prev) && + (dist_test_bias < FIND_NEAR_CYCLE_THRESHOLD_MIN)) + { + data->hit_cycle.dist_bias = dist_test_bias; + data->hit_cycle.dist = dist_test; + data->hit_cycle.index = index; + data->hit_cycle.vert = eve; } } } - -static bool findnearestvert__backbufIndextest(void *handle, unsigned int index) -{ - BMEditMesh *em = (BMEditMesh *)handle; - BMVert *eve = BM_vert_at_index_find(em->bm, index - 1); - return !(eve && BM_elem_flag_test(eve, BM_ELEM_SELECT)); -} /** * Nearest vertex under the cursor. * @@ -415,77 +422,65 @@ static bool findnearestvert__backbufIndextest(void *handle, unsigned int index) * \param use_select_bias * - When true, selected vertice are given a 5 pixel bias to make them further than unselect verts. * - When false, unselected vertice are given the bias. - * \param is_strict When true, the vertice corresponding to the sel parameter are ignored and not just biased + * \param use_cycle Cycle over elements within #FIND_NEAR_CYCLE_THRESHOLD_MIN in order of index. */ BMVert *EDBM_vert_find_nearest_ex( ViewContext *vc, float *r_dist, - const bool use_select_bias, const bool is_strict) + const bool use_select_bias, bool use_cycle) { BMesh *bm = vc->em->bm; if (V3D_IS_ZBUF(vc->v3d)) { const int dist_px = ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); - float distance; + float dist_test; unsigned int index; BMVert *eve; - if (is_strict) { - index = ED_view3d_backbuf_sample_rect( - vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &distance, - is_strict, vc->em, findnearestvert__backbufIndextest); - } - else { - index = ED_view3d_backbuf_sample_rect( - vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &distance, - 0, NULL, NULL); - } - + index = ED_view3d_backbuf_sample_rect( + vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test); eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL; - if (eve && distance < *r_dist) { - *r_dist = distance; - return eve; - } - else { - return NULL; + if (eve) { + if (dist_test < *r_dist) { + *r_dist = dist_test; + return eve; + } } + return NULL; } else { - struct NearestVertUserData data; + struct NearestVertUserData data = {{0}}; + const struct NearestVertUserData_Hit *hit; + const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT; static int prev_select_index = 0; static const BMVert *prev_select_elem = NULL; - if (prev_select_elem && (prev_select_elem != BM_vert_at_index_find_or_table(bm, prev_select_index))) { + if ((use_cycle == false) || + (prev_select_elem && (prev_select_elem != BM_vert_at_index_find_or_table(bm, prev_select_index)))) + { prev_select_index = 0; prev_select_elem = NULL; } - data.index_last = prev_select_index; data.mval_fl[0] = vc->mval[0]; data.mval_fl[1] = vc->mval[1]; - data.hflag_select = use_select_bias ? BM_ELEM_SELECT : 0; - data.dist = *r_dist; - data.is_strict = is_strict; - data.vert_nearest = NULL; - data.index_nearest = 0; - - data.pass = 0; + data.use_select_bias = use_select_bias; + data.use_cycle = use_cycle; + data.hit.dist = data.hit_cycle.dist = \ + data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist; + data.cycle_index_prev = prev_select_index; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, clip_flag); - mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - - if (data.dist > FIND_NEAR_THRESHOLD_MIN) { - data.pass = 1; - mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - } + hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit; + *r_dist = hit->dist; - *r_dist = data.dist; - prev_select_elem = data.vert_nearest; - prev_select_index = data.index_nearest; + prev_select_elem = hit->vert; + prev_select_index = hit->index; - return data.vert_nearest; + return hit->vert; } } @@ -494,100 +489,156 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist) return EDBM_vert_find_nearest_ex(vc, r_dist, false, false); } +struct NearestEdgeUserData_Hit { + float dist; + float dist_bias; + int index; + BMEdge *edge; +}; struct NearestEdgeUserData { ViewContext vc; float mval_fl[2]; - float dist; - BMEdge *edge_nearest; + bool use_select_bias; + bool use_cycle; + int cycle_index_prev; + + struct NearestEdgeUserData_Hit hit; + struct NearestEdgeUserData_Hit hit_cycle; }; /* note; uses v3d, so needs active 3d window */ -static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index)) +static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index) { struct NearestEdgeUserData *data = userData; - int distance; + float dist_test, dist_test_bias; - distance = dist_to_line_segment_v2(data->mval_fl, screen_co_a, screen_co_b); - - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - distance += 5; + float fac = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b); + float screen_co[2]; + + if (fac <= 0.0f) { + fac = 0.0f; + copy_v2_v2(screen_co, screen_co_a); + } + else if (fac >= 1.0f) { + fac = 1.0f; + copy_v2_v2(screen_co, screen_co_b); + } + else { + interp_v3_v3v3(screen_co, screen_co_a, screen_co_b, fac); } - if (distance < data->dist) { - if (data->vc.rv3d->rflag & RV3D_CLIPPING) { - float fac = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b); - float vec[3]; + dist_test = dist_test_bias = len_manhattan_v2v2(data->mval_fl, screen_co); - CLAMP(fac, 0, 1); - interp_v3_v3v3(vec, eed->v1->co, eed->v2->co, fac); - if (ED_view3d_clipping_test(data->vc.rv3d, vec, true) == 0) { - data->dist = distance; - data->edge_nearest = eed; - } + if (data->use_select_bias && BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + dist_test += FIND_NEAR_SELECT_BIAS; + } + + if (data->vc.rv3d->rflag & RV3D_CLIPPING) { + float vec[3]; + + interp_v3_v3v3(vec, eed->v1->co, eed->v2->co, fac); + if (ED_view3d_clipping_test(data->vc.rv3d, vec, true)) { + return; } - else { - data->dist = distance; - data->edge_nearest = eed; + } + + if (dist_test_bias < data->hit.dist_bias) { + data->hit.dist_bias = dist_test_bias; + data->hit.dist = dist_test; + data->hit.index = index; + data->hit.edge = eed; + } + + if (data->use_cycle) { + if ((data->hit_cycle.edge == NULL) && + (index > data->cycle_index_prev) && + (dist_test_bias < FIND_NEAR_CYCLE_THRESHOLD_MIN)) + { + data->hit_cycle.dist_bias = dist_test_bias; + data->hit_cycle.dist = dist_test; + data->hit_cycle.index = index; + data->hit_cycle.edge = eed; } } } -BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist) +BMEdge *EDBM_edge_find_nearest_ex( + ViewContext *vc, float *r_dist, + const bool use_select_bias, const bool use_cycle) { BMesh *bm = vc->em->bm; if (V3D_IS_ZBUF(vc->v3d)) { const int dist_px = ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); - float distance; + float dist_test; unsigned int index; BMEdge *eed; ED_view3d_backbuf_validate(vc); - index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &distance, 0, NULL, NULL); + index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test); eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL; - if (eed && distance < *r_dist) { - *r_dist = distance; - return eed; - } - else { - return NULL; + if (eed) { + if (dist_test < *r_dist) { + *r_dist = dist_test; + return eed; + } } + return NULL; } else { - struct NearestEdgeUserData data; + struct NearestEdgeUserData data = {{0}}; + const struct NearestEdgeUserData_Hit *hit; + /* interpolate along the edge before doing a clipping plane test */ + const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB; + + static int prev_select_index = 0; + static const BMEdge *prev_select_elem = NULL; + + if ((use_cycle == false) || + (prev_select_elem && (prev_select_elem != BM_edge_at_index_find_or_table(bm, prev_select_index)))) + { + prev_select_index = 0; + prev_select_elem = NULL; + } data.vc = *vc; data.mval_fl[0] = vc->mval[0]; data.mval_fl[1] = vc->mval[1]; - data.dist = *r_dist; - data.edge_nearest = NULL; + data.use_select_bias = use_select_bias; + data.use_cycle = use_cycle; + data.hit.dist = data.hit_cycle.dist = \ + data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist; + data.cycle_index_prev = prev_select_index; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, clip_flag); + + hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit; + *r_dist = hit->dist; - mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_PROJ_TEST_CLIP_WIN); + prev_select_elem = hit->edge; + prev_select_index = hit->index; - *r_dist = data.dist; - return data.edge_nearest; + return hit->edge; } } +BMEdge *EDBM_edge_find_nearest( + ViewContext *vc, float *r_dist) +{ + return EDBM_edge_find_nearest_ex(vc, r_dist, false, false); +} + +/* find the distance to the face we already have */ struct NearestFaceUserData_ZBuf { float mval_fl[2]; float dist; const BMFace *face_test; }; -struct NearestFaceUserData_Closest { - float mval_fl[2]; - int pass; - float dist; - int index_last; - int index_nearest; - BMFace *face_nearest; -}; - static void findnearestface__doZBuf(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { struct NearestFaceUserData_ZBuf *data = userData; @@ -602,26 +653,50 @@ static void findnearestface__doZBuf(void *userData, BMFace *efa, const float scr } +struct NearestFaceUserData_Hit { + float dist; + float dist_bias; + int index; + BMFace *face; +}; + +struct NearestFaceUserData { + float mval_fl[2]; + bool use_select_bias; + bool use_cycle; + int cycle_index_prev; + + struct NearestFaceUserData_Hit hit; + struct NearestFaceUserData_Hit hit_cycle; +}; + static void findnearestface__doClosest(void *userData, BMFace *efa, const float screen_co[2], int index) { - struct NearestFaceUserData_Closest *data = userData; + struct NearestFaceUserData *data = userData; + float dist_test, dist_test_bias; - if (data->pass == 0) { - if (index <= data->index_last) - return; - } - else { - if (index > data->index_last) - return; + dist_test = dist_test_bias = len_manhattan_v2v2(data->mval_fl, screen_co); + + if (data->use_select_bias && BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + dist_test_bias += FIND_NEAR_SELECT_BIAS; } - if (data->dist > FIND_NEAR_THRESHOLD_MIN) { - const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); + if (dist_test_bias < data->hit.dist_bias) { + data->hit.dist_bias = dist_test_bias; + data->hit.dist = dist_test; + data->hit.index = index; + data->hit.face = efa; + } - if (dist_test < data->dist) { - data->dist = dist_test; - data->face_nearest = efa; - data->index_nearest = index; + if (data->use_cycle) { + if ((data->hit_cycle.face == NULL) && + (index > data->cycle_index_prev) && + (dist_test_bias < FIND_NEAR_CYCLE_THRESHOLD_MIN)) + { + data->hit_cycle.dist_bias = dist_test_bias; + data->hit_cycle.dist = dist_test; + data->hit_cycle.index = index; + data->hit_cycle.face = efa; } } } @@ -629,11 +704,13 @@ static void findnearestface__doClosest(void *userData, BMFace *efa, const float BMFace *EDBM_face_find_nearest_ex( ViewContext *vc, float *r_dist, + const bool use_select_bias, const bool use_cycle, BMFace **r_efa_zbuf) { BMesh *bm = vc->em->bm; if (V3D_IS_ZBUF(vc->v3d)) { + float dist_test; unsigned int index; BMFace *efa; @@ -646,6 +723,7 @@ BMFace *EDBM_face_find_nearest_ex( *r_efa_zbuf = efa; } + /* exception for faces (verts/edges don't need this) */ if (efa) { struct NearestFaceUserData_ZBuf data; @@ -658,53 +736,62 @@ BMFace *EDBM_face_find_nearest_ex( mesh_foreachScreenFace(vc, findnearestface__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - if ((vc->em->selectmode == SCE_SELECT_FACE) || (data.dist < *r_dist)) { /* only faces, no dist check */ - *r_dist = data.dist; + dist_test = data.dist; + } + /* end exception */ + + if (efa) { + if (dist_test < *r_dist) { + *r_dist = dist_test; return efa; } } - return NULL; } else { - struct NearestFaceUserData_Closest data; + struct NearestFaceUserData data = {{0}}; + const struct NearestFaceUserData_Hit *hit; + const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT; + static int prev_select_index = 0; static const BMFace *prev_select_elem = NULL; - if (prev_select_elem && (prev_select_elem != BM_face_at_index_find_or_table(bm, prev_select_index))) { + if ((use_cycle == false) || + (prev_select_elem && (prev_select_elem != BM_face_at_index_find_or_table(bm, prev_select_index)))) + { prev_select_index = 0; prev_select_elem = NULL; } - data.index_last = prev_select_index; data.mval_fl[0] = vc->mval[0]; data.mval_fl[1] = vc->mval[1]; - data.dist = *r_dist; - data.face_nearest = NULL; - data.index_nearest = 0; + data.use_select_bias = use_select_bias; + data.use_cycle = use_cycle; + data.hit.dist = data.hit_cycle.dist = \ + data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist; + data.cycle_index_prev = prev_select_index; - data.pass = 0; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, clip_flag); - if (data.dist > FIND_NEAR_THRESHOLD_MIN) { - data.pass = 1; - mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - } + hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit; + *r_dist = hit->dist; - *r_dist = data.dist; - prev_select_elem = data.face_nearest; - prev_select_index = data.index_nearest; + prev_select_elem = hit->face; + prev_select_index = hit->index; - return data.face_nearest; + return hit->face; } } BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) { - return EDBM_face_find_nearest_ex(vc, r_dist, NULL); + return EDBM_face_find_nearest_ex(vc, r_dist, false, false, NULL); } +#undef FIND_NEAR_SELECT_BIAS +#undef FIND_NEAR_CYCLE_THRESHOLD_MIN + /* best distance based on screen coords. * use em->selectmode to define how to use @@ -714,44 +801,47 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa) { BMEditMesh *em = vc->em; + static short mval_prev[2] = {-1, -1}; + /* only cycle while the mouse remains still */ + const bool use_cycle = ((mval_prev[0] == vc->mval[0]) && (mval_prev[1] == vc->mval[1])); const float dist_init = ED_view3d_select_dist_px(); - /* since edges select lines, we give dots advantage of 20 pix */ - const float dist_edge_bias = (dist_init / 3.75f); + /* since edges select lines, we give dots advantage of ~20 pix */ + const float dist_bias = (dist_init / 4); float dist = dist_init; - float dist_vert = dist_init; BMFace *efa_zbuf = NULL; BMVert *eve = NULL; BMEdge *eed = NULL; BMFace *efa = NULL; - + + /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */ ED_view3d_backbuf_validate(vc); - if (em->selectmode & SCE_SELECT_VERTEX) { - eve = EDBM_vert_find_nearest_ex(vc, &dist, true, false); - dist_vert = dist; + if ((dist > 0.0f) && em->selectmode & SCE_SELECT_FACE) { + efa = EDBM_face_find_nearest_ex(vc, &dist, true, use_cycle, &efa_zbuf); } - if (em->selectmode & SCE_SELECT_FACE) { - efa = EDBM_face_find_nearest_ex(vc, &dist, eve ? &efa_zbuf : NULL); + if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) { + eed = EDBM_edge_find_nearest_ex(vc, &dist, true, use_cycle); + if (eed) { + dist = min_ff(dist + dist_bias, dist_init); + } } - /* distance bias from verts (not faces) */ - dist = min_ff(dist, dist_vert - dist_edge_bias); - if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) { - eed = EDBM_edge_find_nearest(vc, &dist); + if ((dist > 0.0f) && em->selectmode & SCE_SELECT_VERTEX) { + eve = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle); } /* return only one of 3 pointers, for frontbuffer redraws */ - if (eed) { - efa = NULL; eve = NULL; + if (eve) { + efa = NULL; eed = NULL; } - else if (efa) { - eve = NULL; + else if (eed) { + efa = NULL; } - /* there may be a face under the cursor, but who's center if too far away + /* there may be a face under the cursor, who's center if too far away * use this if all else fails, it makes sense to select this */ if ((eve || eed || efa) == 0) { if (efa_zbuf) { @@ -759,6 +849,9 @@ static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, } } + mval_prev[0] = vc->mval[0]; + mval_prev[1] = vc->mval[1]; + *r_eve = eve; *r_eed = eed; *r_efa = efa; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index acd745637d2..2491685161c 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1082,7 +1082,7 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int * on an edge in the backbuf, we can still select a face */ float dummy_dist; - *index = ED_view3d_backbuf_sample_rect(&vc, mval, size, 1, me->totpoly + 1, &dummy_dist, 0, NULL, NULL); + *index = ED_view3d_backbuf_sample_rect(&vc, mval, size, 1, me->totpoly + 1, &dummy_dist); } else { /* sample only on the exact position */ @@ -1248,7 +1248,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int * on an face in the backbuf, we can still select a vert */ float dummy_dist; - *index = ED_view3d_backbuf_sample_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL); + *index = ED_view3d_backbuf_sample_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist); } else { /* sample only on the exact position */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index f7d51eb403f..706ca5fbdfe 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1769,6 +1769,77 @@ void OBJECT_OT_game_property_remove(wmOperatorType *ot) RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Property index to remove ", 0, INT_MAX); } +#define GAME_PROPERTY_MOVE_UP 1 +#define GAME_PROPERTY_MOVE_DOWN -1 + +static int game_property_move(bContext *C, wmOperator *op) +{ + Object *ob = CTX_data_active_object(C); + bProperty *prop; + bProperty *otherprop = NULL; + const int index = RNA_int_get(op->ptr, "index"); + const int dir = RNA_int_get(op->ptr, "direction"); + + if (ob == NULL) + return OPERATOR_CANCELLED; + + prop = BLI_findlink(&ob->prop, index); + /* invalid index */ + if (prop == NULL) + return OPERATOR_CANCELLED; + + if (dir == GAME_PROPERTY_MOVE_UP) { + otherprop = prop->prev; + } + else if (dir == GAME_PROPERTY_MOVE_DOWN) { + otherprop = prop->next; + } + else { + BLI_assert(0); + } + + if (prop && otherprop) { + BLI_listbase_swaplinks(&ob->prop, prop, otherprop); + + WM_event_add_notifier(C, NC_LOGIC, NULL); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void OBJECT_OT_game_property_move(wmOperatorType *ot) +{ + static EnumPropertyItem direction_property_move[] = { + {GAME_PROPERTY_MOVE_UP, "UP", 0, "Up", ""}, + {GAME_PROPERTY_MOVE_DOWN, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL} + }; + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Move Game Property"; + ot->description = "Move game property"; + ot->idname = "OBJECT_OT_game_property_move"; + + /* api callbacks */ + ot->exec = game_property_move; + ot->poll = ED_operator_object_active_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Property index to move", 0, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN); + RNA_def_enum(ot->srna, "direction", direction_property_move, 0, "Direction", + "Direction for moving the property"); +} + +#undef GAME_PROPERTY_MOVE_UP +#undef GAME_PROPERTY_MOVE_DOWN + #define COPY_PROPERTIES_REPLACE 1 #define COPY_PROPERTIES_MERGE 2 #define COPY_PROPERTIES_COPY 3 diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 1849cab0a88..115676a6165 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -94,6 +94,7 @@ void OBJECT_OT_game_property_new(struct wmOperatorType *ot); void OBJECT_OT_game_property_remove(struct wmOperatorType *ot); void OBJECT_OT_game_property_copy(struct wmOperatorType *ot); void OBJECT_OT_game_property_clear(struct wmOperatorType *ot); +void OBJECT_OT_game_property_move(struct wmOperatorType *ot); void OBJECT_OT_logic_bricks_copy(struct wmOperatorType *ot); void OBJECT_OT_game_physics_copy(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 1045d7245fe..9865a596436 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -214,6 +214,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_game_property_remove); WM_operatortype_append(OBJECT_OT_game_property_copy); WM_operatortype_append(OBJECT_OT_game_property_clear); + WM_operatortype_append(OBJECT_OT_game_property_move); WM_operatortype_append(OBJECT_OT_logic_bricks_copy); WM_operatortype_append(OBJECT_OT_game_physics_copy); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 59d9faebeef..5718c94266b 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -248,6 +248,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) Object *camera = NULL; ImBuf *ibuf; float winmat[4][4]; + float *rectf = RE_RenderViewGetRectf(rr, oglrender->view_id); int sizex = oglrender->sizex; int sizey = oglrender->sizey; const short view_context = (v3d != NULL); @@ -271,7 +272,6 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) ibuf = BKE_sequencer_give_ibuf(&context, CFRA, chanshown); if (ibuf) { - float *rectf; ImBuf *linear_ibuf; BLI_assert((oglrender->sizex == ibuf->x) && (oglrender->sizey == ibuf->y)); @@ -292,7 +292,6 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) BKE_sequencer_imbuf_from_sequencer_space(scene, linear_ibuf); } - rectf = RE_RenderViewGetRectf(rr, oglrender->view_id); memcpy(rectf, linear_ibuf->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey); IMB_freeImBuf(linear_ibuf); @@ -317,10 +316,12 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect"); GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect); + BLI_assert(rectf != NULL); + for (i = 0; i < sizex * sizey * 4; i += 4) { float col_src[4]; rgba_uchar_to_float(col_src, &gp_rect[i]); - blend_color_mix_float(&rr->rectf[i], &rr->rectf[i], col_src); + blend_color_mix_float(&rectf[i], &rectf[i], col_src); } GPU_offscreen_unbind(oglrender->ofs, true); @@ -478,12 +479,14 @@ static void screen_opengl_render_write(OGLRender *oglrender) rr = RE_AcquireResultRead(oglrender->re); + BKE_render_result_stamp_info(scene, camera, rr); + BKE_image_path_from_imformat( name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false, NULL); /* write images as individual images or stereo */ - ok = RE_WriteRenderViewsImage(oglrender->reports, rr, scene, camera, false, name); + ok = RE_WriteRenderViewsImage(oglrender->reports, rr, scene, false, name); RE_ReleaseResultImage(oglrender->re); @@ -805,7 +808,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) } } else { - ok = RE_WriteRenderViewsImage(op->reports, rr, scene, scene->camera, true, name); + ok = RE_WriteRenderViewsImage(op->reports, rr, scene, true, name); if (ok) { printf("Saved: %s", name); BKE_reportf(op->reports, RPT_INFO, "Saved file: %s", name); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 82a1cca2110..4eab5e56d84 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -65,6 +65,9 @@ #include "BIF_glutil.h" #include "BLF_api.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + #include "UI_interface.h" #include "UI_interface_icons.h" #include "UI_resources.h" @@ -2035,6 +2038,200 @@ void ED_region_info_draw(ARegion *ar, const char *text, int block, float fill_co glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); } +#define MAX_METADATA_STR 1024 + +const char *meta_data_list[] = +{ + "File", + "Strip", + "Note", + "Date", + "RenderTime", + "Marker", + "Time", + "Frame", + "Camera", + "Scene" +}; + +BLI_INLINE bool metadata_is_valid(ImBuf *ibuf, char *r_str, short index, int offset) +{ + return (IMB_metadata_get_field(ibuf, meta_data_list[index], r_str + offset, MAX_METADATA_STR - offset) && r_str[0]); +} + +static void metadata_draw_imbuf(ImBuf *ibuf, rcti rect, int fontid, const bool is_top, float factor) +{ + char temp_str[MAX_METADATA_STR]; + int line_width; + int ofs_y = 0; + short i; + int len; + const float height = BLF_height_max(fontid); + + if (is_top) { + for (i = 0; i < 4; i++) { + /* first line */ + if (i == 0) { + bool do_newline = false; + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[0]); + if (metadata_is_valid(ibuf, temp_str, 0, len)) { + BLF_position(fontid, rect.xmin + (0.2f * U.widget_unit), + rect.ymax - factor * (1.5f * U.widget_unit - UI_UNIT_Y), 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + do_newline = true; + } + + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[1]); + if (metadata_is_valid(ibuf, temp_str, 1, len)) { + line_width = BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + BLF_position(fontid, rect.xmax - line_width - (0.2f * U.widget_unit), + rect.ymax - factor * (1.5f * U.widget_unit - UI_UNIT_Y), 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + do_newline = true; + } + + if (do_newline) + ofs_y += (height + (0.2f * U.widget_unit)); + } + else if (i == 1) { + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]); + if (metadata_is_valid(ibuf, temp_str, i + 1, len)) { + BLF_position(fontid, rect.xmin + (0.2f * U.widget_unit), + rect.ymax - factor * (1.5f * U.widget_unit - UI_UNIT_Y) - ofs_y, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + ofs_y += (height + (0.2f * U.widget_unit)); + } + } + else { + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]); + if (metadata_is_valid(ibuf, temp_str, i + 1, len)) { + line_width = BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + BLF_position(fontid, rect.xmax - line_width - (0.2f * U.widget_unit), + rect.ymax - factor * (1.5f * U.widget_unit - UI_UNIT_Y) - ofs_y, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + ofs_y += (height + (0.2f * U.widget_unit)); + } + } + } + } + else { + int ofs_x = 0; + for (i = 5; i < 10; i++) { + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i]); + if (metadata_is_valid(ibuf, temp_str, i, len)) { + const int line_height = height; + BLF_position(fontid, rect.xmin + (0.2f * U.widget_unit) + ofs_x, + rect.ymin - line_height + factor * (U.widget_unit), 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + + ofs_x += BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX) + UI_UNIT_X; + } + } + } +} + +static float metadata_box_height_get(ImBuf *ibuf, int fontid, const bool is_top) +{ + char str[MAX_METADATA_STR]; + short i, count = 0; + const float height = BLF_height_max(fontid) + 0.2f * U.widget_unit; + + if (is_top) { + if (metadata_is_valid(ibuf, str, 0, 0) || metadata_is_valid(ibuf, str, 1, 0)) { + count++; + } + for (i = 2; i < 5; i++) { + if (metadata_is_valid(ibuf, str, i, 0)) { + count++; + } + } + } + else { + for (i = 5; i < 10; i++) { + if (metadata_is_valid(ibuf, str, i, 0)) { + count = 1; + } + } + } + + if (count) { + return (height * count + (0.2f * U.widget_unit)); + } + + return 0; +} + +#undef MAX_METADATA_STR + +void ED_region_image_metadata_draw(ARegion *ar, ImBuf *ibuf, float zoomx, float zoomy) +{ + uiStyle *style = UI_style_get_dpi(); + int fontid = style->widget.uifont_id; + float box_y; + rcti rect; + int x, y; + + if (!ibuf->metadata) + return; + + /* find window pixel coordinates of origin */ + UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y); + + glPushMatrix(); + + /* offset and zoom using ogl */ + glTranslatef(x, y, 0.0f); + glScalef(zoomx, zoomy, 1.0f); + + BLF_size(fontid, style->widgetlabel.points, U.dpi * zoomy); + + /* *** upper box*** */ + + /* get needed box height */ + box_y = metadata_box_height_get(ibuf, fontid, true); + + if (box_y) { + UI_ThemeColor(TH_METADATA_BG); + + /* set up rect */ + BLI_rcti_init(&rect, 0, ibuf->x, ibuf->y, ibuf->y + box_y); + /* draw top box */ + glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + BLF_clipping(fontid, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + BLF_enable(fontid, BLF_CLIPPING); + + UI_ThemeColor(TH_METADATA_TEXT); + metadata_draw_imbuf(ibuf, rect, fontid, true, zoomy); + + BLF_disable(fontid, BLF_CLIPPING); + } + + + /* *** lower box*** */ + + box_y = metadata_box_height_get(ibuf, fontid, false); + + if (box_y) { + UI_ThemeColor(TH_METADATA_BG); + + /* set up box rect */ + BLI_rcti_init(&rect, 0, ibuf->x, -box_y, 0); + /* draw top box */ + glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + BLF_clipping(fontid, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + BLF_enable(fontid, BLF_CLIPPING); + + UI_ThemeColor(TH_METADATA_TEXT); + metadata_draw_imbuf(ibuf, rect, fontid, false, zoomy); + + BLF_disable(fontid, BLF_CLIPPING); + } + + glPopMatrix(); +} + void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) { float gridsize, gridstep = 1.0f / 32.0f; diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 5f919c9b51d..48f8f587106 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -177,9 +177,7 @@ void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track) MovieTracking *tracking = &clip->tracking; MovieTrackingStabilization *stab = &tracking->stabilization; MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); - MovieTrackingPlaneTrack *plane_track, *next_plane_track; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); bool has_bundle = false, update_stab = false; char track_name_escaped[MAX_NAME], prefix[MAX_NAME * 2]; @@ -197,49 +195,7 @@ void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track) has_bundle = true; /* Make sure no plane will use freed track */ - for (plane_track = plane_tracks_base->first; - plane_track; - plane_track = next_plane_track) - { - bool found = false; - int i; - - next_plane_track = plane_track->next; - - for (i = 0; i < plane_track->point_tracksnr; i++) { - if (plane_track->point_tracks[i] == track) { - found = true; - break; - } - } - - if (!found) { - continue; - } - - if (plane_track->point_tracksnr > 4) { - int track_index; - MovieTrackingTrack **new_point_tracks; - - new_point_tracks = MEM_mallocN(sizeof(*new_point_tracks) * plane_track->point_tracksnr, - "new point tracks array"); - - for (i = 0, track_index = 0; i < plane_track->point_tracksnr; i++) { - if (plane_track->point_tracks[i] != track) { - new_point_tracks[track_index++] = plane_track->point_tracks[i]; - } - } - - MEM_freeN(plane_track->point_tracks); - plane_track->point_tracks = new_point_tracks; - plane_track->point_tracksnr--; - } - else { - /* Delete planes with less than 3 point tracks in it. */ - BKE_tracking_plane_track_free(plane_track); - BLI_freelinkN(plane_tracks_base, plane_track); - } - } + BKE_tracking_plane_tracks_remove_point_track(tracking, track); /* Delete f-curves associated with the track (such as weight, i.e.) */ BLI_strescape(track_name_escaped, track->name, sizeof(track_name_escaped)); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index db8881a865e..4521e980687 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -825,12 +825,8 @@ static void apply_mouse_slide(bContext *C, SlideMarkerData *data) plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) { - int i; - for (i = 0; i < plane_track->point_tracksnr; i++) { - if (plane_track->point_tracks[i] == data->track) { - BKE_tracking_track_plane_from_existing_motion(plane_track, framenr); - break; - } + if (BKE_tracking_plane_track_has_point_track(plane_track, data->track)) { + BKE_tracking_track_plane_from_existing_motion(plane_track, framenr); } } } @@ -3117,6 +3113,12 @@ static int join_tracks_exec(bContext *C, wmOperator *op) if (tracking->stabilization.rot_track == track) tracking->stabilization.rot_track = act_track; + /* TODO(sergey): Re-evaluate planes with auto-key. */ + BKE_tracking_plane_tracks_replace_point_track(tracking, + track, + act_track); + + BKE_tracking_track_free(track); BLI_freelinkN(tracksbase, track); } diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index a6f3a73841e..9763efbc7b5 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -307,10 +307,10 @@ static void file_draw_string(int sx, int sy, const char *string, float width, in /* no text clipping needed, UI_fontstyle_draw does it but is a bit too strict (for buttons it works) */ rect.xmin = sx; - rect.xmax = (int)(sx + ceil(width + 4.0f)); + rect.xmax = (int)(sx + ceil(width + 5.0f / UI_DPI_FAC)); rect.ymin = sy - height; rect.ymax = sy; - + UI_fontstyle_draw(&fs, &rect, fname); } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index c398d32dad5..2e9c2d96be5 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -580,7 +580,7 @@ static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) ImageUser *iuser = iuser_v; RenderLayer *rl; RenderPass *rp; - RenderPass *prev= NULL; + RenderPass *prev = NULL; int layer = iuser->layer; if (RE_HasFakeLayer(rr)) diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 0ca580986fa..863f6260be8 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -836,14 +836,23 @@ void draw_image_main(const bContext *C, ARegion *ar) ibuf = ED_space_image_acquire_buffer(sima, &lock); /* draw the image or grid */ - if (ibuf == NULL) + if (ibuf == NULL) { ED_region_grid_draw(ar, zoomx, zoomy); - else if (sima->flag & SI_DRAW_TILE) - draw_image_buffer_repeated(C, sima, ar, scene, ima, ibuf, zoomx, zoomy); - else if (ima && (ima->tpageflag & IMA_TILES)) - draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, 0.0f, 0.0, zoomx, zoomy); - else - draw_image_buffer(C, sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy); + } + else { + + if (sima->flag & SI_DRAW_TILE) + draw_image_buffer_repeated(C, sima, ar, scene, ima, ibuf, zoomx, zoomy); + else if (ima && (ima->tpageflag & IMA_TILES)) + draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, 0.0f, 0.0, zoomx, zoomy); + else + draw_image_buffer(C, sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy); + + if (sima->flag & SI_DRAW_METADATA) + ED_region_image_metadata_draw(ar, ibuf, zoomx, zoomy); + } + + ED_space_image_release_buffer(sima, ibuf, lock); /* paint helpers */ if (show_paint) @@ -866,8 +875,6 @@ void draw_image_main(const bContext *C, ARegion *ar) } #endif - ED_space_image_release_buffer(sima, ibuf, lock); - if (show_viewer) { BLI_unlock_thread(LOCK_DRAW_IMAGE); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 756f90fe560..db4029d9678 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1672,6 +1672,7 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI goto cleanup; } } + BKE_imbuf_stamp_info(rr, ibuf); } /* fancy multiview OpenEXR */ @@ -1693,6 +1694,7 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI } else { colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf); + IMB_metadata_copy(colormanaged_ibuf, ibuf); ok = BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, imf, save_copy); save_imbuf_post(ibuf, colormanaged_ibuf); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 32584a3a2df..a9a5e601e10 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -683,7 +683,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) View2D *v2d = &ar->v2d; //View2DScrollers *scrollers; float col[3]; - + /* XXX not supported yet, disabling for now */ scene->r.scemode &= ~R_COMP_CROP; diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 52156a2394e..4d37fcc9276 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -433,7 +433,7 @@ static void nla_draw_strip_text(AnimData *adt, NlaTrack *nlt, NlaStrip *strip, i /* just print the name and the range */ if (strip->flag & NLASTRIP_FLAG_TEMP_META) { - str_len = BLI_snprintf(str, sizeof(str), "%d) Temp-Meta", index); + str_len = BLI_snprintf_rlen(str, sizeof(str), "%d) Temp-Meta", index); } else { str_len = BLI_strncpy_rlen(str, strip->name, sizeof(str)); @@ -490,11 +490,11 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V * while also preserving some accuracy, since we do use floats */ /* start frame */ - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->start); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->start); UI_view2d_text_cache_add(v2d, strip->start - 1.0f, ymaxc + ytol, numstr, numstr_len, col); /* end frame */ - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->end); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->end); UI_view2d_text_cache_add(v2d, strip->end, ymaxc + ytol, numstr, numstr_len, col); } diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index db5d489cfbc..a1980c88d7e 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -208,12 +208,10 @@ void ED_node_tree_path_get_fixedbuf(SpaceNode *snode, char *value, int max_lengt value[0] = '\0'; for (path = snode->treepath.first, i = 0; path; path = path->next, ++i) { if (i == 0) { - BLI_strncpy(value, path->node_name, max_length); - size = strlen(path->node_name); + size = BLI_strncpy_rlen(value, path->node_name, max_length); } else { - BLI_snprintf(value, max_length, "/%s", path->node_name); - size = strlen(path->node_name) + 1; + size = BLI_snprintf_rlen(value, max_length, "/%s", path->node_name); } max_length -= size; if (max_length <= 0) diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index e5833103658..4c4378e004e 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -1654,9 +1654,14 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); + uiBut *but = UI_context_active_but_get(C); TreeElement *te; float fmval[2]; + if (but) { + UI_but_tooltip_timer_remove(C, but); + } + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); for (te = soops->tree.first; te; te = te->next) { diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index bd7b78bb885..a0760680cb3 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -442,12 +442,12 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla size_t numstr_len; if (direction == SEQ_LEFTHANDLE) { - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", seq->startdisp); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->startdisp); x1 = rx1; y1 -= 0.45f; } else { - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", seq->enddisp - 1); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->enddisp - 1); x1 = x2 - handsize_clamped * 0.75f; y1 = y2 + 0.05f; } @@ -999,6 +999,76 @@ void sequencer_display_size(Scene *scene, SpaceSeq *sseq, float r_viewrect[2]) } } +static void sequencer_draw_gpencil(const bContext *C) +{ + /* draw grease-pencil (image aligned) */ + ED_gpencil_draw_2dimage(C); + + /* ortho at pixel level */ + UI_view2d_view_restore(C); + + /* draw grease-pencil (screen aligned) */ + ED_gpencil_draw_view2d(C, 0); +} + +/* draws content borders plus safety borders if needed */ +static void sequencer_draw_borders(const SpaceSeq *sseq, const View2D *v2d, const Scene *scene) +{ + float x1 = v2d->tot.xmin; + float y1 = v2d->tot.ymin; + float x2 = v2d->tot.xmax; + float y2 = v2d->tot.ymax; + + /* border */ + setlinestyle(3); + + UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0); + + glBegin(GL_LINE_LOOP); + glVertex2f(x1 - 0.5f, y1 - 0.5f); + glVertex2f(x1 - 0.5f, y2 + 0.5f); + glVertex2f(x2 + 0.5f, y2 + 0.5f); + glVertex2f(x2 + 0.5f, y1 - 0.5f); + glEnd(); + + /* safety border */ + if (sseq->flag & SEQ_SHOW_SAFE_MARGINS) { + UI_draw_safe_areas( + x1, x2, y1, y2, + scene->safe_areas.title, + scene->safe_areas.action); + + if (sseq->flag & SEQ_SHOW_SAFE_CENTER) { + UI_draw_safe_areas( + x1, x2, y1, y2, + scene->safe_areas.title_center, + scene->safe_areas.action_center); + } + } + + setlinestyle(0); +} + +/* draws checkerboard background for transparent content */ +static void sequencer_draw_background(const SpaceSeq *sseq, View2D *v2d, const float viewrect[2]) +{ + /* setting up the view */ + UI_view2d_totRect_set(v2d, viewrect[0] + 0.5f, viewrect[1] + 0.5f); + UI_view2d_curRect_validate(v2d); + UI_view2d_view_ortho(v2d); + + /* only draw alpha for main buffer */ + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + if (sseq->flag & SEQ_USE_ALPHA) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax); + glColor4f(1.0, 1.0, 1.0, 1.0); + } + } +} + void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay, bool draw_overdrop) { struct Main *bmain = CTX_data_main(C); @@ -1015,6 +1085,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq const bool is_imbuf = ED_space_sequencer_check_show_imbuf(sseq); int format, type; bool glsl_used = false; + const bool draw_gpencil = ((sseq->flag & SEQ_SHOW_GPENCIL) && sseq->gpd); const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; if (G.is_rendering == false && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) { @@ -1037,6 +1108,9 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glClear(GL_COLOR_BUFFER_BIT); } + /* without this colors can flicker from previous opengl state */ + glColor4ub(255, 255, 255, 255); + /* only initialize the preview if a render is in progress */ if (G.is_rendering) return; @@ -1048,15 +1122,24 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* for now we only support Left/Right */ ibuf = sequencer_ibuf_get(bmain, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]); - if (ibuf == NULL) - return; + if ((ibuf == NULL) || + (ibuf->rect == NULL && ibuf->rect_float == NULL)) + { + /* gpencil can also be drawn if no imbuf is invalid */ + if (draw_gpencil && is_imbuf) { + sequencer_display_size(scene, sseq, viewrect); - if (ibuf->rect == NULL && ibuf->rect_float == NULL) + sequencer_draw_background(sseq, v2d, viewrect); + sequencer_draw_borders(sseq, v2d, scene); + + sequencer_draw_gpencil(C); + } return; + } sequencer_display_size(scene, sseq, viewrect); - if (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0) { + if (!draw_backdrop && (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0)) { SequencerScopes *scopes = &sseq->scopes; sequencer_check_scopes(scopes, ibuf); @@ -1136,7 +1219,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq } } } - + if (scope) { IMB_freeImBuf(ibuf); ibuf = scope; @@ -1284,59 +1367,21 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq if (!scope) IMB_freeImBuf(ibuf); - - if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - - float x1 = v2d->tot.xmin; - float y1 = v2d->tot.ymin; - float x2 = v2d->tot.xmax; - float y2 = v2d->tot.ymax; - - /* border */ - setlinestyle(3); - - UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0); - glBegin(GL_LINE_LOOP); - glVertex2f(x1 - 0.5f, y1 - 0.5f); - glVertex2f(x1 - 0.5f, y2 + 0.5f); - glVertex2f(x2 + 0.5f, y2 + 0.5f); - glVertex2f(x2 + 0.5f, y1 - 0.5f); - glEnd(); - - /* safety border */ - if (sseq->flag & SEQ_SHOW_SAFE_MARGINS) { - UI_draw_safe_areas( - x1, x2, y1, y2, - scene->safe_areas.title, - scene->safe_areas.action); - - if (sseq->flag & SEQ_SHOW_SAFE_CENTER) { - UI_draw_safe_areas( - x1, x2, y1, y2, - scene->safe_areas.title_center, - scene->safe_areas.action_center); - } - } + if (draw_overdrop) { + return; + } - setlinestyle(0); + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + sequencer_draw_borders(sseq, v2d, scene); } - - if (sseq->flag & SEQ_SHOW_GPENCIL) { - if (is_imbuf) { - /* draw grease-pencil (image aligned) */ - ED_gpencil_draw_2dimage(C); - } + + if (draw_gpencil && is_imbuf) { + sequencer_draw_gpencil(C); } - - /* ortho at pixel level */ - UI_view2d_view_restore(C); - - if (sseq->flag & SEQ_SHOW_GPENCIL) { - if (is_imbuf) { - /* draw grease-pencil (screen aligned) */ - ED_gpencil_draw_view2d(C, 0); - } + else { + /* ortho at pixel level */ + UI_view2d_view_restore(C); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 9283615ff09..96e330ed79b 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3372,7 +3372,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe unit->system, B_UNIT_LENGTH, do_split, false); } else { - numstr_len = BLI_snprintf(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2)); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2)); } view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); @@ -3449,7 +3449,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe angle = angle_normalized_v3v3(no_a, no_b); - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); } @@ -3474,7 +3474,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe 3, unit->system, B_UNIT_AREA, do_split, false); \ } \ else { \ - numstr_len = BLI_snprintf(numstr, sizeof(numstr), conv_float, area); \ + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, area); \ } \ view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); \ } (void)0 @@ -3592,7 +3592,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe angle = angle_v3v3v3(v1, v2, v3); - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); interp_v3_v3v3(fvec, vmid, v2_local, 0.8f); view3d_cached_text_draw_add(fvec, numstr, numstr_len, 0, txt_flag, col); } @@ -3623,7 +3623,7 @@ static void draw_em_indices(BMEditMesh *em) UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i); view3d_cached_text_draw_add(v->co, numstr, numstr_len, 0, txt_flag, col); } i++; @@ -3635,7 +3635,7 @@ static void draw_em_indices(BMEditMesh *em) UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i); mid_v3_v3v3(pos, e->v1->co, e->v2->co); view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col); } @@ -3649,7 +3649,7 @@ static void draw_em_indices(BMEditMesh *em) BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { BM_face_calc_center_mean(f, pos); - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i); view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col); } i++; @@ -5793,15 +5793,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if (part->draw & PART_DRAW_NUM) { if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { - numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health); + numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health); } else { - numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%d", a); + numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d", a); } } else { if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { - numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%.2f", pa_health); + numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%.2f", pa_health); } } @@ -6058,7 +6058,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { float vec_txt[3]; - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%i", a); + numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%i", a); /* use worldspace because object matrix is already applied */ mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co); view3d_cached_text_draw_add(vec_txt, numstr, numstr_len, diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 8558a90d5b7..c70977a2a85 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1183,7 +1183,7 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN break; case NC_GPENCIL: - if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) { + if (wmn->data == ND_DATA || ELEM(wmn->action, NA_EDITED, NA_SELECTED)) { ED_region_tag_redraw(ar); } break; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 546a3058fba..e2a4e0fea6b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1552,16 +1552,13 @@ ImBuf *ED_view3d_backbuf_read(ViewContext *vc, short xmin, short ymin, short xma /* smart function to sample a rect spiralling outside, nice for backbuf selection */ unsigned int ED_view3d_backbuf_sample_rect( ViewContext *vc, const int mval[2], int size, - unsigned int min, unsigned int max, float *r_dist, const bool is_strict, - void *handle, bool (*indextest)(void *handle, unsigned int index)) + unsigned int min, unsigned int max, float *r_dist) { struct ImBuf *buf; - unsigned int *bufmin, *bufmax, *tbuf; + const unsigned int *bufmin, *bufmax, *tbuf; int minx, miny; int a, b, rc, nr, amount, dirvec[4][2]; - int distance = 0; unsigned int index = 0; - bool indexok = false; amount = (size - 1) / 2; @@ -1585,21 +1582,19 @@ unsigned int ED_view3d_backbuf_sample_rect( for (nr = 1; nr <= size; nr++) { for (a = 0; a < 2; a++) { - for (b = 0; b < nr; b++, distance++) { - if (*tbuf && *tbuf >= min && *tbuf < max) { /* we got a hit */ - if (is_strict) { - indexok = indextest(handle, *tbuf - min + 1); - if (indexok) { - *r_dist = sqrtf((float)distance); - index = *tbuf - min + 1; - goto exit; - } - } - else { - *r_dist = sqrtf((float)distance); /* XXX, this distance is wrong - */ - index = *tbuf - min + 1; /* messy yah, but indices start at 1 */ - goto exit; - } + for (b = 0; b < nr; b++) { + if (*tbuf && *tbuf >= min && *tbuf < max) { + /* we got a hit */ + + /* get x,y pixel coords from the offset + * (manhatten distance in keeping with other screen-based selection) */ + *r_dist = (float)( + abs(((tbuf - buf->rect) % size) - (size / 2)) + + abs(((tbuf - buf->rect) / size) - (size / 2))); + + /* indices start at 1 here */ + index = (*tbuf - min) + 1; + goto exit; } tbuf += (dirvec[rc][0] + dirvec[rc][1]); @@ -1626,17 +1621,19 @@ static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, Ima if ((ima->flag & IMA_IS_STEREO)) { iuser->flag |= IMA_SHOW_STEREO; - if ((scene->r.scemode & R_MULTIVIEW) == 0) + if ((scene->r.scemode & R_MULTIVIEW) == 0) { iuser->multiview_eye = STEREO_LEFT_ID; - - /* show only left or right camera */ - else if (v3d->stereo3d_camera != STEREO_3D_ID) + } + else if (v3d->stereo3d_camera != STEREO_3D_ID) { + /* show only left or right camera */ iuser->multiview_eye = v3d->stereo3d_camera; + } BKE_image_multiview_index(ima, iuser); } - else + else { iuser->flag &= ~IMA_SHOW_STEREO; + } } static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index a3dfd62ba6b..469a7e63903 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -296,10 +296,10 @@ static void fly_update_header(bContext *C, FlyInfo *fly) "Ctrl: free look, " "X: Upright x axis (%s), " "Z: Upright z axis (%s), " - "(+/- | Wheel): speed"), + "(+/- | Wheel): speed"), WM_bool_as_string(fly->xlock != FLY_AXISLOCK_STATE_OFF), - WM_bool_as_string(fly->zlock != FLY_AXISLOCK_STATE_OFF)); + WM_bool_as_string(fly->zlock != FLY_AXISLOCK_STATE_OFF)); ED_area_headerprint(CTX_wm_area(C), header); #undef HEADER_LENGTH diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 11756e4feca..fb98f8b91a7 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -344,7 +344,7 @@ static void walk_update_header(bContext *C, WalkInfo *walk) char header[HEADER_LENGTH]; BLI_snprintf(header, HEADER_LENGTH, IFACE_("LMB/Return: confirm, Esc/RMB: cancel, " - "Tab: gravity (%s), " + "Tab: gravity (%s), " "WASD: move around, " "Shift: fast, Alt: slow, " "QE: up and down, MMB/Space: teleport, V: jump, " diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 562e9e292e4..99cfc23a168 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -896,6 +896,11 @@ static void postOrtho(const bool ortho) } } +BLI_INLINE bool manipulator_rotate_is_visible(const int drawflags) +{ + return (drawflags & (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z)); +} + static void draw_manipulator_rotate( View3D *v3d, RegionView3D *rv3d, const int drawflags, const int combo, const bool is_moving, const bool is_picksel) @@ -909,8 +914,8 @@ static void draw_manipulator_rotate( const int colcode = (is_moving) ? MAN_MOVECOL : MAN_RGB; bool ortho; - /* when called while moving in mixed mode, do not draw when... */ - if ((drawflags & MAN_ROT_C) == 0) return; + /* skip drawing if all axes are locked */ + if (manipulator_rotate_is_visible(drawflags) == false) return; /* Init stuff */ glDisable(GL_DEPTH_TEST); @@ -1449,8 +1454,8 @@ static void draw_manipulator_rotate_cyl( int axis_order[3] = {2, 0, 1}; int i; - /* when called while moving in mixed mode, do not draw when... */ - if ((drawflags & MAN_ROT_C) == 0) return; + /* skip drawing if all axes are locked */ + if (manipulator_rotate_is_visible(drawflags) == false) return; manipulator_axis_order(rv3d, axis_order); diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index f4189a18da4..d1495d85e64 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -24,6 +24,7 @@ set(INC ../../blenkernel ../../blenlib ../../bmesh + ../../imbuf ../../gpu ../../makesdna ../../makesrna |