Own recent removal of string encoded menus missed render layers/passes
authorCampbell Barton <ideasman42@gmail.com>
Tue, 11 Feb 2014 13:08:54 +0000 (00:08 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 11 Feb 2014 13:08:54 +0000 (00:08 +1100)
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/space_buttons/buttons_texture.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_node/node_templates.c

index 71d55c73faadea4f8b24d271ed506fa259b7e4f7..1dbef0ba0149bfe88ffa534edf3f8fdb8c0e2a29 100644 (file)
@@ -440,6 +440,8 @@ void    uiButClearFlag(uiBut *but, int flag);
 void    uiButSetDrawFlag(uiBut *but, int flag);
 void    uiButClearDrawFlag(uiBut *but, int flag);
 
+void    uiButSetMenuFromPulldown(uiBut *but);
+
 /* special button case, only draw it when used actively, for outliner etc */
 bool    uiButActiveOnly(const struct bContext *C, struct ARegion *ar, uiBlock *block, uiBut *but);
 
index 4034ad46520bed87da63696585754ed1aa8a98ad..2e6cb35faaae2e60fbcfb8ab43c6805b3aeff526 100644 (file)
@@ -3757,6 +3757,14 @@ void uiButClearDrawFlag(uiBut *but, int flag)
        but->drawflag &= ~flag;
 }
 
+void uiButSetMenuFromPulldown(uiBut *but)
+{
+       BLI_assert(but->type == PULLDOWN);
+       but->type = MENU;
+       uiButClearDrawFlag(but, UI_BUT_TEXT_RIGHT);
+       uiButSetDrawFlag(but, UI_BUT_TEXT_LEFT);
+}
+
 int uiButGetRetVal(uiBut *but)
 {
        return but->retval;
index a2cbd0723c9a6fb6108c03388be1ae8ce80a707b..e27177be4b4b27e4f271e79d01bc870ea14aebb3 100644 (file)
@@ -1654,8 +1654,7 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre
        if (ELEM(layout->root->type, UI_LAYOUT_PANEL, UI_LAYOUT_TOOLBAR) ||
            (force_menu && layout->root->type != UI_LAYOUT_MENU))  /* We never want a dropdown in menu! */
        {
-               but->type = MENU;
-               but->drawflag |= UI_BUT_TEXT_LEFT;
+               uiButSetMenuFromPulldown(but);
        }
 }
 
index eb992b650106be69810142f44e337785e01103af..7c42ea9a13b51a8cc8c8a5c995ab6e0b2eb8e0f8 100644 (file)
@@ -576,8 +576,8 @@ void uiTemplateTextureUser(uiLayout *layout, bContext *C)
        }
 
        /* some cosmetic tweaks */
-       but->type = MENU;
-       but->drawflag |= UI_BUT_TEXT_LEFT;
+       uiButSetMenuFromPulldown(but);
+
        but->flag &= ~UI_ICON_SUBMENU;
 }
 
index f9539d44f2b9e1b5236222699ee5bfec5d360b55..f4a3454359091441a9c4030e87260f6a6cca3d9d 100644 (file)
@@ -70,6 +70,8 @@
 
 #include "image_intern.h"
 
+#define B_NOP -1
+
 /* proto */
 
 static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str, size_t len)
@@ -289,76 +291,128 @@ static void image_panel_preview(ScrArea *sa, short cntrl)   // IMAGE_HANDLER_PRE
 
 /* ********************* callbacks for standard image buttons *************** */
 
-static char *slot_menu(void)
+static void ui_imageuser_slot_menu(bContext *UNUSED(C), uiLayout *layout, void *render_slot_p)
 {
-       char *str;
-       int a, slot;
-       
-       str = MEM_callocN(IMA_MAX_RENDER_SLOT * 32, "menu slots");
-       
-       strcpy(str, IFACE_("Slot %t"));
-       a = strlen(str);
+       uiBlock *block = uiLayoutGetBlock(layout);
+       short *render_slot = render_slot_p;
+       int slot;
 
-       for (slot = 0; slot < IMA_MAX_RENDER_SLOT; slot++)
-               a += sprintf(str + a, IFACE_("|Slot %d %%x%d"), slot + 1, slot);
-       
-       return str;
+       uiDefBut(block, LABEL, 0, IFACE_("Slot"),
+                0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+       uiItemS(layout);
+
+       slot = IMA_MAX_RENDER_SLOT;
+       while (slot--) {
+               char str[32];
+               BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), slot + 1);
+               uiDefButS(block, BUTM, B_NOP, str, 0, 0,
+                         UI_UNIT_X * 5, UI_UNIT_X, render_slot, (float) slot, 0.0, 0, -1, "");
+       }
 }
 
-/* TODO, curlay should be removed? */
-static char *layer_menu(RenderResult *rr, short *UNUSED(curlay))
+static const char *ui_imageuser_layer_fake_name(RenderResult *rr)
 {
-       RenderLayer *rl;
-       int len = 64 + RE_MAXNAME * BLI_countlist(&rr->layers);
-       short a, nr = 0;
-       char *str = MEM_callocN(len, "menu layers");
-       
-       strcpy(str, IFACE_("Layer %t"));
-       a = strlen(str);
-       
-       /* compo result */
        if (rr->rectf) {
-               a += sprintf(str + a, "|%s %%x0", IFACE_("Composite"));
-               nr = 1;
+               return IFACE_("Composite");
        }
        else if (rr->rect32) {
-               a += sprintf(str + a, "|%s %%x0", IFACE_("Sequence"));
-               nr = 1;
+               return IFACE_("Sequence");
        }
-       for (rl = rr->layers.first; rl; rl = rl->next, nr++) {
-               a += sprintf(str + a, "|%s %%x%d", rl->name, nr);
+       else {
+               return NULL;
+       }
+}
+
+static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void *rnd_pt)
+{
+       void **rnd_data = rnd_pt;
+       uiBlock *block = uiLayoutGetBlock(layout);
+       RenderResult *rr = rnd_data[0];
+       ImageUser *iuser = rnd_data[1];
+       RenderLayer *rl;
+       RenderLayer rl_fake = {0};
+       const char *fake_name;
+       int nr;
+
+       uiBlockSetCurLayout(block, layout);
+       uiLayoutColumn(layout, false);
+
+       uiDefBut(block, LABEL, 0, IFACE_("Layer"),
+                0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+       uiItemS(layout);
+
+       nr = BLI_countlist(&rr->layers) - 1;
+       fake_name = ui_imageuser_layer_fake_name(rr);
+
+       if (fake_name) {
+               BLI_strncpy(rl_fake.name, fake_name, sizeof(rl_fake.name));
+               rl_fake.prev = rr->layers.last;
+               nr += 1;
+       }
+
+       for (rl = rr->layers.last; rl; rl = rl->prev, nr--) {
+final:
+               uiDefButS(block, BUTM, B_NOP, IFACE_(rl->name), 0, 0,
+                         UI_UNIT_X * 5, UI_UNIT_X, &iuser->layer, (float) nr, 0.0, 0, -1, "");
+       }
+
+       if (fake_name && nr != -1) {
+               rl = &rl_fake;
+               goto final;
+       }
+}
+
+static const char *ui_imageuser_pass_fake_name(RenderLayer *rl)
+{
+       if (rl == NULL || rl->rectf) {
+               return IFACE_("Combined");
+       }
+       else {
+               return NULL;
        }
-       
-       /* no curlay clip here, on render (redraws) the amount of layers can be 1 fir single-layer render */
-       
-       return str;
 }
 
-/* rl==NULL means composite result */
-static char *pass_menu(RenderLayer *rl, short *curpass)
+static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *ptrpair_p)
 {
+       void **ptrpair = ptrpair_p;
+       uiBlock *block = uiLayoutGetBlock(layout);
+       // RenderResult *rr = ptrpair[0];
+       ImageUser *iuser = ptrpair[1];
+       /* rl==NULL means composite result */
+       RenderLayer *rl = ptrpair[2];
+       RenderPass rpass_fake = {0};
        RenderPass *rpass;
-       int len = 64 + 32 * (rl ? BLI_countlist(&rl->passes) : 1);
-       short a, nr = 0;
-       char *str = MEM_callocN(len, "menu layers");
-       
-       strcpy(str, IFACE_("Pass %t"));
-       a = strlen(str);
-       
+       const char *fake_name;
+       int nr;
+
+       uiBlockSetCurLayout(block, layout);
+       uiLayoutColumn(layout, false);
+
+       uiDefBut(block, LABEL, 0, IFACE_("Pass"),
+                0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+
+       uiItemS(layout);
+
+       nr = (rl ? BLI_countlist(&rl->passes) : 0) - 1;
+       fake_name = ui_imageuser_pass_fake_name(rl);
+
+       if (fake_name) {
+               BLI_strncpy(rpass_fake.name, fake_name, sizeof(rpass_fake.name));
+               rpass = &rpass_fake;
+               nr += 1;
+       }
+
        /* rendered results don't have a Combined pass */
-       if (rl == NULL || rl->rectf) {
-               a += sprintf(str + a, "|%s %%x0", IFACE_("Combined"));
-               nr = 1;
+       for (rpass = rl->passes.last; rpass; rpass = rpass->prev, nr--) {
+final:
+               uiDefButS(block, BUTM, B_NOP, IFACE_(rpass->name), 0, 0,
+                         UI_UNIT_X * 5, UI_UNIT_X, &iuser->pass, (float) nr, 0.0, 0, -1, "");
+       }
+
+       if (fake_name && nr != -1) {
+               rpass = &rpass_fake;
+               goto final;
        }
-       
-       if (rl)
-               for (rpass = rl->passes.first; rpass; rpass = rpass->next, nr++)
-                       a += sprintf(str + a, "|%s %%x%d", IFACE_(rpass->name), nr);
-       
-       if (*curpass >= nr)
-               *curpass = 0;
-       
-       return str;
 }
 
 /* 5 layer button callbacks... */
@@ -443,11 +497,13 @@ static void image_user_change(bContext *C, void *iuser_v, void *unused)
 
 static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w, short *render_slot)
 {
+       static void *rnd_pt[3];  /* XXX, workaround */
        uiBlock *block = uiLayoutGetBlock(layout);
        uiBut *but;
        RenderLayer *rl = NULL;
-       int wmenu1, wmenu2, wmenu3, layer;
-       char *strp;
+       int wmenu1, wmenu2, wmenu3;
+       const char *fake_name;
+       const char *display_name;
 
        uiLayoutRow(layout, TRUE);
 
@@ -456,29 +512,40 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, Image
        wmenu2 = (3 * w) / 5;
        wmenu3 = (3 * w) / 6;
        
+       rnd_pt[0] = rr;
+       rnd_pt[1] = iuser;
+       rnd_pt[2] = NULL;
+
        /* menu buts */
        if (render_slot) {
-               strp = slot_menu();
-               but = uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, UI_UNIT_Y, render_slot, 0, 0, 0, 0, TIP_("Select Slot"));
-               uiButSetFunc(but, image_multi_cb, rr, iuser);
-               MEM_freeN(strp);
+               char str[64];
+               BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), *render_slot + 1);
+               but = uiDefMenuBut(block, ui_imageuser_slot_menu, render_slot, str, 0, 0, wmenu1, UI_UNIT_Y, TIP_("Select Slot"));
+               uiButSetMenuFromPulldown(but);
        }
 
        if (rr) {
-               strp = layer_menu(rr, &iuser->layer);
-               but = uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, UI_UNIT_Y, &iuser->layer, 0, 0, 0, 0, TIP_("Select Layer"));
+               RenderPass *rpass;
+
+               /* layer */
+               fake_name = ui_imageuser_layer_fake_name(rr);
+               rl = BLI_findlink(&rr->layers, iuser->layer  - (fake_name ? 1 : 0));
+               rnd_pt[2] = rl;
+
+               display_name = rl ? rl->name : (fake_name ? fake_name : "");
+               but = uiDefMenuBut(block, ui_imageuser_layer_menu, rnd_pt, display_name, 0, 0, wmenu2, UI_UNIT_Y, TIP_("Select Layer"));
                uiButSetFunc(but, image_multi_cb, rr, iuser);
-               MEM_freeN(strp);
+               uiButSetMenuFromPulldown(but);
 
-               layer = iuser->layer;
-               if (rr->rectf || rr->rect32)
-                       layer--;  /* fake compo/sequencer layer */
-               
-               rl = BLI_findlink(&rr->layers, layer); /* return NULL is meant to be */
-               strp = pass_menu(rl, &iuser->pass);
-               but = uiDefButS(block, MENU, 0, strp, 0, 0, wmenu3, UI_UNIT_Y, &iuser->pass, 0, 0, 0, 0, TIP_("Select Pass"));
+
+               /* pass */
+               fake_name = ui_imageuser_pass_fake_name(rl);
+               rpass = (rl ? BLI_findlink(&rl->passes, iuser->pass  - (fake_name ? 1 : 0)) : NULL);
+
+               display_name = rpass ? rpass->name : (fake_name ? fake_name : "");
+               but = uiDefMenuBut(block, ui_imageuser_pass_menu, rnd_pt, display_name, 0, 0, wmenu3, UI_UNIT_Y, TIP_("Select Pass"));
                uiButSetFunc(but, image_multi_cb, rr, iuser);
-               MEM_freeN(strp);
+               uiButSetMenuFromPulldown(but);
        }
 }
 
index 13a702e09c41b0127a4b04fad9cf5bbc97affc88..c75c16e61c586ac01e531e5bde86f3054acfb432 100644 (file)
@@ -562,8 +562,8 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo
        else
                but = uiDefIconMenuBut(block, ui_template_node_link_menu, NULL, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, "");
 
-       but->type = MENU;
-       but->drawflag |= UI_BUT_TEXT_LEFT;
+       uiButSetMenuFromPulldown(but);
+
        but->flag |= UI_BUT_NODE_LINK;
        but->poin = (char *)but;
        but->func_argN = arg;