Merge branch 'master' into blender2.8
This commit is contained in:
@@ -292,11 +292,6 @@ protected:
|
||||
/** Ignores window size messages (when window is dragged). */
|
||||
bool m_ignoreWindowSizedMessages;
|
||||
|
||||
/** Stores the mouse cursor delta due to setting a new cursor position
|
||||
* Needed because cocoa event delta cursor move takes setCursorPosition changes too.
|
||||
*/
|
||||
GHOST_TInt32 m_cursorDelta_x, m_cursorDelta_y;
|
||||
|
||||
/** Temporarily ignore momentum scroll events */
|
||||
bool m_ignoreMomentumScroll;
|
||||
/** Is the scroll wheel event generated by a multitouch trackpad or mouse? */
|
||||
|
||||
@@ -366,8 +366,6 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
|
||||
char *rstring = NULL;
|
||||
|
||||
m_modifierMask =0;
|
||||
m_cursorDelta_x=0;
|
||||
m_cursorDelta_y=0;
|
||||
m_outsideLoopEventProcessed = false;
|
||||
m_needDelayedApplicationBecomeActiveEventProcessing = false;
|
||||
m_displayManager = new GHOST_DisplayManagerCocoa ();
|
||||
@@ -644,6 +642,13 @@ GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(GHOST_TInt32 x, GHOST_T
|
||||
|
||||
CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf));
|
||||
|
||||
// See https://stackoverflow.com/a/17559012. By default, hardware events
|
||||
// will be suppressed for 500ms after a synthetic mouse event. For unknown
|
||||
// reasons CGEventSourceSetLocalEventsSuppressionInterval does not work,
|
||||
// however calling CGAssociateMouseAndMouseCursorPosition also removes the
|
||||
// delay, even if this is undocumented.
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@@ -1354,9 +1359,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
||||
case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
|
||||
{
|
||||
NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
|
||||
GHOST_TInt32 x_mouse= mousePos.x;
|
||||
GHOST_TInt32 y_mouse= mousePos.y;
|
||||
GHOST_TInt32 x_accum, y_accum, x_cur, y_cur, x, y;
|
||||
GHOST_TInt32 x_mouse = mousePos.x;
|
||||
GHOST_TInt32 y_mouse = mousePos.y;
|
||||
GHOST_Rect bounds, windowBounds, correctedBounds;
|
||||
|
||||
/* fallback to window bounds */
|
||||
@@ -1370,29 +1374,26 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
||||
correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b;
|
||||
correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t;
|
||||
|
||||
//Update accumulation counts
|
||||
//Get accumulation from previous mouse warps
|
||||
GHOST_TInt32 x_accum, y_accum;
|
||||
window->getCursorGrabAccum(x_accum, y_accum);
|
||||
x_accum += [event deltaX]-m_cursorDelta_x;
|
||||
y_accum += -[event deltaY]-m_cursorDelta_y; //Strange Apple implementation (inverted coordinates for the deltaY) ...
|
||||
window->setCursorGrabAccum(x_accum, y_accum);
|
||||
|
||||
//Warp mouse cursor if needed
|
||||
x_mouse += [event deltaX]-m_cursorDelta_x;
|
||||
y_mouse += -[event deltaY]-m_cursorDelta_y;
|
||||
correctedBounds.wrapPoint(x_mouse, y_mouse, 2);
|
||||
|
||||
//Compensate for mouse moved event taking cursor position set into account
|
||||
m_cursorDelta_x = x_mouse-mousePos.x;
|
||||
m_cursorDelta_y = y_mouse-mousePos.y;
|
||||
GHOST_TInt32 warped_x_mouse = x_mouse;
|
||||
GHOST_TInt32 warped_y_mouse = y_mouse;
|
||||
correctedBounds.wrapPoint(warped_x_mouse, warped_y_mouse, 4);
|
||||
|
||||
//Set new cursor position
|
||||
window->clientToScreenIntern(x_mouse, y_mouse, x_cur, y_cur);
|
||||
setMouseCursorPosition(x_cur, y_cur); /* wrap */
|
||||
if (x_mouse != warped_x_mouse || y_mouse != warped_y_mouse) {
|
||||
GHOST_TInt32 warped_x, warped_y;
|
||||
window->clientToScreenIntern(warped_x_mouse, warped_y_mouse, warped_x, warped_y);
|
||||
setMouseCursorPosition(warped_x, warped_y); /* wrap */
|
||||
window->setCursorGrabAccum(x_accum + (x_mouse - warped_x_mouse), y_accum + (y_mouse - warped_y_mouse));
|
||||
}
|
||||
|
||||
//Post event
|
||||
window->getCursorGrabInitPos(x_cur, y_cur);
|
||||
window->screenToClientIntern(x_cur, y_cur, x_cur, y_cur);
|
||||
window->clientToScreenIntern(x_cur + x_accum, y_cur + y_accum, x, y);
|
||||
//Generate event
|
||||
GHOST_TInt32 x, y;
|
||||
window->clientToScreenIntern(x_mouse + x_accum, y_mouse + y_accum, x, y);
|
||||
pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
|
||||
break;
|
||||
}
|
||||
@@ -1404,9 +1405,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
||||
|
||||
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
|
||||
pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
|
||||
|
||||
m_cursorDelta_x=0;
|
||||
m_cursorDelta_y=0; //Mouse motion occurred between two cursor warps, so we can reset the delta counter
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1311,9 +1311,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode
|
||||
//Make window key if it wasn't to get the mouse move events
|
||||
[m_window makeKeyWindow];
|
||||
|
||||
//Dissociate cursor position even for warp mode, to allow mouse acceleration to work even when warping the cursor
|
||||
err = CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
}
|
||||
@@ -1323,7 +1320,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode
|
||||
setWindowCursorVisibility(true);
|
||||
}
|
||||
|
||||
err = CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
|
||||
/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
|
||||
setCursorGrabAccum(0, 0);
|
||||
m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */
|
||||
|
||||
@@ -2144,9 +2144,14 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
|
||||
|
||||
/**
|
||||
* \param float_precision For number buttons the precision to use or -1 to fallback to the button default.
|
||||
* \param use_exp_float Use exponent representation of floats when out of reasonable range (outside of 1e3/1e-3).
|
||||
*/
|
||||
void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
|
||||
void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision, const bool use_exp_float, bool *r_use_exp_float)
|
||||
{
|
||||
if (r_use_exp_float) {
|
||||
*r_use_exp_float = false;
|
||||
}
|
||||
|
||||
if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
|
||||
PropertyType type;
|
||||
const char *buf = NULL;
|
||||
@@ -2215,16 +2220,31 @@ void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int
|
||||
}
|
||||
else {
|
||||
const int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision;
|
||||
BLI_snprintf(str, maxlen, "%.*f", prec, value);
|
||||
if (use_exp_float) {
|
||||
const int l10 = (int)log10(fabs(value));
|
||||
if (l10 < -6 || l10 > 12) {
|
||||
BLI_snprintf(str, maxlen, "%.*g", prec, value);
|
||||
if (r_use_exp_float) {
|
||||
*r_use_exp_float = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(str, maxlen, "%.*f", prec - l10 + (int)(l10 < 0), value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(str, maxlen, "%.*f", prec, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
BLI_snprintf(str, maxlen, "%d", (int)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
void ui_but_string_get(uiBut *but, char *str, const size_t maxlen)
|
||||
{
|
||||
ui_but_string_get_ex(but, str, maxlen, -1);
|
||||
ui_but_string_get_ex(but, str, maxlen, -1, false, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2313,7 +2313,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
|
||||
/* Get many decimal places, then strip trailing zeros.
|
||||
* note: too high values start to give strange results */
|
||||
char buf_copy[UI_MAX_DRAW_STR];
|
||||
ui_but_string_get_ex(but, buf_copy, sizeof(buf_copy), UI_PRECISION_FLOAT_MAX);
|
||||
ui_but_string_get_ex(but, buf_copy, sizeof(buf_copy), UI_PRECISION_FLOAT_MAX, false, NULL);
|
||||
BLI_str_rstrip_float_zero(buf_copy, '\0');
|
||||
|
||||
WM_clipboard_text_set(buf_copy, 0);
|
||||
@@ -3054,6 +3054,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
int len;
|
||||
const bool is_num_but = ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER);
|
||||
bool no_zero_strip = false;
|
||||
|
||||
if (data->str) {
|
||||
MEM_freeN(data->str);
|
||||
@@ -3082,14 +3083,16 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
|
||||
data->maxlen = ui_but_string_get_max_length(but);
|
||||
if (data->maxlen != 0) {
|
||||
data->str = MEM_callocN(sizeof(char) * data->maxlen, "textedit str");
|
||||
ui_but_string_get(but, data->str, data->maxlen);
|
||||
/* We do not want to truncate precision to default here, it's nice to show value,
|
||||
* not to edit it - way too much precision is lost then. */
|
||||
ui_but_string_get_ex(but, data->str, data->maxlen, UI_PRECISION_FLOAT_MAX, true, &no_zero_strip);
|
||||
}
|
||||
else {
|
||||
data->is_str_dynamic = true;
|
||||
data->str = ui_but_string_get_dynamic(but, &data->maxlen);
|
||||
}
|
||||
|
||||
if (ui_but_is_float(but) && !ui_but_is_unit(but) && !ui_but_anim_expression_get(but, NULL, 0)) {
|
||||
if (ui_but_is_float(but) && !ui_but_is_unit(but) && !ui_but_anim_expression_get(but, NULL, 0) && !no_zero_strip) {
|
||||
BLI_str_rstrip_float_zero(data->str, '\0');
|
||||
}
|
||||
|
||||
|
||||
@@ -475,7 +475,9 @@ extern void ui_hsvcircle_pos_from_vals(struct uiBut *but, const rcti *rect, floa
|
||||
extern void ui_hsvcube_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp);
|
||||
bool ui_but_is_colorpicker_display_space(struct uiBut *but);
|
||||
|
||||
extern void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) ATTR_NONNULL();
|
||||
extern void ui_but_string_get_ex(
|
||||
uiBut *but, char *str, const size_t maxlen,
|
||||
const int float_precision, const bool use_exp_float, bool *r_use_exp_float) ATTR_NONNULL(1, 2);
|
||||
extern void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) ATTR_NONNULL();
|
||||
extern char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size);
|
||||
extern void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL();
|
||||
|
||||
@@ -277,9 +277,10 @@ typedef struct FileListFilter {
|
||||
|
||||
/* FileListFilter.flags */
|
||||
enum {
|
||||
FLF_HIDE_DOT = 1 << 0,
|
||||
FLF_HIDE_PARENT = 1 << 1,
|
||||
FLF_HIDE_LIB_DIR = 1 << 2,
|
||||
FLF_DO_FILTER = 1 << 0,
|
||||
FLF_HIDE_DOT = 1 << 1,
|
||||
FLF_HIDE_PARENT = 1 << 2,
|
||||
FLF_HIDE_LIB_DIR = 1 << 3,
|
||||
};
|
||||
|
||||
typedef struct FileList {
|
||||
@@ -594,24 +595,27 @@ static bool is_filtered_file(FileListInternEntry *file, const char *UNUSED(root)
|
||||
{
|
||||
bool is_filtered = !is_hidden_file(file->relpath, filter);
|
||||
|
||||
if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
if (file->typeflag & FILE_TYPE_DIR) {
|
||||
if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
|
||||
if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) {
|
||||
is_filtered = false;
|
||||
if (is_filtered && (filter->flags & FLF_DO_FILTER) && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
/* We only check for types if some type are enabled in filtering. */
|
||||
if (filter->filter) {
|
||||
if (file->typeflag & FILE_TYPE_DIR) {
|
||||
if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
|
||||
if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) {
|
||||
is_filtered = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(filter->filter & FILE_TYPE_FOLDER)) {
|
||||
is_filtered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(filter->filter & FILE_TYPE_FOLDER)) {
|
||||
if (!(file->typeflag & filter->filter)) {
|
||||
is_filtered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(file->typeflag & filter->filter)) {
|
||||
is_filtered = false;
|
||||
}
|
||||
}
|
||||
if (is_filtered && (filter->filter_search[0] != '\0')) {
|
||||
if (fnmatch(filter->filter_search, file->relpath, FNM_CASEFOLD) != 0) {
|
||||
is_filtered = false;
|
||||
@@ -631,27 +635,30 @@ static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileLis
|
||||
|
||||
if (BLO_library_path_explode(path, dir, &group, &name)) {
|
||||
is_filtered = !is_hidden_file(file->relpath, filter);
|
||||
if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
if (file->typeflag & FILE_TYPE_DIR) {
|
||||
if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
|
||||
if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) {
|
||||
is_filtered = false;
|
||||
if (is_filtered && (filter->flags & FLF_DO_FILTER) && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
/* We only check for types if some type are enabled in filtering. */
|
||||
if (filter->filter || filter->filter_id) {
|
||||
if (file->typeflag & FILE_TYPE_DIR) {
|
||||
if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
|
||||
if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) {
|
||||
is_filtered = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(filter->filter & FILE_TYPE_FOLDER)) {
|
||||
is_filtered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(filter->filter & FILE_TYPE_FOLDER)) {
|
||||
if (is_filtered && group) {
|
||||
if (!name && (filter->flags & FLF_HIDE_LIB_DIR)) {
|
||||
is_filtered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_filtered && group) {
|
||||
if (!name && (filter->flags & FLF_HIDE_LIB_DIR)) {
|
||||
is_filtered = false;
|
||||
}
|
||||
else {
|
||||
unsigned int filter_id = groupname_to_filter_id(group);
|
||||
if (!(filter_id & filter->filter_id)) {
|
||||
is_filtered = false;
|
||||
else {
|
||||
unsigned int filter_id = groupname_to_filter_id(group);
|
||||
if (!(filter_id & filter->filter_id)) {
|
||||
is_filtered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -729,12 +736,17 @@ void filelist_filter(FileList *filelist)
|
||||
MEM_freeN(filtered_tmp);
|
||||
}
|
||||
|
||||
void filelist_setfilter_options(FileList *filelist, const bool hide_dot, const bool hide_parent,
|
||||
void filelist_setfilter_options(FileList *filelist, const bool do_filter,
|
||||
const bool hide_dot, const bool hide_parent,
|
||||
const unsigned int filter, const unsigned int filter_id,
|
||||
const char *filter_glob, const char *filter_search)
|
||||
{
|
||||
bool update = false;
|
||||
|
||||
if (((filelist->filter_data.flags & FLF_DO_FILTER) != 0) != (do_filter != 0)) {
|
||||
filelist->filter_data.flags ^= FLF_DO_FILTER;
|
||||
update = true;
|
||||
}
|
||||
if (((filelist->filter_data.flags & FLF_HIDE_DOT) != 0) != (hide_dot != 0)) {
|
||||
filelist->filter_data.flags ^= FLF_HIDE_DOT;
|
||||
update = true;
|
||||
|
||||
@@ -68,7 +68,8 @@ int folderlist_clear_next(struct SpaceFile *sfile);
|
||||
void filelist_setsorting(struct FileList *filelist, const short sort);
|
||||
void filelist_sort(struct FileList *filelist);
|
||||
|
||||
void filelist_setfilter_options(struct FileList *filelist, const bool hide_dot, const bool hide_parent,
|
||||
void filelist_setfilter_options(struct FileList *filelist, const bool do_filter,
|
||||
const bool hide_dot, const bool hide_parent,
|
||||
const unsigned int filter, const unsigned int filter_id,
|
||||
const char *filter_glob, const char *filter_search);
|
||||
void filelist_filter(struct FileList *filelist);
|
||||
|
||||
@@ -223,9 +223,10 @@ static void file_refresh(const bContext *C, ScrArea *sa)
|
||||
filelist_setdir(sfile->files, params->dir);
|
||||
filelist_setrecursion(sfile->files, params->recursion_level);
|
||||
filelist_setsorting(sfile->files, params->sort);
|
||||
filelist_setfilter_options(sfile->files, (params->flag & FILE_HIDE_DOT) != 0,
|
||||
filelist_setfilter_options(sfile->files, (params->flag & FILE_FILTER) != 0,
|
||||
(params->flag & FILE_HIDE_DOT) != 0,
|
||||
false, /* TODO hide_parent, should be controllable? */
|
||||
(params->flag & FILE_FILTER) ? params->filter : 0,
|
||||
params->filter,
|
||||
params->filter_id,
|
||||
params->filter_glob,
|
||||
params->filter_search);
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "DNA_anim_types.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
@@ -186,6 +187,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
|
||||
bNode *node, *nextnode;
|
||||
bNodeTree *ngroup, *wgroup;
|
||||
ListBase anim_basepaths = {NULL, NULL};
|
||||
LinkNode *nodes_delayed_free = NULL;
|
||||
|
||||
ngroup = (bNodeTree *)gnode->id;
|
||||
|
||||
@@ -208,8 +210,8 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
|
||||
* This also removes remaining links to and from interface nodes.
|
||||
*/
|
||||
if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
|
||||
nodeFreeNode(wgroup, node);
|
||||
continue;
|
||||
/* We must delay removal since sockets will reference this node. see: T52092 */
|
||||
BLI_linklist_prepend(&nodes_delayed_free, node);
|
||||
}
|
||||
|
||||
/* keep track of this node's RNA "base" path (the part of the path identifying the node)
|
||||
@@ -336,6 +338,11 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
|
||||
}
|
||||
}
|
||||
|
||||
while (nodes_delayed_free) {
|
||||
node = BLI_linklist_pop(&nodes_delayed_free);
|
||||
nodeFreeNode(ntree, node);
|
||||
}
|
||||
|
||||
/* delete the group instance */
|
||||
nodeFreeNode(ntree, gnode);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user