[Bf-blender-cvs] [1fa40c9f8a8] master: UI: Add shortcuts for modifier panels

Hans Goudey noreply at git.blender.org
Mon Jun 29 21:00:36 CEST 2020


Commit: 1fa40c9f8a81036476d5051b09ff15e27b628012
Author: Hans Goudey
Date:   Mon Jun 29 15:00:25 2020 -0400
Branches: master
https://developer.blender.org/rB1fa40c9f8a81036476d5051b09ff15e27b628012

UI: Add shortcuts for modifier panels

The shortcuts act on the modifier with its panel under the mouse.
The following shortcuts are enabled by default:
  - Remove modifier: X, Delete
  - Apply modifier: Ctrl A
  - Duplicate modifier: Shift D
More shortcuts can be added in the keymap.

Each panel can now store a custom data RNA pointer, and a new
function is added to get the custom data for the panel under the
cursor. This custom data could be used to refactor the "List Panel
System" to generalize it and integrate it further with RNA.

The same functionality will be added  in further commits where it
applies to constraints, grease pencil modifiers, and effects.

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

===================================================================

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	source/blender/blenkernel/intern/screen.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/editors/interface/interface_panel.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/editors/object/object_data_transfer.c
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_modifier.c
M	source/blender/makesdna/DNA_screen_types.h
M	source/blender/modifiers/intern/MOD_ui_common.c

===================================================================

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index dbfc9daca84..b924625b4de 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -728,6 +728,11 @@ def km_property_editor(_params):
          {"properties": [("direction", 'PREV'), ], },),
         ("screen.space_context_cycle", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "ctrl": True},
          {"properties": [("direction", 'NEXT'), ], },),
+        # Modifier panels
+        ("object.modifier_remove", {"type": 'X', "value": 'PRESS'}, {"properties": [("report", True)]}),
+        ("object.modifier_remove", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("report", True)]}),
+        ("object.modifier_copy", {"type": 'D', "value": 'PRESS', "shift": True}, None),
+        ("object.modifier_apply", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("report", True)]}),
     ])
 
     return keymap
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index bfc0d437994..c510b3a2dfb 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -393,6 +393,7 @@ static void panel_list_copy(ListBase *newlb, const ListBase *lb)
   Panel *panel = lb->first;
   for (; new_panel; new_panel = new_panel->next, panel = panel->next) {
     new_panel->activedata = NULL;
+    new_panel->runtime.custom_data_ptr = NULL;
     panel_list_copy(&new_panel->children, &panel->children);
   }
 }
@@ -575,18 +576,25 @@ void BKE_region_callback_free_gizmomap_set(void (*callback)(struct wmGizmoMap *)
   region_free_gizmomap_callback = callback;
 }
 
-void BKE_area_region_panels_free(ListBase *lb)
+static void area_region_panels_free_recursive(Panel *panel)
 {
-  Panel *panel, *panel_next;
-  for (panel = lb->first; panel; panel = panel_next) {
-    panel_next = panel->next;
-    if (panel->activedata) {
-      MEM_freeN(panel->activedata);
-    }
-    BKE_area_region_panels_free(&panel->children);
+  MEM_SAFE_FREE(panel->activedata);
+
+  LISTBASE_FOREACH_MUTABLE (Panel *, child_panel, &panel->children) {
+    area_region_panels_free_recursive(child_panel);
   }
 
-  BLI_freelistN(lb);
+  MEM_freeN(panel);
+}
+
+void BKE_area_region_panels_free(ListBase *lb)
+{
+  LISTBASE_FOREACH_MUTABLE (Panel *, panel, lb) {
+    /* Free custom data just for parent panels to avoid a double free. */
+    MEM_SAFE_FREE(panel->runtime.custom_data_ptr);
+    area_region_panels_free_recursive(panel);
+  }
+  BLI_listbase_clear(lb);
 }
 
 /* not region itself */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index e9389561b47..e4822c4cb7f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -7015,6 +7015,7 @@ static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb)
     panel->runtime_flag = 0;
     panel->activedata = NULL;
     panel->type = NULL;
+    panel->runtime.custom_data_ptr = NULL;
     direct_link_panel_list(reader, &panel->children);
   }
 }
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index bcbee51246e..1cedd4e122f 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1706,12 +1706,17 @@ void UI_panel_category_draw_all(struct ARegion *region, const char *category_id_
 
 struct PanelType *UI_paneltype_find(int space_id, int region_id, const char *idname);
 
+struct PointerRNA *UI_region_panel_custom_data_under_cursor(const struct bContext *C,
+                                                            const struct wmEvent *event);
+void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_data);
+
 /* Polyinstantiated panels for representing a list of data. */
 struct Panel *UI_panel_add_instanced(struct ScrArea *area,
                                      struct ARegion *region,
                                      struct ListBase *panels,
                                      char *panel_idname,
-                                     int list_index);
+                                     int list_index,
+                                     struct PointerRNA *custom_data);
 void UI_panels_free_instanced(struct bContext *C, struct ARegion *region);
 
 #define LIST_PANEL_UNIQUE_STR_LEN 4
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 6aefef197df..771e9383b8a 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -5576,6 +5576,7 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout,
   panel->layout = layout;
   pt->draw(C, panel);
   panel->layout = NULL;
+  BLI_assert(panel->runtime.custom_data_ptr = NULL);
 
   MEM_freeN(panel);
 
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 9ff678df0db..4bf88c76857 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -245,20 +245,25 @@ static bool panels_need_realign(ScrArea *area, ARegion *region, Panel **r_panel_
 
 /********* Functions for instanced panels. ***********/
 
-static Panel *UI_panel_add_instanced_ex(
-    ScrArea *area, ARegion *region, ListBase *panels, PanelType *panel_type, int list_index)
+static Panel *UI_panel_add_instanced_ex(ScrArea *area,
+                                        ARegion *region,
+                                        ListBase *panels,
+                                        PanelType *panel_type,
+                                        int list_index,
+                                        PointerRNA *custom_data)
 {
   Panel *panel = MEM_callocN(sizeof(Panel), "instanced panel");
   panel->type = panel_type;
   BLI_strncpy(panel->panelname, panel_type->idname, sizeof(panel->panelname));
 
   panel->runtime.list_index = list_index;
+  panel->runtime.custom_data_ptr = custom_data;
 
   /* Add the panel's children too. Although they aren't instanced panels, we can still use this
    * function to create them, as UI_panel_begin does other things we don't need to do. */
   LISTBASE_FOREACH (LinkData *, child, &panel_type->children) {
     PanelType *child_type = child->data;
-    UI_panel_add_instanced_ex(area, region, &panel->children, child_type, list_index);
+    UI_panel_add_instanced_ex(area, region, &panel->children, child_type, list_index, custom_data);
   }
 
   /* Make sure the panel is added to the end of the display-order as well. This is needed for
@@ -283,8 +288,12 @@ static Panel *UI_panel_add_instanced_ex(
  * Called in situations where panels need to be added dynamically rather than having only one panel
  * corresponding to each PanelType.
  */
-Panel *UI_panel_add_instanced(
-    ScrArea *area, ARegion *region, ListBase *panels, char *panel_idname, int list_index)
+Panel *UI_panel_add_instanced(ScrArea *area,
+                              ARegion *region,
+                              ListBase *panels,
+                              char *panel_idname,
+                              int list_index,
+                              PointerRNA *custom_data)
 {
   ARegionType *region_type = region->type;
 
@@ -296,7 +305,7 @@ Panel *UI_panel_add_instanced(
     return NULL;
   }
 
-  return UI_panel_add_instanced_ex(area, region, panels, panel_type, list_index);
+  return UI_panel_add_instanced_ex(area, region, panels, panel_type, list_index, custom_data);
 }
 
 /**
@@ -332,7 +341,8 @@ static void panel_free_block(ARegion *region, Panel *panel)
 }
 
 /**
- * Free a panel and it's children.
+ * Free a panel and it's children. Custom data is shared by the panel and its children
+ * and is freed by #UI_panels_free_instanced.
  *
  * \note The only panels that should need to be deleted at runtime are panels with the
  * #PNL_INSTANCED flag set.
@@ -369,6 +379,13 @@ void UI_panels_free_instanced(bContext *C, ARegion *region)
       if (C != NULL && panel->activedata != NULL) {
         panel_activate_state(C, panel, PANEL_STATE_EXIT);
       }
+
+      /* Free panel's custom data. */
+      if (panel->runtime.custom_data_ptr != NULL) {
+        MEM_freeN(panel->runtime.custom_data_ptr);
+      }
+
+      /* Free the panel and its subpanels. */
       panel_delete(region, &region->panels, panel);
     }
   }
@@ -2886,6 +2903,56 @@ int ui_handler_panel_region(bContext *C,
   return retval;
 }
 
+static void ui_panel_custom_data_set_recursive(Panel *panel, PointerRNA *custom_data)
+{
+  panel->runtime.custom_data_ptr = custom_data;
+
+  LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
+    ui_panel_custom_data_set_recursive(child_panel, custom_data);
+  }
+}
+
+void UI_panel_custom_data_set(Panel *panel, PointerRNA *custom_data)
+{
+  BLI_assert(panel->type != NULL);
+
+  /* Free the old custom data, which should be shared among all of the panel's subpanels. */
+  if (panel->runtime.custom_data_ptr != NULL) {
+    MEM_freeN(panel->runtime.custom_data_ptr);
+  }
+
+  ui_panel_custom_data_set_recursive(panel, custom_data);
+}
+
+PointerRNA *UI_region_panel_custom_data_under_cursor(const bContext *C, const wmEvent *event)
+{
+  ARegion *region = CTX_wm_region(C);
+
+  Panel *panel = NULL;
+  LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+    panel = block->panel;
+    if (panel == NULL) {
+      continue;
+    }
+
+    int mx = event->x;
+    int my = event->y;
+    ui_window_to_block(region, block, &mx, &my);
+    int mouse_state = ui_panel_mouse_state_get(block, panel, mx, my);
+    if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) {
+      break;
+    }
+  }
+
+  if (panel == NULL) {
+    return NULL;
+  }
+
+  PointerRNA *customdata = panel->runtime.custom_data_ptr;
+
+  return customdata;
+}
+
 /**************** window level modal panel interaction **************/
 
 /* note, this is modal handler and should 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list