Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Wed, 19 Jul 2017 04:38:22 +0000 (14:38 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 19 Jul 2017 04:38:22 +0000 (14:38 +1000)
intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemCocoa.mm
intern/ghost/intern/GHOST_WindowCocoa.mm
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/space_file/filelist.c
source/blender/editors/space_file/filelist.h
source/blender/editors/space_file/space_file.c
source/blender/editors/space_node/node_group.c

index b142c2f7194f022cf2d9b33b1a7758f9c06e456f..6802ad42c7b55f2fe02d99961cf79e912d4e44bc 100644 (file)
@@ -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? */
index 173f59c9c8f417954237738189b98fc4c12547cb..4582dfb2a4970750108645584758dbd1da16ce47 100644 (file)
@@ -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;
                                        }
                                }
index b0feb11a6afc079a1076cf40542043891d169d25..a018bbe15c6e417d7de7b1220c9baeb4faaf00f1 100644 (file)
@@ -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 */
index d8812b85c196aac5b164db12d34629813f1b0c74..da1bfd397b855e9eba2f1579afdc3ef8846196a6 100644 (file)
@@ -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);
 }
 
 /**
index 59064ec332ef2dba95ac477f1d40ce2dc2fc8ab2..278cd511abb699c1d55b2b373382d6e994e8f4a1 100644 (file)
@@ -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');
        }
 
index ace3bb5b4f8e34a872707eafb8f1cd45fbc80139..2abb8dcf20fdfaabbae61d153c4f01d8686bbc2f 100644 (file)
@@ -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();
index 6c33091ff011df10a76eed3c3d44f524e829dc89..8e548d7a9bd43894903a8813ff47669cb77669a9 100644 (file)
@@ -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,28 +635,31 @@ 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)) {
+                                                       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)) {
+                               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;
+                                               }
+                                       }
                                }
                        }
                        if (is_filtered && (filter->filter_search[0] != '\0')) {
@@ -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;
index f4304681780a5e8569829205f89f3ae1308b71de..4e9c1e0dd1dd0fb1f5e293b76f83fa1495fbc336 100644 (file)
@@ -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);
index 269b1146ba04f6331f1f1264c5a6489e4fe8a211..6e4815af0323daa8813828559fc50312a8207ecc 100644 (file)
@@ -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);
index 914f8ffbe105d80a89fa1d71f41fe6676e758861..9d750bfe3483abcbb9cd7cdc6c8db1f2b8035d58 100644 (file)
@@ -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);