UI: add Visibility panel for objects
authorDalai Felinto <dfelinto@gmail.com>
Mon, 20 May 2019 10:14:48 +0000 (12:14 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Mon, 20 May 2019 11:47:37 +0000 (13:47 +0200)
The outliner should not be the only way for users to change these settings.
The Python API was extended to keep these properties positive and keyframable.

Differential Revision: https://developer.blender.org/D4889

release/scripts/startup/bl_ui/properties_object.py
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/space_outliner/outliner_draw.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_ui_api.c

index 6a938b40c2e0fe62ccc1e58c40d08e414f348e9d..aeda8d8648ac43594391917dddd8ef468da1f478 100644 (file)
@@ -378,6 +378,31 @@ class OBJECT_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel):
         self.draw_settings(context, avs, mpath)
 
 
+class OBJECT_PT_visibility(ObjectButtonsPanel, Panel):
+    bl_label = "Visibility"
+    bl_options = {'DEFAULT_CLOSED'}
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
+
+    @classmethod
+    def poll(cls, context):
+        return (context.object) and (context.engine in cls.COMPAT_ENGINES)
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
+        layout = self.layout
+        ob = context.object
+
+        col = flow.column()
+        col.prop(ob, "hide_viewport", text="Show in Viewports", invert_checkbox=True)
+        col = flow.column()
+        col.prop(ob, "hide_render", text="Show in Renders", invert_checkbox=True)
+        col = flow.column()
+        col.prop(ob, "hide_select", text="Selectable", invert_checkbox=True)
+
+
 class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel):
     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
     _context_path = "object"
@@ -397,6 +422,7 @@ classes = (
     OBJECT_PT_motion_paths_display,
     OBJECT_PT_display,
     OBJECT_PT_display_bounds,
+    OBJECT_PT_visibility,
     OBJECT_PT_custom_props,
 )
 
index 14d681ee8178ab7aeb79c4993b42025d40a31886..5912a3a59e44b92d86aad9f6df05d4b52982209c 100644 (file)
@@ -281,6 +281,9 @@ enum {
 
   /** Value is animated, but the current value differs from the animated one. */
   UI_BUT_ANIMATED_CHANGED = 1 << 25,
+
+  /* Draw the checkbox buttons inverted. */
+  UI_BUT_CHECKBOX_INVERT = 1 << 26,
 };
 
 /* scale fixed button widths by this to account for DPI */
@@ -1719,6 +1722,7 @@ enum {
   UI_ITEM_R_IMMEDIATE = 1 << 8,
   UI_ITEM_O_DEPRESS = 1 << 9,
   UI_ITEM_R_COMPACT = 1 << 10,
+  UI_ITEM_R_CHECKBOX_INVERT = 1 << 11,
 };
 
 #define UI_HEADER_OFFSET ((void)0, 0.4f * UI_UNIT_X)
index f1724d9240265006fc9b211a1d672cecf2fffe32..e436328c1398d384471903555c8edf22bfc72b92 100644 (file)
@@ -1845,6 +1845,9 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
     }
   }
 
+  if ((but->drawflag & UI_BUT_CHECKBOX_INVERT) && (is_push != -1)) {
+    is_push = !((bool)is_push);
+  }
   return is_push;
 }
 int ui_but_is_pushed(uiBut *but)
index dc57be4f07fd648edbe739b3b9043081e3a3290d..df4b18477fc25c32a8e7386d582168136de1b629 100644 (file)
@@ -1904,6 +1904,10 @@ void uiItemFullR(uiLayout *layout,
     }
   }
 
+  if (type != PROP_BOOLEAN) {
+    flag &= ~UI_ITEM_R_CHECKBOX_INVERT;
+  }
+
   if (icon == ICON_NONE) {
     icon = RNA_property_ui_icon(prop);
   }
@@ -2156,6 +2160,12 @@ void uiItemFullR(uiLayout *layout,
       but->type = UI_BTYPE_NUM_SLIDER;
     }
 
+    if (flag & UI_ITEM_R_CHECKBOX_INVERT) {
+      if (ELEM(but->type, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N)) {
+        but->drawflag |= UI_BUT_CHECKBOX_INVERT;
+      }
+    }
+
     if (toggle && but->type == UI_BTYPE_CHECKBOX) {
       but->type = UI_BTYPE_TOGGLE;
     }
index 6a7795393c91a0be85158b20acc5ebdf867f181a..f34f280a29d607541beb55b9dc8100c206b0b5a0 100644 (file)
@@ -1088,10 +1088,13 @@ static void outliner_draw_restrictbuts(uiBlock *block,
         }
 
         if (soops->show_restrict_flags & SO_RESTRICT_SELECT) {
+          const int icon = RNA_property_boolean_get(&ptr, props.object_hide_select) ?
+                               ICON_RESTRICT_SELECT_ON :
+                               ICON_RESTRICT_SELECT_OFF;
           bt = uiDefIconButR_prop(block,
                                   UI_BTYPE_ICON_TOGGLE,
                                   0,
-                                  0,
+                                  icon,
                                   (int)(ar->v2d.cur.xmax - restrict_offsets.select),
                                   te->ys,
                                   UI_UNIT_X,
@@ -1113,10 +1116,13 @@ static void outliner_draw_restrictbuts(uiBlock *block,
         }
 
         if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+          const int icon = RNA_property_boolean_get(&ptr, props.object_hide_viewport) ?
+                               ICON_RESTRICT_VIEW_ON :
+                               ICON_RESTRICT_VIEW_OFF;
           bt = uiDefIconButR_prop(block,
                                   UI_BTYPE_ICON_TOGGLE,
                                   0,
-                                  0,
+                                  icon,
                                   (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
                                   te->ys,
                                   UI_UNIT_X,
@@ -1138,10 +1144,13 @@ static void outliner_draw_restrictbuts(uiBlock *block,
         }
 
         if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+          const int icon = RNA_property_boolean_get(&ptr, props.object_hide_render) ?
+                               ICON_RESTRICT_RENDER_ON :
+                               ICON_RESTRICT_RENDER_OFF;
           bt = uiDefIconButR_prop(block,
                                   UI_BTYPE_ICON_TOGGLE,
                                   0,
-                                  0,
+                                  icon,
                                   (int)(ar->v2d.cur.xmax - restrict_offsets.render),
                                   te->ys,
                                   UI_UNIT_X,
index b445399609505a575c117456e0deb12c8b875fbd..dbc822460d994c42208ce20ab79213a1e47e4ba7 100644 (file)
@@ -2819,7 +2819,6 @@ static void rna_def_object(BlenderRNA *brna)
   RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_VIEWPORT);
   RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
   RNA_def_property_ui_text(prop, "Disable in Viewports", "Globally disable in viewports");
-  RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
   RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update");
 
   prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE);
@@ -2827,14 +2826,12 @@ static void rna_def_object(BlenderRNA *brna)
   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
   RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
   RNA_def_property_ui_text(prop, "Disable Selection", "Disable selection in viewport");
-  RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, -1);
   RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update");
 
   prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE);
   RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_RENDER);
   RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
   RNA_def_property_ui_text(prop, "Disable in Renders", "Globally disable in renders");
-  RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, -1);
   RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update");
 
   prop = RNA_def_property(srna, "show_instancer_for_render", PROP_BOOLEAN, PROP_NONE);
index 7ce9155e3d903efaaa475d26e05af8adb2eff4f2..5a001f05b5376f1e110fe3956bc839b3995f06c6 100644 (file)
@@ -101,7 +101,8 @@ static void rna_uiItemR(uiLayout *layout,
                         bool full_event,
                         bool emboss,
                         int index,
-                        int icon_value)
+                        int icon_value,
+                        bool invert_checkbox)
 {
   PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
   int flag = 0;
@@ -125,6 +126,7 @@ static void rna_uiItemR(uiLayout *layout,
   flag |= (event) ? UI_ITEM_R_EVENT : 0;
   flag |= (full_event) ? UI_ITEM_R_FULL_EVENT : 0;
   flag |= (emboss) ? 0 : UI_ITEM_R_NO_BG;
+  flag |= (invert_checkbox) ? UI_ITEM_R_CHECKBOX_INVERT : 0;
 
   uiItemFullR(layout, ptr, prop, index, 0, flag, name, icon);
 }
@@ -789,6 +791,7 @@ void RNA_api_ui_layout(StructRNA *srna)
               INT_MAX); /* RNA_NO_INDEX == -1 */
   parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
   RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item");
+  RNA_def_boolean(func, "invert_checkbox", false, "", "Draw checkbox value inverted");
 
   func = RNA_def_function(srna, "props_enum", "uiItemsEnumR");
   api_ui_item_rna_common(func);