UI: Ctrl-click on panel header expands & collapses subpanels
If the panel is already open and you ctrl click on its header, its sub-panels are now expanded / collapsed instead of toggling the expansion for all other panels. If you're toggling a panel's expansion it's already in view anyway, so there is no need to collapse the other panels. Differential Revision: https://developer.blender.org/D8042
This commit is contained in:
		@@ -583,6 +583,26 @@ static void set_panels_list_data_expand_flag(const bContext *C, ARegion *region)
 | 
			
		||||
 | 
			
		||||
/****************************** panels ******************************/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set flag state for a panel and its subpanels.
 | 
			
		||||
 *
 | 
			
		||||
 * \return True if this function changed any of the flags, false if it didn't.
 | 
			
		||||
 */
 | 
			
		||||
static bool panel_set_flag_recursive(Panel *panel, int flag, bool value)
 | 
			
		||||
{
 | 
			
		||||
  short flag_original = panel->flag;
 | 
			
		||||
 | 
			
		||||
  SET_FLAG_FROM_TEST(panel->flag, value, flag);
 | 
			
		||||
 | 
			
		||||
  bool changed = (flag_original != panel->flag);
 | 
			
		||||
 | 
			
		||||
  LISTBASE_FOREACH (Panel *, child, &panel->children) {
 | 
			
		||||
    changed |= panel_set_flag_recursive(child, flag, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void panels_collapse_all(const bContext *C,
 | 
			
		||||
                                ScrArea *area,
 | 
			
		||||
                                ARegion *region,
 | 
			
		||||
@@ -2017,11 +2037,25 @@ static void ui_handle_panel_header(
 | 
			
		||||
    if (button == 2) { /* close */
 | 
			
		||||
      ED_region_tag_redraw(region);
 | 
			
		||||
    }
 | 
			
		||||
    else { /* collapse */
 | 
			
		||||
    else {
 | 
			
		||||
      /* Collapse and expand panels. */
 | 
			
		||||
 | 
			
		||||
      if (ctrl) {
 | 
			
		||||
        /* Only collapse all for parent panels. */
 | 
			
		||||
        if (block->panel->type != NULL && block->panel->type->parent == NULL) {
 | 
			
		||||
          if (block->panel->flag & PNL_CLOSED || BLI_listbase_is_empty(&block->panel->children)) {
 | 
			
		||||
            panels_collapse_all(C, area, region, block->panel);
 | 
			
		||||
          }
 | 
			
		||||
          else {
 | 
			
		||||
            const int closed_flag = (align == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY;
 | 
			
		||||
            /* If a panel has subpanels and it's open, toggle the expansion
 | 
			
		||||
             * of the subpanels (based on the expansion of the first subpanel). */
 | 
			
		||||
            Panel *first_child = block->panel->children.first;
 | 
			
		||||
            BLI_assert(first_child != NULL);
 | 
			
		||||
            panel_set_flag_recursive(
 | 
			
		||||
                block->panel, closed_flag, (first_child->flag & PNL_CLOSED) == 0);
 | 
			
		||||
            block->panel->flag |= closed_flag;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          /* reset the view - we don't want to display a view without content */
 | 
			
		||||
          UI_view2d_offset(®ion->v2d, 0.0f, 1.0f);
 | 
			
		||||
@@ -2899,24 +2933,6 @@ static void ui_handler_remove_panel(bContext *C, void *userdata)
 | 
			
		||||
  panel_activate_state(C, panel, PANEL_STATE_EXIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set selection state for a panel and its subpanels. The subpanels need to know they are selected
 | 
			
		||||
 * too so they can be drawn above their parent when it is dragged.
 | 
			
		||||
 */
 | 
			
		||||
static void set_panel_selection(Panel *panel, bool value)
 | 
			
		||||
{
 | 
			
		||||
  if (value) {
 | 
			
		||||
    panel->flag |= PNL_SELECT;
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    panel->flag &= ~PNL_SELECT;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  LISTBASE_FOREACH (Panel *, child, &panel->children) {
 | 
			
		||||
    set_panel_selection(child, value);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelState state)
 | 
			
		||||
{
 | 
			
		||||
  uiHandlePanelData *data = panel->activedata;
 | 
			
		||||
@@ -2929,6 +2945,8 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS
 | 
			
		||||
 | 
			
		||||
  bool was_drag_drop = (data && data->state == PANEL_STATE_DRAG);
 | 
			
		||||
 | 
			
		||||
  /* Set selection state for the panel and its subpanels, which need to know they are selected
 | 
			
		||||
   * too so they can be drawn above their parent when it's dragged. */
 | 
			
		||||
  if (state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) {
 | 
			
		||||
    if (data && data->state != PANEL_STATE_ANIMATION) {
 | 
			
		||||
      /* XXX:
 | 
			
		||||
@@ -2941,10 +2959,10 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS
 | 
			
		||||
      check_panel_overlap(region, NULL); /* clears */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_panel_selection(panel, false);
 | 
			
		||||
    panel_set_flag_recursive(panel, PNL_SELECT, false);
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    set_panel_selection(panel, true);
 | 
			
		||||
    panel_set_flag_recursive(panel, PNL_SELECT, true);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (data && data->animtimer) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user