Fix [#35750] list items in properties editor (text colors not following list item...
authorBastien Montagne <montagne29@wanadoo.fr>
Wed, 26 Jun 2013 07:28:55 +0000 (07:28 +0000)
committerBastien Montagne <montagne29@wanadoo.fr>
Wed, 26 Jun 2013 07:28:55 +0000 (07:28 +0000)
Issue goes back since we stopped using LISTROW button to draw item's name (i.e. since we have custom buttons in list items!).

This commit:
* Adds a new flag to uiBlock, UI_BLOCK_LIST_ITEM, to mark blocks used for each list item.
* Adds a new button type, LISTLABEL, which basically behaves exactly as LABEL, but uses wcol_list_item color set.
* When uiItemL is called, it checks whether current block has UI_BLOCK_LIST_ITEM set, and if so, switch produced button to LISTLABEL type.
* Adds a new helper func, ui_layout_list_set_labels_active, called after the active list item has been "drawn", to set all LISTLABEL buttons as UI_SELECT.

Note custom widget_state_label() was removed, in interface_widgets.c, as it did nothing more than default widget_state().

Thanks to Brecht for the review and advices.

source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c

index 9c9ab2972b30b5648ad5d99ae24af0be9526986e..b997d0ef6a0e4e9a6ac9e2500b2f6f0b9bdb9f2c 100644 (file)
@@ -125,9 +125,11 @@ typedef struct uiLayout uiLayout;
 #define UI_BLOCK_POPUP_MEMORY   (1 << 12)
 #define UI_BLOCK_CLIP_EVENTS    (1 << 13)  /* stop handling mouse events */
 
-/* XXX This comment is no more valid! */
+/* XXX This comment is no more valid! Maybe it is now bits 14-17? */
 /* block->flag bits 12-15 are identical to but->flag bits */
 
+#define UI_BLOCK_LIST_ITEM   (1 << 19)
+
 /* uiPopupBlockHandle->menuretval */
 #define UI_RETURN_CANCEL     (1 << 0)   /* cancel all menus cascading */
 #define UI_RETURN_OK         (1 << 1)   /* choice made */
@@ -251,7 +253,8 @@ typedef enum {
        VECTORSCOPE   = (50 << 9),
        PROGRESSBAR   = (51 << 9),
        SEARCH_MENU_UNLINK   = (52 << 9),
-       NODESOCKET    = (53 << 9)
+       NODESOCKET    = (53 << 9),
+       LISTLABEL     = (54 << 9),
 } eButType;
 
 #define BUTTYPE     (63 << 9)
index 7aee228ddaabdfd229227f6edc21a64f9d4d3df5..d86f22df4a798fb2cf097420c9dfba8d599b1b6a 100644 (file)
@@ -276,7 +276,7 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val)
 
 static bool ui_but_editable(uiBut *but)
 {
-       return ELEM5(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR);
+       return ELEM6(but->type, LABEL, LISTLABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR);
 }
 
 static uiBut *ui_but_prev(uiBut *but)
@@ -2010,7 +2010,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
        uiBut *but;
 
        /* label and roundbox can overlap real buttons (backdrops...) */
-       if (ELEM4(actbut->type, LABEL, SEPR, ROUNDBOX, LISTBOX))
+       if (ELEM5(actbut->type, LABEL, LISTLABEL, SEPR, ROUNDBOX, LISTBOX))
                return;
 
        for (but = actbut->next; but; but = but->next) {
@@ -2038,7 +2038,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
        uiBut *but;
 
        /* label and roundbox can overlap real buttons (backdrops...) */
-       if (ELEM4(actbut->type, LABEL, SEPR, ROUNDBOX, LISTBOX))
+       if (ELEM5(actbut->type, LABEL, LISTLABEL, SEPR, ROUNDBOX, LISTBOX))
                return;
 
        for (but = actbut->prev; but; but = but->prev) {
@@ -5361,6 +5361,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
                case ROUNDBOX:
                case LISTBOX:
                case LABEL:
+               case LISTLABEL:
                case ROW:
                case LISTROW:
                case BUT_IMAGE:
@@ -5558,7 +5559,7 @@ static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y)
 bool ui_is_but_interactive(uiBut *but)
 {
        /* note, LABEL is included for highlights, this allows drags */
-       if (but->type == LABEL && but->dragpoin == NULL)
+       if (ELEM(but->type, LABEL, LISTLABEL) && but->dragpoin == NULL)
                return false;
        if (ELEM3(but->type, ROUNDBOX, SEPR, LISTBOX))
                return false;
@@ -6995,7 +6996,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
                                                for (but = block->buttons.first; but; but = but->next) {
                                                        int doit = FALSE;
                                                        
-                                                       if (but->type != LABEL && but->type != SEPR)
+                                                       if (but->type != LABEL && but->type != LISTLABEL && but->type != SEPR)
                                                                count++;
                                                        
                                                        /* exception for rna layer buts */
index a6076b8df78bcc0a84efb6ecbe8740e13e390e94..82352cee05e9efec7ebc0b80dea78d7379b13d11 100644 (file)
@@ -94,7 +94,8 @@ typedef enum {
        UI_WTYPE_BOX,
        UI_WTYPE_SCROLL,
        UI_WTYPE_LISTITEM,
-       UI_WTYPE_PROGRESSBAR
+       UI_WTYPE_PROGRESSBAR,
+       UI_WTYPE_LISTLABEL,
 } uiWidgetTypeEnum;
 
 /* menu scrolling */
@@ -563,6 +564,7 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but);
 int ui_but_can_align(uiBut *but);
 void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop);
 void ui_but_add_shortcut(uiBut *but, const char *key_str, const bool do_strip);
+void ui_layout_list_set_labels_active(uiLayout *layout);
 
 /* interface_anim.c */
 void ui_but_anim_flag(uiBut *but, float cfra);
index 7c32f354c0a32d3c012adc21778a37304f82d1c3..2a6a9600582f201b943b857cdd9109ccccbca604 100644 (file)
@@ -1632,7 +1632,7 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
                but = uiDefIconBut(block, LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
        else
                but = uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-       
+
        /* to compensate for string size padding in ui_text_icon_width,
         * make text aligned right if the layout is aligned right.
         */
@@ -1640,7 +1640,12 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
                but->flag &= ~UI_TEXT_LEFT;     /* default, needs to be unset */
                but->flag |= UI_TEXT_RIGHT;
        }
-       
+
+       /* Mark as a label inside a listbox. */
+       if (block->flag & UI_BLOCK_LIST_ITEM) {
+               but->type = LISTLABEL;
+       }
+
        return but;
 }
 
@@ -2399,6 +2404,18 @@ uiLayout *uiLayoutBox(uiLayout *layout)
        return (uiLayout *)ui_layout_box(layout, ROUNDBOX);
 }
 
+/* Check all buttons defined in this layout, and set labels as active/selected.
+ * Needed to handle correctly text colors of list items. */
+void ui_layout_list_set_labels_active(uiLayout *layout)
+{
+       uiButtonItem *bitem;
+       for (bitem = layout->items.first; bitem; bitem = bitem->item.next) {
+               if (bitem->item.type == ITEM_BUTTON && bitem->but->type == LISTLABEL) {
+                       uiButSetFlag(bitem->but, UI_SELECT);
+               }
+       }
+}
+
 uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr,
                           PropertyRNA *actprop)
 {
index 34d1c24aade1d5ed32f70dcc3a0e2a61ec1ea9ff..1a6d79c918dce5b8243e027b94ad87924a99b4b0 100644 (file)
@@ -2640,6 +2640,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
                                        subblock = uiLayoutGetBlock(col);
                                        overlap = uiLayoutOverlap(col);
 
+                                       uiBlockSetFlag(subblock, UI_BLOCK_LIST_ITEM);
+
                                        /* list item behind label & other buttons */
                                        sub = uiLayoutRow(overlap, FALSE);
 
@@ -2653,6 +2655,11 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
                                        if (icon == ICON_DOT)
                                                icon = ICON_NONE;
                                        draw_item(ui_list, C, sub, dataptr, &itemptr, icon, active_dataptr, active_propname, i);
+
+                                       /* If we are "drawing" active item, set all labels as active. */
+                                       if (i == activei) {
+                                               ui_layout_list_set_labels_active(sub);
+                                       }
                                }
                                i++;
                        }
@@ -2721,6 +2728,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
                                subblock = uiLayoutGetBlock(row);
                                overlap = uiLayoutOverlap(row);
 
+                               uiBlockSetFlag(subblock, UI_BLOCK_LIST_ITEM);
+
                                /* list item behind label & other buttons */
                                sub = uiLayoutRow(overlap, FALSE);
 
@@ -2733,6 +2742,11 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
                                icon = UI_rnaptr_icon_get(C, &itemptr, rnaicon, false);
                                draw_item(ui_list, C, sub, dataptr, &itemptr, icon, active_dataptr, active_propname, i);
 
+                               /* If we are "drawing" active item, set all labels as active. */
+                               if (i == activei) {
+                                       ui_layout_list_set_labels_active(sub);
+                               }
+
                                i++;
                        }
                        RNA_PROP_END;
index d8efb972ce9a15161876d73dc6c103dc73b598e7..6ac681104d0fc555a4d2e9676211a3b33cf414a8 100644 (file)
@@ -883,7 +883,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti
        }
        
        /* extra feature allows more alpha blending */
-       if (but->type == LABEL && but->a1 == 1.0f) alpha *= but->a2;
+       if (ELEM(but->type, LABEL, LISTLABEL) && but->a1 == 1.0f)
+               alpha *= but->a2;
        
        glEnable(GL_BLEND);
        
@@ -1731,19 +1732,6 @@ static void widget_state_numslider(uiWidgetType *wt, int state)
        }
 }
 
-/* labels use theme colors for text */
-static void widget_state_label(uiWidgetType *wt, int state)
-{
-       /* call this for option button */
-       widget_state(wt, state);
-
-       if (state & UI_SELECT)
-               UI_GetThemeColor3ubv(TH_TEXT_HI, (unsigned char *)wt->wcol.text);
-       else
-               UI_GetThemeColor3ubv(TH_TEXT, (unsigned char *)wt->wcol.text);
-       
-}
-
 /* labels use theme colors for text */
 static void widget_state_option_menu(uiWidgetType *wt, int state)
 {
@@ -2980,9 +2968,11 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
                case UI_WTYPE_REGULAR:
                        break;
 
+               case UI_WTYPE_LISTLABEL:
+                       wt.wcol_theme = &btheme->tui.wcol_list_item;
+                       /* No break, we use usual label code too. */
                case UI_WTYPE_LABEL:
                        wt.draw = NULL;
-                       wt.state = widget_state_label;
                        break;
                        
                case UI_WTYPE_TOGGLE:
@@ -3230,6 +3220,11 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
                                }
                                break;
                                
+                       case LISTLABEL:
+                               wt = widget_type(UI_WTYPE_LISTLABEL);
+                               fstyle = &style->widgetlabel;
+                               break;
+
                        case SEPR:
                                break;