UI: layout support for fixed size buttons, and use for file browser open/cancel
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 19 Sep 2019 14:14:47 +0000 (16:14 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 19 Sep 2019 16:40:58 +0000 (18:40 +0200)
Not exposed to Python API yet, this should get more detailed testing with different
layouts before that happens.

Ref T69652

source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/space_file/file_panels.c

index 702d319817fb790c3d1c1e79014c1dc186bb8df1..6fc71846cbb7fc016d41b01b53d77bdc0f860922 100644 (file)
@@ -1810,6 +1810,7 @@ void uiLayoutSetActivateInit(uiLayout *layout, bool active);
 void uiLayoutSetEnabled(uiLayout *layout, bool enabled);
 void uiLayoutSetRedAlert(uiLayout *layout, bool redalert);
 void uiLayoutSetAlignment(uiLayout *layout, char alignment);
+void uiLayoutSetFixedSize(uiLayout *layout, bool fixed_size);
 void uiLayoutSetKeepAspect(uiLayout *layout, bool keepaspect);
 void uiLayoutSetScaleX(uiLayout *layout, float scale);
 void uiLayoutSetScaleY(uiLayout *layout, float scale);
@@ -1827,6 +1828,7 @@ bool uiLayoutGetActivateInit(uiLayout *layout);
 bool uiLayoutGetEnabled(uiLayout *layout);
 bool uiLayoutGetRedAlert(uiLayout *layout);
 int uiLayoutGetAlignment(uiLayout *layout);
+bool uiLayoutGetFixedSize(uiLayout *layout);
 bool uiLayoutGetKeepAspect(uiLayout *layout);
 int uiLayoutGetWidth(uiLayout *layout);
 float uiLayoutGetScaleX(uiLayout *layout);
index 6a707b56f363536f0262009f995e9a127dc06617..a6f8ba4560de81c71b4a045b287ab40498e1ff4f 100644 (file)
@@ -130,8 +130,8 @@ typedef struct uiItem {
 } uiItem;
 
 enum {
-  UI_ITEM_FIXED = 1 << 0,
-  UI_ITEM_MIN = 1 << 1,
+  UI_ITEM_AUTO_FIXED_SIZE = 1 << 0,
+  UI_ITEM_FIXED_SIZE = 1 << 1,
 
   UI_ITEM_BOX_ITEM = 1 << 2, /* The item is "inside" a box item */
   UI_ITEM_PROP_SEP = 1 << 3,
@@ -307,7 +307,7 @@ static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, bool
       return unit_x; /* No icon or name. */
     }
     if (layout->alignment != UI_LAYOUT_ALIGN_EXPAND) {
-      layout->item.flag |= UI_ITEM_MIN;
+      layout->item.flag |= UI_ITEM_FIXED_SIZE;
     }
     const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
     float margin = compact ? 1.25 : 1.50;
@@ -3269,7 +3269,7 @@ static void ui_litem_estimate_row(uiLayout *litem)
   for (item = litem->items.first; item; item = item->next) {
     ui_item_size(item, &itemw, &itemh);
 
-    min_size_flag = min_size_flag && (item->flag & UI_ITEM_MIN);
+    min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE);
 
     litem->w += itemw;
     litem->h = MAX2(itemh, litem->h);
@@ -3280,7 +3280,7 @@ static void ui_litem_estimate_row(uiLayout *litem)
   }
 
   if (min_size_flag) {
-    litem->item.flag |= UI_ITEM_MIN;
+    litem->item.flag |= UI_ITEM_FIXED_SIZE;
   }
 }
 
@@ -3326,7 +3326,7 @@ static void ui_litem_layout_row(uiLayout *litem)
     extra_pixel = 0.0f;
 
     for (item = litem->items.first; item; item = item->next) {
-      if (item->flag & UI_ITEM_FIXED) {
+      if (item->flag & UI_ITEM_AUTO_FIXED_SIZE) {
         continue;
       }
 
@@ -3342,18 +3342,19 @@ static void ui_litem_layout_row(uiLayout *litem)
 
       x += neww;
 
-      bool min_flag = item->flag & UI_ITEM_MIN;
+      bool min_flag = item->flag & UI_ITEM_FIXED_SIZE;
       /* ignore min flag for rows with right or center alignment */
       if (item->type != ITEM_BUTTON &&
           ELEM(((uiLayout *)item)->alignment, UI_LAYOUT_ALIGN_RIGHT, UI_LAYOUT_ALIGN_CENTER) &&
-          litem->alignment == UI_LAYOUT_ALIGN_EXPAND && ((uiItem *)litem)->flag & UI_ITEM_MIN) {
+          litem->alignment == UI_LAYOUT_ALIGN_EXPAND &&
+          ((uiItem *)litem)->flag & UI_ITEM_FIXED_SIZE) {
         min_flag = false;
       }
 
       if ((neww < minw || min_flag) && w != 0) {
         /* fixed size */
-        item->flag |= UI_ITEM_FIXED;
-        if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_MIN) {
+        item->flag |= UI_ITEM_AUTO_FIXED_SIZE;
+        if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_FIXED_SIZE) {
           minw = itemw;
         }
         fixedw += minw;
@@ -3362,7 +3363,7 @@ static void ui_litem_layout_row(uiLayout *litem)
       }
       else {
         /* keep free size */
-        item->flag &= ~UI_ITEM_FIXED;
+        item->flag &= ~UI_ITEM_AUTO_FIXED_SIZE;
         freew += itemw;
       }
     }
@@ -3380,9 +3381,9 @@ static void ui_litem_layout_row(uiLayout *litem)
     ui_item_size(item, &itemw, &itemh);
     minw = ui_litem_min_width(itemw);
 
-    if (item->flag & UI_ITEM_FIXED) {
+    if (item->flag & UI_ITEM_AUTO_FIXED_SIZE) {
       /* fixed minimum size items */
-      if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_MIN) {
+      if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_FIXED_SIZE) {
         minw = itemw;
       }
       itemw = ui_item_fit(
@@ -3423,7 +3424,7 @@ static void ui_litem_layout_row(uiLayout *litem)
   uiItem *last_item = litem->items.last;
   extra_pixel = litem->w - (x - litem->x);
   if (extra_pixel > 0 && litem->alignment == UI_LAYOUT_ALIGN_EXPAND && last_free_item &&
-      last_item && last_item->flag & UI_ITEM_FIXED) {
+      last_item && last_item->flag & UI_ITEM_AUTO_FIXED_SIZE) {
     ui_item_move(last_free_item, 0, extra_pixel);
     for (item = last_free_item->next; item; item = item->next) {
       ui_item_move(item, extra_pixel, extra_pixel);
@@ -3449,7 +3450,7 @@ static void ui_litem_estimate_column(uiLayout *litem, bool is_box)
   for (item = litem->items.first; item; item = item->next) {
     ui_item_size(item, &itemw, &itemh);
 
-    min_size_flag = min_size_flag && (item->flag & UI_ITEM_MIN);
+    min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE);
 
     litem->w = MAX2(litem->w, itemw);
     litem->h += itemh;
@@ -3460,7 +3461,7 @@ static void ui_litem_estimate_column(uiLayout *litem, bool is_box)
   }
 
   if (min_size_flag) {
-    litem->item.flag |= UI_ITEM_MIN;
+    litem->item.flag |= UI_ITEM_FIXED_SIZE;
   }
 }
 
@@ -4279,7 +4280,7 @@ static void ui_litem_layout_absolute(uiLayout *litem)
 static void ui_litem_estimate_split(uiLayout *litem)
 {
   ui_litem_estimate_row(litem);
-  litem->item.flag &= ~UI_ITEM_MIN;
+  litem->item.flag &= ~UI_ITEM_FIXED_SIZE;
 }
 
 static void ui_litem_layout_split(uiLayout *litem)
@@ -5099,7 +5100,7 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
   /* XXX uiBut hasn't scaled yet
    * we can flag the button as not expandable, depending on its size */
   if (w <= 2 * UI_UNIT_X && (!but->str || but->str[0] == '\0')) {
-    bitem->item.flag |= UI_ITEM_MIN;
+    bitem->item.flag |= UI_ITEM_FIXED_SIZE;
   }
 
   if (layout->child_items_layout) {
@@ -5119,6 +5120,21 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
   }
 }
 
+void uiLayoutSetFixedSize(uiLayout *layout, bool fixed_size)
+{
+  if (fixed_size) {
+    layout->item.flag |= UI_ITEM_FIXED_SIZE;
+  }
+  else {
+    layout->item.flag &= ~UI_ITEM_FIXED_SIZE;
+  }
+}
+
+bool uiLayoutGetFixedSize(uiLayout *layout)
+{
+  return (layout->item.flag & UI_ITEM_FIXED_SIZE) != 0;
+}
+
 void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext)
 {
   layout->root->opcontext = opcontext;
index 8b83b5e1b053e0bd8b2d96aaaa901263e491070e..9ba098fcf45c0afdd9d45315a4cfd5f7cc77f807 100644 (file)
@@ -110,18 +110,22 @@ void file_tool_props_region_panels_register(ARegionType *art)
   BLI_addtail(&art->paneltypes, pt);
 }
 
-static void file_panel_execution_cancel_button(uiBlock *block)
+static void file_panel_execution_cancel_button(uiLayout *layout)
 {
-  uiDefButO(block,
-            UI_BTYPE_BUT,
-            "FILE_OT_cancel",
-            WM_OP_EXEC_REGION_WIN,
-            IFACE_("Cancel"),
-            0,
-            0,
-            UI_UNIT_X,
-            UI_UNIT_Y,
-            "");
+  uiLayout *row = uiLayoutRow(layout, false);
+  uiLayoutSetScaleX(row, 0.8f);
+  uiLayoutSetFixedSize(row, true);
+  uiItemO(row, IFACE_("Cancel"), ICON_NONE, "FILE_OT_cancel");
+}
+
+static void file_panel_execution_execute_button(uiLayout *layout, const char *title)
+{
+  uiLayout *row = uiLayoutRow(layout, false);
+  uiLayoutSetScaleX(row, 0.8f);
+  uiLayoutSetFixedSize(row, true);
+  /* Just a display hint. */
+  uiLayoutSetActiveDefault(row, true);
+  uiItemO(row, title, ICON_NONE, "FILE_OT_execute");
 }
 
 static void file_panel_execution_buttons_draw(const bContext *C, Panel *pa)
@@ -145,7 +149,6 @@ static void file_panel_execution_buttons_draw(const bContext *C, Panel *pa)
   RNA_pointer_create(&screen->id, &RNA_FileSelectParams, params, &params_rna_ptr);
 
   row = uiLayoutRow(pa->layout, false);
-  uiLayoutSetScaleX(row, 1.3f);
   uiLayoutSetScaleY(row, 1.3f);
 
   /* callbacks for operator check functions */
@@ -192,23 +195,16 @@ static void file_panel_execution_buttons_draw(const bContext *C, Panel *pa)
   UI_block_func_set(block, NULL, NULL, NULL);
 
   {
-    if (windows_layout == false) {
-      file_panel_execution_cancel_button(block);
-    }
-    but = uiDefButO(block,
-                    UI_BTYPE_BUT,
-                    "FILE_OT_execute",
-                    WM_OP_EXEC_REGION_WIN,
-                    params->title,
-                    0,
-                    0,
-                    UI_UNIT_X,
-                    UI_UNIT_Y,
-                    "");
-    /* Just a display hint. */
-    UI_but_flag_enable(but, UI_BUT_ACTIVE_DEFAULT);
+    uiLayout *sub = uiLayoutRow(row, false);
+    uiLayoutSetOperatorContext(sub, WM_OP_EXEC_REGION_WIN);
+
     if (windows_layout) {
-      file_panel_execution_cancel_button(block);
+      file_panel_execution_execute_button(sub, params->title);
+      file_panel_execution_cancel_button(sub);
+    }
+    else {
+      file_panel_execution_cancel_button(sub);
+      file_panel_execution_execute_button(sub, params->title);
     }
   }
 }