Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Fri, 8 Dec 2017 13:39:17 +0000 (14:39 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Fri, 8 Dec 2017 13:39:17 +0000 (14:39 +0100)
Conflicts:
source/blender/editors/interface/interface_templates.c

1  2 
source/blender/editors/interface/interface_templates.c

index 7c58ac88a236c0d99d45e87186ec973cb1788869,b5f88158e16b7b8028286b137008a49e2e312fd9..fae71f1fbc22c381500b79cc81c09271de111f03
  #include "BKE_colorband.h"
  #include "BKE_colortools.h"
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_global.h"
  #include "BKE_idcode.h"
  #include "BKE_idprop.h"
 +#include "BKE_layer.h"
  #include "BKE_library.h"
  #include "BKE_linestyle.h"
  #include "BKE_main.h"
@@@ -72,9 -72,6 +72,9 @@@
  #include "BKE_sca.h"
  #include "BKE_screen.h"
  
 +#include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_build.h"
 +
  #include "ED_screen.h"
  #include "ED_object.h"
  #include "ED_render.h"
  
  // #define USE_OP_RESET_BUT  // we may want to make this optional, disable for now.
  
 +/* defines for templateID/TemplateSearch */
 +#define TEMPLATE_SEARCH_TEXTBUT_WIDTH  (UI_UNIT_X * 6)
 +#define TEMPLATE_SEARCH_TEXTBUT_HEIGHT  UI_UNIT_Y
 +
  
  void UI_template_fix_linking(void)
  {
  }
  
 +/**
 + * Add a block button for the search menu for templateID and templateSearch.
 + */
 +static void template_add_button_search_menu(
 +        const bContext *C, uiLayout *layout, uiBlock *block,
 +        PointerRNA *ptr, PropertyRNA *prop,
 +        uiBlockCreateFunc block_func, void *block_argN, const char * const tip,
 +        const bool use_previews, const bool editable)
 +{
 +      PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop);
 +      ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL;
 +      const ID *idfrom = ptr->id.data;
 +      const StructRNA *type = active_ptr.type ? active_ptr.type : RNA_property_pointer_type(ptr, prop);
 +      uiBut *but;
 +
 +      if (use_previews) {
 +              ARegion *region = CTX_wm_region(C);
 +              const bool use_big_size = (region->regiontype != RGN_TYPE_HEADER); /* silly check, could be more generic */
 +              /* Ugly exception for screens here, drawing their preview in icon size looks ugly/useless */
 +              const bool use_preview_icon = use_big_size || (id && (GS(id->name) != ID_SCR));
 +              const short width = UI_UNIT_X * (use_big_size ? 6 : 1.6f);
 +              const short height = UI_UNIT_Y * (use_big_size ? 6 : 1);
 +
 +              but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, width, height, tip);
 +              if (use_preview_icon) {
 +                      int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type);
 +                      ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
 +              }
 +              else {
 +                      ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
 +                      UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
 +              }
 +
 +              if ((idfrom && idfrom->lib) || !editable)
 +                      UI_but_flag_enable(but, UI_BUT_DISABLED);
 +              if (use_big_size) {
 +                      uiLayoutRow(layout, true);
 +              }
 +      }
 +      else {
 +              but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip);
 +              ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
 +              if (id) {
 +                      /* default dragging of icon for id browse buttons */
 +                      UI_but_drag_set_id(but, id);
 +              }
 +              UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
 +
 +              if ((idfrom && idfrom->lib) || !editable)
 +                      UI_but_flag_enable(but, UI_BUT_DISABLED);
 +      }
 +}
 +
 +static uiBlock *template_common_search_menu(
 +        const bContext *C, ARegion *region,
 +        uiButSearchFunc search_func, void *search_arg,
 +        uiButHandleFunc handle_func, void *active_item,
 +        const int preview_rows, const int preview_cols)
 +{
 +      static char search[256];
 +      wmWindow *win = CTX_wm_window(C);
 +      uiBlock *block;
 +      uiBut *but;
 +
 +      /* clear initial search string, then all items show */
 +      search[0] = 0;
 +
 +      block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
 +      UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
 +
 +      /* preview thumbnails */
 +      if (preview_rows > 0 && preview_cols > 0) {
 +              const int w = 4 * U.widget_unit * preview_cols;
 +              const int h = 5 * U.widget_unit * preview_rows;
 +
 +              /* fake button, it holds space for search items */
 +              uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
 +
 +              but = uiDefSearchBut(
 +                      block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
 +                      preview_rows, preview_cols, "");
 +      }
 +      /* list view */
 +      else {
 +              const int searchbox_width  = UI_searchbox_size_x();
 +              const int searchbox_height = UI_searchbox_size_y();
 +
 +              /* fake button, it holds space for search items */
 +              uiDefBut(
 +                      block, UI_BTYPE_LABEL, 0, "", 10, 15, searchbox_width, searchbox_height,
 +                      NULL, 0, 0, 0, 0, NULL);
 +              but = uiDefSearchBut(
 +                      block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0,
 +                      searchbox_width, UI_UNIT_Y - 1, 0, 0, "");
 +      }
 +      UI_but_func_search_set(
 +              but, ui_searchbox_create_generic, search_func,
 +              search_arg, handle_func, active_item);
 +
 +
 +      UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
 +      UI_block_direction_set(block, UI_DIR_DOWN);
 +
 +      /* give search-field focus */
 +      UI_but_focus_on_enter_event(win, but);
 +      /* this type of search menu requires undo */
 +      but->flag |= UI_BUT_UNDO;
 +
 +      return block;
 +}
 +
  /********************** Header Template *************************/
  
  void uiTemplateHeader(uiLayout *layout, bContext *C)
@@@ -295,16 -177,61 +295,16 @@@ static void id_search_cb(const bContex
  /* ID Search browse menu, open */
  static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
  {
 -      static char search[256];
        static TemplateID template;
 -      PointerRNA idptr;
 -      wmWindow *win = CTX_wm_window(C);
 -      uiBlock *block;
 -      uiBut *but;
 -      
 -      /* clear initial search string, then all items show */
 -      search[0] = 0;
 +      PointerRNA active_item_ptr;
 +
        /* arg_litem is malloced, can be freed by parent button */
        template = *((TemplateID *)arg_litem);
 -      
 -      /* get active id for showing first item */
 -      idptr = RNA_property_pointer_get(&template.ptr, template.prop);
 +      active_item_ptr = RNA_property_pointer_get(&template.ptr, template.prop);
  
 -      block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
 -      UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
 -      
 -      /* preview thumbnails */
 -      if (template.prv_rows > 0 && template.prv_cols > 0) {
 -              int w = 4 * U.widget_unit * template.prv_cols;
 -              int h = 5 * U.widget_unit * template.prv_rows;
 -              
 -              /* fake button, it holds space for search items */
 -              uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
 -              
 -              but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
 -                                   template.prv_rows, template.prv_cols, "");
 -              UI_but_func_search_set(
 -                      but, ui_searchbox_create_generic, id_search_cb,
 -                      &template, id_search_call_cb, idptr.data);
 -      }
 -      /* list view */
 -      else {
 -              const int searchbox_width  = UI_searchbox_size_x();
 -              const int searchbox_height = UI_searchbox_size_y();
 -              
 -              /* fake button, it holds space for search items */
 -              uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL);
 -              but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, searchbox_width, UI_UNIT_Y - 1, 0, 0, "");
 -              UI_but_func_search_set(
 -                      but, ui_searchbox_create_generic, id_search_cb,
 -                      &template, id_search_call_cb, idptr.data);
 -      }
 -              
 -      
 -      UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
 -      UI_block_direction_set(block, UI_DIR_DOWN);
 -      
 -      /* give search-field focus */
 -      UI_but_focus_on_enter_event(win, but);
 -      /* this type of search menu requires undo */
 -      but->flag |= UI_BUT_UNDO;
 -      
 -      return block;
 +      return template_common_search_menu(
 +                     C, ar, id_search_cb, &template, id_search_call_cb, active_item_ptr.data,
 +                     template.prv_rows, template.prv_cols);
  }
  
  /************************ ID Template ***************************/
@@@ -403,13 -330,13 +403,13 @@@ static void template_id_cb(bContext *C
                                        Scene *scene = CTX_data_scene(C);
                                        ED_object_single_user(bmain, scene, (struct Object *)id);
                                        WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
 -                                      DAG_relations_tag_update(bmain);
 +                                      DEG_relations_tag_update(bmain);
                                }
                                else {
                                        if (id) {
                                                Main *bmain = CTX_data_main(C);
                                                id_single_user(C, id, &template->ptr, template->prop);
 -                                              DAG_relations_tag_update(bmain);
 +                                              DEG_relations_tag_update(bmain);
                                        }
                                }
                        }
        }
  }
  
 -static const char *template_id_browse_tip(StructRNA *type)
 +static const char *template_id_browse_tip(const StructRNA *type)
  {
        if (type) {
                switch (RNA_type_to_ID_code(type)) {
                        case ID_PAL: return N_("Browse Palette Data to be linked");
                        case ID_PC:  return N_("Browse Paint Curve Data to be linked");
                        case ID_CF:  return N_("Browse Cache Files to be linked");
 +                      case ID_WS:  return N_("Browse Workspace to be linked");
 +                      case ID_LP:  return N_("Browse LightProbe to be linked");
                }
        }
        return N_("Browse ID data to be linked");
@@@ -475,7 -400,7 +475,7 @@@ static const char *template_id_context(
  #endif
  
  static void template_ID(
-         bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag,
+         bContext *C, uiLayout *layout, TemplateID *template_ui, StructRNA *type, short idcode, int flag,
          const char *newop, const char *openop, const char *unlinkop)
  {
        uiBut *but;
        PointerRNA idptr;
        // ListBase *lb; // UNUSED
        ID *id, *idfrom;
-       const bool editable = RNA_property_editable(&template->ptr, template->prop);
-       const bool use_previews = template->preview = (flag & UI_ID_PREVIEWS) != 0;
+       const bool editable = RNA_property_editable(&template_ui->ptr, template_ui->prop);
++      const bool use_previews = template_ui->preview = (flag & UI_ID_PREVIEWS) != 0;
  
-       idptr = RNA_property_pointer_get(&template->ptr, template->prop);
+       idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
        id = idptr.data;
-       idfrom = template->ptr.id.data;
+       idfrom = template_ui->ptr.id.data;
        // lb = template->idlb;
  
        block = uiLayoutGetBlock(layout);
        if (idptr.type)
                type = idptr.type;
  
 -      if (flag & UI_ID_PREVIEWS) {
 -              template_ui->preview = true;
 -
 -              but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template_ui), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6,
 -                                   TIP_(template_id_browse_tip(type)));
 -              ui_def_but_icon(but, id ? ui_id_icon_get(C, id, true) : RNA_struct_ui_icon(type),
 -                              UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
 -
 -              if ((idfrom && idfrom->lib) || !editable)
 -                      UI_but_flag_enable(but, UI_BUT_DISABLED);
 -              
 -              uiLayoutRow(layout, true);
 -      }
 -      else if (flag & UI_ID_BROWSE) {
 -              but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template_ui), "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y,
 -                                   TIP_(template_id_browse_tip(type)));
 -              ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
 -              /* default dragging of icon for id browse buttons */
 -              UI_but_drag_set_id(but, id);
 -              UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
 -
 -              if ((idfrom && idfrom->lib) || !editable)
 -                      UI_but_flag_enable(but, UI_BUT_DISABLED);
 +      if (flag & UI_ID_BROWSE) {
 +              template_add_button_search_menu(
-                       C, layout, block, &template->ptr, template->prop,
-                       id_search_menu, MEM_dupallocN(template), TIP_(template_id_browse_tip(type)),
++                      C, layout, block, &template_ui->ptr, template_ui->prop,
++                      id_search_menu, MEM_dupallocN(template_ui), TIP_(template_id_browse_tip(type)),
 +                      use_previews, editable);
        }
  
        /* text button with name */
  
                //text_idbutton(id, name);
                name[0] = '\0';
 -              but = uiDefButR(block, UI_BTYPE_TEXT, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y,
 -                              &idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
 +              but = uiDefButR(
 +                      block, UI_BTYPE_TEXT, 0, name, 0, 0, TEMPLATE_SEARCH_TEXTBUT_WIDTH, TEMPLATE_SEARCH_TEXTBUT_HEIGHT,
 +                      &idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
-               UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
+               UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_RENAME));
                if (user_alert) UI_but_flag_enable(but, UI_BUT_REDALERT);
  
                if (id->lib) {
                                        UI_but_flag_enable(but, UI_BUT_DISABLED);
                        }
  
-                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL));
+                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_LOCAL));
                }
  
                if (id->us > 1) {
                                       TIP_("Display number of users of this data (click to make a single-user copy)"));
                        but->flag |= UI_BUT_UNDO;
  
-                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
+                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_ALONE));
                        if (/* test only */
                            (id_copy(CTX_data_main(C), id, NULL, true) == false) ||
                            (idfrom && idfrom->lib) ||
        
                if (user_alert) UI_but_flag_enable(but, UI_BUT_REDALERT);
                
 -              if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB))) {
 +              if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) {
                        uiDefButR(block, UI_BTYPE_TOGGLE, 0, "F", 0, 0, UI_UNIT_X, UI_UNIT_Y, &idptr, "use_fake_user", -1, 0, 0, -1, -1, NULL);
                }
        }
                                                 BLT_I18NCONTEXT_ID_PARTICLESETTINGS,
                                                 BLT_I18NCONTEXT_ID_GPENCIL,
                                                 BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE,
 +                                               BLT_I18NCONTEXT_ID_WORKSPACE,
 +                                               BLT_I18NCONTEXT_ID_LIGHTPROBE,
                );
                
                if (newop) {
                        but = uiDefIconTextButO(block, UI_BTYPE_BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN,
                                                (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, UI_UNIT_Y, NULL);
-                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
+                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
                }
                else {
                        but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
                                               0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
-                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
+                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
                }
  
                if ((idfrom && idfrom->lib) || !editable)
                if (openop) {
                        but = uiDefIconTextButO(block, UI_BTYPE_BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"),
                                                0, 0, w, UI_UNIT_Y, NULL);
-                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
+                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_OPEN));
                }
                else {
                        but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y,
                                               NULL, 0, 0, 0, 0, NULL);
-                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
+                       UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_OPEN));
                }
  
                if ((idfrom && idfrom->lib) || !editable)
                if (unlinkop) {
                        but = uiDefIconButO(block, UI_BTYPE_BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
                        /* so we can access the template from operators, font unlinking needs this */
-                       UI_but_funcN_set(but, NULL, MEM_dupallocN(template), NULL);
+                       UI_but_funcN_set(but, NULL, MEM_dupallocN(template_ui), NULL);
                }
                else {
-                       if ((RNA_property_flag(template->prop) & PROP_NEVER_UNLINK) == 0) {
+                       if ((RNA_property_flag(template_ui->prop) & PROP_NEVER_UNLINK) == 0) {
                                but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
                                                   TIP_("Unlink data-block "
                                                        "(Shift + Click to set users to zero, data will then not be saved)"));
-                               UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
+                               UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_DELETE));
  
-                               if (RNA_property_flag(template->prop) & PROP_NEVER_NULL) {
+                               if (RNA_property_flag(template_ui->prop) & PROP_NEVER_NULL) {
                                        UI_but_flag_enable(but, UI_BUT_DISABLED);
                                }
                        }
        }
  
        if (idcode == ID_TE)
-               uiTemplateTextureShow(layout, C, &template->ptr, template->prop);
+               uiTemplateTextureShow(layout, C, &template_ui->ptr, template_ui->prop);
        
        UI_block_align_end(block);
  }
@@@ -681,7 -620,7 +681,7 @@@ static void ui_template_id
          uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
          const char *openop, const char *unlinkop, int flag, int prv_rows, int prv_cols)
  {
-       TemplateID *template;
+       TemplateID *template_ui;
        PropertyRNA *prop;
        StructRNA *type;
        short idcode;
                return;
        }
  
-       template = MEM_callocN(sizeof(TemplateID), "TemplateID");
-       template->ptr = *ptr;
-       template->prop = prop;
-       template->prv_rows = prv_rows;
-       template->prv_cols = prv_cols;
+       template_ui = MEM_callocN(sizeof(TemplateID), "TemplateID");
+       template_ui->ptr = *ptr;
+       template_ui->prop = prop;
+       template_ui->prv_rows = prv_rows;
+       template_ui->prv_cols = prv_cols;
  
        if (newop)
                flag |= UI_ID_ADD_NEW;
  
        type = RNA_property_pointer_type(ptr, prop);
        idcode = RNA_type_to_ID_code(type);
-       template->idlb = which_libbase(CTX_data_main(C), idcode);
+       template_ui->idlb = which_libbase(CTX_data_main(C), idcode);
        
        /* create UI elements for this template
         *      - template_ID makes a copy of the template data and assigns it to the relevant buttons
         */
-       if (template->idlb) {
+       if (template_ui->idlb) {
                uiLayoutRow(layout, true);
-               template_ID(C, layout, template, type, idcode, flag, newop, openop, unlinkop);
+               template_ID(C, layout, template_ui, type, idcode, flag, newop, openop, unlinkop);
        }
  
-       MEM_freeN(template);
+       MEM_freeN(template_ui);
  }
  
  void uiTemplateID(
@@@ -801,208 -740,6 +801,208 @@@ void uiTemplateAnyID
        uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
  }
  
 +/********************* Search Template ********************/
 +
 +typedef struct TemplateSearch {
 +      uiRNACollectionSearch search_data;
 +
 +      bool use_previews;
 +      int preview_rows, preview_cols;
 +} TemplateSearch;
 +
 +static void template_search_handle_cb(bContext *C, void *arg_template, void *item)
 +{
 +      TemplateSearch *template_search = arg_template;
 +      uiRNACollectionSearch *coll_search = &template_search->search_data;
 +      StructRNA *type = RNA_property_pointer_type(&coll_search->target_ptr, coll_search->target_prop);
 +      PointerRNA item_ptr;
 +
 +      RNA_pointer_create(NULL, type, item, &item_ptr);
 +      RNA_property_pointer_set(&coll_search->target_ptr, coll_search->target_prop, item_ptr);
 +      RNA_property_update(C, &coll_search->target_ptr, coll_search->target_prop);
 +}
 +
 +static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_template)
 +{
 +      static TemplateSearch template_search;
 +      PointerRNA active_ptr;
 +
 +      /* arg_template is malloced, can be freed by parent button */
 +      template_search = *((TemplateSearch *)arg_template);
 +      active_ptr = RNA_property_pointer_get(&template_search.search_data.target_ptr,
 +                                            template_search.search_data.target_prop);
 +
 +      return template_common_search_menu(
 +                     C, region, ui_rna_collection_search_cb, &template_search,
 +                     template_search_handle_cb, active_ptr.data,
 +                     template_search.preview_rows, template_search.preview_cols);
 +}
 +
 +static void template_search_add_button_searchmenu(
 +        const bContext *C, uiLayout *layout, uiBlock *block,
 +        TemplateSearch *template_search, const bool editable)
 +{
 +      const char *ui_description = RNA_property_ui_description(template_search->search_data.target_prop);
 +
 +      template_add_button_search_menu(
 +              C, layout, block,
 +              &template_search->search_data.target_ptr, template_search->search_data.target_prop,
 +              template_search_menu, MEM_dupallocN(template_search), ui_description,
 +              template_search->use_previews, editable);
 +}
 +
 +static void template_search_add_button_name(
 +        uiBlock *block, PointerRNA *active_ptr, const StructRNA *type)
 +{
 +      uiDefAutoButR(
 +              block, active_ptr, RNA_struct_name_property(type), 0, "", ICON_NONE,
 +              0, 0, TEMPLATE_SEARCH_TEXTBUT_WIDTH, TEMPLATE_SEARCH_TEXTBUT_HEIGHT);
 +}
 +
 +static void template_search_add_button_operator(
 +        uiBlock *block, const char * const operator_name,
 +        const int opcontext, const int icon, const bool editable)
 +{
 +      if (!operator_name) {
 +              return;
 +      }
 +
 +      uiBut *but = uiDefIconButO(
 +              block, UI_BTYPE_BUT, operator_name, opcontext, icon,
 +              0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
 +
 +      if (!editable) {
 +              UI_but_drawflag_enable(but, UI_BUT_DISABLED);
 +      }
 +}
 +
 +static void template_search_buttons(
 +        const bContext *C, uiLayout *layout, TemplateSearch *template_search,
 +        const char *newop, const char *unlinkop)
 +{
 +      uiBlock *block = uiLayoutGetBlock(layout);
 +      uiRNACollectionSearch *search_data = &template_search->search_data;
 +      StructRNA *type = RNA_property_pointer_type(&search_data->target_ptr, search_data->target_prop);
 +      const bool editable = RNA_property_editable(&search_data->target_ptr, search_data->target_prop);
 +      PointerRNA active_ptr = RNA_property_pointer_get(&search_data->target_ptr, search_data->target_prop);
 +
 +      if (active_ptr.type) {
 +              /* can only get correct type when there is an active item */
 +              type = active_ptr.type;
 +      }
 +
 +      uiLayoutRow(layout, true);
 +      UI_block_align_begin(block);
 +
 +      template_search_add_button_searchmenu(C, layout, block, template_search, editable);
 +      template_search_add_button_name(block, &active_ptr, type);
 +      template_search_add_button_operator(block, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, editable);
 +      template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable);
 +
 +      UI_block_align_end(block);
 +}
 +
 +static PropertyRNA *template_search_get_searchprop(
 +        PointerRNA *targetptr, PropertyRNA *targetprop,
 +        PointerRNA *searchptr, const char * const searchpropname)
 +{
 +      PropertyRNA *searchprop;
 +
 +      if (searchptr && !searchptr->data) {
 +              searchptr = NULL;
 +      }
 +
 +      if (!searchptr && !searchpropname) {
 +              /* both NULL means we don't use a custom rna collection to search in */
 +      }
 +      else if (!searchptr && searchpropname) {
 +              RNA_warning("searchpropname defined (%s) but searchptr is missing", searchpropname);
 +      }
 +      else if (searchptr && !searchpropname) {
 +              RNA_warning("searchptr defined (%s) but searchpropname is missing", RNA_struct_identifier(searchptr->type));
 +      }
 +      else if (!(searchprop = RNA_struct_find_property(searchptr, searchpropname))) {
 +              RNA_warning("search collection property not found: %s.%s",
 +                          RNA_struct_identifier(searchptr->type), searchpropname);
 +      }
 +      else if (RNA_property_type(searchprop) != PROP_COLLECTION) {
 +              RNA_warning("search collection property is not a collection type: %s.%s",
 +                          RNA_struct_identifier(searchptr->type), searchpropname);
 +      }
 +      /* check if searchprop has same type as targetprop */
 +      else if (RNA_property_pointer_type(searchptr, searchprop) != RNA_property_pointer_type(targetptr, targetprop)) {
 +              RNA_warning("search collection items from %s.%s are not of type %s",
 +                          RNA_struct_identifier(searchptr->type), searchpropname,
 +                          RNA_struct_identifier(RNA_property_pointer_type(targetptr, targetprop)));
 +      }
 +      else {
 +              return searchprop;
 +      }
 +
 +      return NULL;
 +}
 +
 +static TemplateSearch *template_search_setup(
 +        PointerRNA *ptr, const char * const propname,
 +        PointerRNA *searchptr, const char * const searchpropname)
 +{
 +      TemplateSearch *template_search;
 +      PropertyRNA *prop, *searchprop;
 +
 +      prop = RNA_struct_find_property(ptr, propname);
 +
 +      if (!prop || RNA_property_type(prop) != PROP_POINTER) {
 +              RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
 +              return NULL;
 +      }
 +      searchprop = template_search_get_searchprop(ptr, prop, searchptr, searchpropname);
 +
 +      template_search = MEM_callocN(sizeof(*template_search), __func__);
 +      template_search->search_data.target_ptr = *ptr;
 +      template_search->search_data.target_prop = prop;
 +      template_search->search_data.search_ptr = *searchptr;
 +      template_search->search_data.search_prop = searchprop;
 +
 +      return template_search;
 +}
 +
 +/**
 + * Search menu to pick an item from a collection.
 + * A version of uiTemplateID that works for non-ID types.
 + */
 +void uiTemplateSearch(
 +        uiLayout *layout, bContext *C,
 +        PointerRNA *ptr, const char *propname,
 +        PointerRNA *searchptr, const char *searchpropname,
 +        const char *newop, const char *unlinkop)
 +{
 +      TemplateSearch *template_search = template_search_setup(ptr, propname, searchptr, searchpropname);
 +      if (template_search != NULL) {
 +              template_search_buttons(C, layout, template_search, newop, unlinkop);
 +              MEM_freeN(template_search);
 +      }
 +}
 +
 +void uiTemplateSearchPreview(
 +        uiLayout *layout, bContext *C,
 +        PointerRNA *ptr, const char *propname,
 +        PointerRNA *searchptr, const char *searchpropname,
 +        const char *newop, const char *unlinkop,
 +        const int rows, const int cols)
 +{
 +      TemplateSearch *template_search = template_search_setup(ptr, propname, searchptr, searchpropname);
 +
 +      if (template_search != NULL) {
 +              template_search->use_previews = true;
 +              template_search->preview_rows = rows;
 +              template_search->preview_cols = cols;
 +
 +              template_search_buttons(C, layout, template_search, newop, unlinkop);
 +
 +              MEM_freeN(template_search);
 +      }
 +}
 +
  /********************* RNA Path Builder Template ********************/
  
  /* ---------- */
@@@ -1056,7 -793,7 +1056,7 @@@ static void modifiers_convertToReal(bCo
        ob->partype = PAROBJECT;
  
        WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
 -      DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +      DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
  
        ED_undo_push(C, "Modifier convert to real");
  }
@@@ -1200,7 -937,7 +1200,7 @@@ static uiLayout *draw_modifier
                /* When Modifier is a simulation, show button to switch to context rather than the delete button. */
                if (modifier_can_delete(md) &&
                    (!modifier_is_simulation(md) ||
 -                   STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME)))
 +                   STREQ(scene->view_render.engine_id, RE_engine_id_BLENDER_GAME)))
                {
                        uiItemO(row, "", ICON_X, "OBJECT_OT_modifier_remove");
                }
@@@ -1337,7 -1074,7 +1337,7 @@@ static void do_constraint_panels(bConte
                        Main *bmain = CTX_data_main(C);
                        if (ob->pose)
                                BKE_pose_tag_recalc(bmain, ob->pose); /* checks & sorts pose channels */
 -                      DAG_relations_tag_update(bmain);
 +                      DEG_relations_tag_update(bmain);
                        break;
                }
  #endif
         * object_test_constraints(ob);
         * if (ob->pose) BKE_pose_update_constraint_flags(ob->pose); */
        
 -      if (ob->type == OB_ARMATURE) DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB);
 -      else DAG_id_tag_update(&ob->id, OB_RECALC_OB);
 +      if (ob->type == OB_ARMATURE) DEG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB);
 +      else DEG_id_tag_update(&ob->id, OB_RECALC_OB);
  
        WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
  }
@@@ -4112,7 -3849,6 +4112,7 @@@ void uiTemplateKeymapItemProperties(uiL
        if (propptr.data) {
                uiBut *but = uiLayoutGetBlock(layout)->buttons.last;
  
 +              WM_operator_properties_sanitize(&propptr, false);
                template_keymap_item_properties(layout, NULL, &propptr);
  
                /* attach callbacks to compensate for missing properties update,
        }
  }
  
 +/********************************* Overrides *************************************/
 +
 +void uiTemplateOverrideProperty(
 +        uiLayout *layout, PointerRNA *collection_props_ptr, PointerRNA *scene_props_ptr, const char *propname,
 +        const char *name, const char *text_ctxt, int translate, int icon,
 +        const char *custom_template)
 +{
 +      bool is_set = false;
 +      uiLayout *row, *col;
 +
 +      PointerRNA *ptr;
 +      PropertyRNA *prop;
 +
 +      IDProperty *collection_props = collection_props_ptr->data;
 +
 +      if (IDP_GetPropertyFromGroup(collection_props, propname)) {
 +              prop = RNA_struct_find_property(collection_props_ptr, propname);
 +              ptr = collection_props_ptr;
 +              is_set = RNA_property_is_set(ptr, prop);
 +      }
 +      else {
 +              /* property doesn't exist yet */
 +              prop = RNA_struct_find_property(scene_props_ptr, propname);
 +              ptr = scene_props_ptr;
 +      }
 +
 +      /* Get translated name (label). */
 +      name = RNA_translate_ui_text(name, text_ctxt, NULL, prop, translate);
 +
 +      row = uiLayoutRow(layout, false);
 +      col = uiLayoutColumn(row, false);
 +
 +      uiLayoutSetEnabled(col, is_set);
 +
 +      if (custom_template && STREQ(custom_template, "icon_view")) {
 +              uiTemplateIconView(col, ptr, propname, false, 5.0f);
 +      }
 +      else {
 +              uiItemFullR(col, ptr, prop, -1, 0, 0, name, icon);
 +      }
 +
 +      col = uiLayoutColumn(row, false);
 +      uiBut *but;
 +      uiBlock *block = uiLayoutGetBlock(col);
 +      UI_block_emboss_set(block, UI_EMBOSS_NONE);
 +
 +      if (is_set) {
 +              but = uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_unuse_property_button", WM_OP_EXEC_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
 +      }
 +      else {
 +              but = uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_use_property_button", WM_OP_EXEC_DEFAULT, ICON_ZOOMIN, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
 +              /* XXX - Using existing data struct to pass another RNAPointer */
 +              but->rnasearchpoin = *scene_props_ptr;
 +      }
 +
 +      but->rnapoin = *collection_props_ptr;
 +      but->rnaprop = prop;
 +      UI_block_emboss_set(block, UI_EMBOSS);
 +}
 +
  /********************************* Color management *************************************/
  
  void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char *propname)