Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2015-04-22 20:34:37 +0300
committerAntony Riakiotakis <kalast@gmail.com>2015-04-22 20:34:37 +0300
commita6167306a29d1acf1a36539604612c98a7051273 (patch)
tree6c35087895b0ee0513b612734774f896b3b1bc7f /source/blender/editors
parentd794ce627faab1f107ef8fd366294b9990cfe446 (diff)
parent3174cbe8f2d3fa384b644a62b3c265a946ab866f (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')
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c152
-rw-r--r--source/blender/editors/include/ED_mesh.h11
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_view3d.h3
-rw-r--r--source/blender/editors/include/UI_interface.h1
-rw-r--r--source/blender/editors/include/UI_resources.h5
-rw-r--r--source/blender/editors/interface/interface.c55
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c55
-rw-r--r--source/blender/editors/interface/interface_intern.h10
-rw-r--r--source/blender/editors/interface/interface_widgets.c17
-rw-r--r--source/blender/editors/interface/resources.c16
-rw-r--r--source/blender/editors/interface/view2d_ops.c8
-rw-r--r--source/blender/editors/mesh/editmesh_select.c439
-rw-r--r--source/blender/editors/mesh/meshtools.c4
-rw-r--r--source/blender/editors/object/object_edit.c71
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_ops.c1
-rw-r--r--source/blender/editors/render/render_opengl.c13
-rw-r--r--source/blender/editors/screen/area.c197
-rw-r--r--source/blender/editors/space_clip/clip_utils.c46
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c14
-rw-r--r--source/blender/editors/space_file/file_draw.c4
-rw-r--r--source/blender/editors/space_image/image_buttons.c2
-rw-r--r--source/blender/editors/space_image/image_draw.c25
-rw-r--r--source/blender/editors/space_image/image_ops.c2
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_nla/nla_draw.c6
-rw-r--r--source/blender/editors/space_node/space_node.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c5
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c157
-rw-r--r--source/blender/editors/space_view3d/drawobject.c22
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c47
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c2
-rw-r--r--source/blender/editors/transform/transform_manipulator.c13
-rw-r--r--source/blender/editors/util/CMakeLists.txt1
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