diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2013-11-23 21:43:23 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2013-11-23 21:43:23 +0400 |
commit | f842ce82e6c92b156c0036cbefb4e4d97cd1d498 (patch) | |
tree | a0067336e631b8ac7cfa59a43bc7585b1f1ac7f5 /source/blender | |
parent | d846c9a3b75c3d6f20bc7ab7d2da6cdd18bbbef2 (diff) |
UI List: ctrl click on names in list can be used for renaming.
Summary:
More information here:
http://lists.blender.org/pipermail/bf-committers/2013-November/042113.html
Reviewers: brecht
Reviewed By: brecht
CC: mont29
Differential Revision: http://developer.blender.org/D8
Diffstat (limited to 'source/blender')
7 files changed, 71 insertions, 46 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 0c37d35a93b..0786f266735 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -432,7 +432,6 @@ void uiButSetDragValue(uiBut *but); void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale); int UI_but_active_drop_name(struct bContext *C); -struct uiBut *ui_but_find_mouse_over(struct ARegion *ar, int x, int y); void uiButSetFlag(uiBut *but, int flag); void uiButClearFlag(uiBut *but, int flag); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index db53809c7c4..c871fdcf746 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -235,8 +235,10 @@ typedef struct uiAfterFunc { +static bool ui_is_but_interactive(uiBut *but, const bool ctrl); static bool ui_but_contains_pt(uiBut *but, int mx, int my); static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y); +static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event, int x, int y); static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state); static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *userdata); static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type); @@ -728,7 +730,9 @@ static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set ui_window_to_block_fl(ar, block, &xy_b_block[0], &xy_b_block[1]); for (but = block->buttons.first; but; but = but->next) { - if (ui_is_but_interactive(but)) { + /* Note: ctrl is always true here because (at least for now) we always want to consider text control + * in this case, even when not embossed. */ + if (ui_is_but_interactive(but, true)) { if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) { /* execute the button */ @@ -754,7 +758,7 @@ static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set return change; } -static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const int xy_input[2]) +static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const wmEvent *event) { ARegion *ar = CTX_wm_region(C); bool do_draw = false; @@ -768,7 +772,7 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const */ if (drag_info->is_init == false) { /* first store the buttons original coords */ - uiBut *but = ui_but_find_mouse_over(ar, xy_input[0], xy_input[1]); + uiBut *but = ui_but_find_mouse_over(ar, event, 0, 0); if (but) { if (but->flag & UI_BUT_DRAG_LOCK) { @@ -796,8 +800,8 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const /* done with axis locking */ - xy[0] = (drag_info->xy_lock[0] == false) ? xy_input[0] : drag_info->xy_last[0]; - xy[1] = (drag_info->xy_lock[1] == false) ? xy_input[1] : drag_info->xy_last[1]; + xy[0] = (drag_info->xy_lock[0] == false) ? event->x : drag_info->xy_last[0]; + xy[1] = (drag_info->xy_lock[1] == false) ? event->y : drag_info->xy_last[1]; /* touch all buttons between last mouse coord and this one */ @@ -831,7 +835,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void } case MOUSEMOVE: { - ui_drag_toggle_set(C, drag_info, &event->x); + ui_drag_toggle_set(C, drag_info, event); break; } } @@ -839,7 +843,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void if (done) { wmWindow *win = CTX_wm_window(C); ARegion *ar = CTX_wm_region(C); - uiBut *but = ui_but_find_mouse_over(ar, drag_info->xy_init[0], drag_info->xy_init[1]); + uiBut *but = ui_but_find_mouse_over(ar, NULL, drag_info->xy_init[0], drag_info->xy_init[1]); if (but) { ui_apply_undo(but); @@ -5883,8 +5887,9 @@ static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y) /** * Can we mouse over the button or is it hidden/disabled/layout. + * Note: ctrl is kind of a hack currently, so that non-embossed TEX button behaves as a label when ctrl is not pressed. */ -bool ui_is_but_interactive(uiBut *but) +static bool ui_is_but_interactive(uiBut *but, const bool ctrl) { /* note, LABEL is included for highlights, this allows drags */ if ((but->type == LABEL) && but->dragpoin == NULL) @@ -5895,6 +5900,8 @@ bool ui_is_but_interactive(uiBut *but) return false; if (but->flag & UI_SCROLLED) return false; + if ((but->type == TEX) && (but->dt & UI_EMBOSSN) && !ctrl) + return false; return true; } @@ -5906,11 +5913,19 @@ bool ui_is_but_search_unlink_visible(uiBut *but) (but->drawstr[0] != '\0')); } -uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y) +/* x and y are only used in case event is NULL... */ +static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event, int x, int y) { uiBlock *block; uiBut *but, *butover = NULL; int mx, my; + bool ctrl = true; + + if (event) { + x = event->x; + y = event->y; + ctrl = event->ctrl; + } // if (!win->active) // return NULL; @@ -5923,7 +5938,7 @@ uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y) ui_window_to_block(ar, block, &mx, &my); for (but = block->buttons.first; but; but = but->next) { - if (ui_is_but_interactive(but)) { + if (ui_is_but_interactive(but, ctrl)) { if (ui_but_contains_pt(but, mx, my)) { butover = but; } @@ -6493,7 +6508,7 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *ar) uiBut *but; if (event->type == MOUSEMOVE) { - but = ui_but_find_mouse_over(ar, event->x, event->y); + but = ui_but_find_mouse_over(ar, event, 0, 0); if (but) { button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER); } @@ -6585,7 +6600,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) data->cancel = TRUE; button_activate_state(C, but, BUTTON_STATE_EXIT); } - else if (ui_but_find_mouse_over(ar, event->x, event->y) != but) { + else if (ui_but_find_mouse_over(ar, event, 0, 0) != but) { data->cancel = TRUE; button_activate_state(C, but, BUTTON_STATE_EXIT); } @@ -6697,7 +6712,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) } } - bt = ui_but_find_mouse_over(ar, event->x, event->y); + bt = ui_but_find_mouse_over(ar, event, 0, 0); if (bt && bt->active != data) { if (but->type != COLOR) { /* exception */ @@ -6737,7 +6752,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) * it stays active while the mouse is over it. * This avoids adding mousemoves, see: [#33466] */ if (ELEM(state_orig, BUTTON_STATE_INIT, BUTTON_STATE_HIGHLIGHT)) { - if (ui_but_find_mouse_over(ar, event->x, event->y) == but) { + if (ui_but_find_mouse_over(ar, event, 0, 0) == but) { button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER); } } @@ -6778,7 +6793,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) break; } } - if (dragbut && dragbut == ui_but_find_mouse_over(ar, event->x, event->y)) { + if (dragbut && dragbut == ui_but_find_mouse_over(ar, event, 0, 0)) { is_over_dragbut = true; } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 30d8535e471..9287385a329 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -54,6 +54,9 @@ struct ImBuf; /* ****************** general defines ************** */ +#define RNA_NO_INDEX -1 +#define RNA_ENUM_VALUE -2 + /* visual types for drawing */ /* for time being separated from functional types */ typedef enum { @@ -403,7 +406,6 @@ extern bool ui_is_but_bool(uiBut *but); extern bool ui_is_but_unit(uiBut *but); extern bool ui_is_but_rna_valid(uiBut *but); extern bool ui_is_but_utf8(uiBut *but); -extern bool ui_is_but_interactive(uiBut *but); extern bool ui_is_but_search_unlink_visible(uiBut *but); extern int ui_is_but_push_ex(uiBut *but, double *value); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b85c30b8710..346a54cf4eb 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -64,10 +64,6 @@ /************************ Structs and Defines *************************/ -#define RNA_NO_INDEX -1 -#define RNA_ENUM_VALUE -2 - - // #define USE_OP_RESET_BUT // we may want to make this optional, disable for now. #define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \ @@ -632,13 +628,11 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n if (subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) { uiBlockSetCurLayout(block, uiLayoutRow(sub, TRUE)); - uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w - UI_UNIT_X, h); + but = uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w - UI_UNIT_X, h); /* BUTTONS_OT_file_browse calls uiFileBrowseContextProperty */ - but = uiDefIconButO(block, BUT, subtype == PROP_DIRPATH ? - "BUTTONS_OT_directory_browse" : - "BUTTONS_OT_file_browse", - WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL); + uiDefIconButO(block, BUT, subtype == PROP_DIRPATH ? "BUTTONS_OT_directory_browse" : "BUTTONS_OT_file_browse", + WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL); } else if (flag & UI_ITEM_R_EVENT) { uiDefButR_prop(block, KEYEVT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL); @@ -1142,7 +1136,7 @@ static void ui_item_rna_size(uiLayout *layout, const char *name, int icon, Point void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int flag, const char *name, int icon) { uiBlock *block = layout->root->block; - uiBut *but; + uiBut *but = NULL; PropertyType type; char namestr[UI_MAX_NAME_STR]; int len, is_array, w, h, slider, toggle, expand, icon_only, no_bg; @@ -1231,7 +1225,12 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index if (layout->redalert) uiButSetFlag(but, UI_BUT_REDALERT); } - + + /* Mark non-embossed textfields inside a listbox. */ + if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == TEX) && (but->dt & UI_EMBOSSN)) { + uiButSetFlag(but, UI_BUT_LIST_ITEM); + } + if (no_bg) uiBlockSetEmboss(block, UI_EMBOSS); } @@ -2452,8 +2451,9 @@ 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. */ +/* Check all buttons defined in this layout, and set any button flagged as UI_BUT_LIST_ITEM as active/selected. + * Needed to handle correctly text colors of active (selected) list item. + */ void ui_layout_list_set_labels_active(uiLayout *layout) { uiButtonItem *bitem; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 1d1b7dbb835..8926a16481d 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2475,11 +2475,7 @@ static void uilist_draw_item_default(struct uiList *ui_list, struct bContext *UN struct PointerRNA *UNUSED(active_dataptr), const char *UNUSED(active_propname), int UNUSED(index), int UNUSED(flt_flag)) { - char *namebuf; - const char *name; - - namebuf = RNA_struct_name_get_alloc(itemptr, NULL, 0, NULL); - name = (namebuf) ? namebuf : ""; + PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type); /* Simplest one! */ switch (ui_list->layout_type) { @@ -2489,14 +2485,14 @@ static void uilist_draw_item_default(struct uiList *ui_list, struct bContext *UN case UILST_LAYOUT_DEFAULT: case UILST_LAYOUT_COMPACT: default: - uiItemL(layout, name, icon); + if (nameprop) { + uiItemFullR(layout, itemptr, nameprop, RNA_NO_INDEX, 0, UI_ITEM_R_NO_BG, "", icon); + } + else { + uiItemL(layout, "", icon); + } break; } - - /* free name */ - if (namebuf) { - MEM_freeN(namebuf); - } } static void uilist_draw_filter_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout) @@ -2713,8 +2709,8 @@ static void prepare_list(uiList *ui_list, int len, int activei, int rows, int ma } void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id, - PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, - const char *active_propname, int rows, int maxrows, int layout_type, int columns) + PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, + int rows, int maxrows, int layout_type, int columns) { uiListType *ui_list_type; uiList *ui_list = NULL; @@ -2950,7 +2946,6 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co draw_item(ui_list, C, sub, dataptr, itemptr, icon, active_dataptr, active_propname, org_i, flt_flag); - /* If we are "drawing" active item, set all labels as active. */ if (i == activei) { ui_layout_list_set_labels_active(sub); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 3058888c012..c85ecd1b5a1 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1656,8 +1656,14 @@ static void widget_state(uiWidgetType *wt, int state) { uiWidgetStateColors *wcol_state = wt->wcol_state; + if ((state & UI_BUT_LIST_ITEM) && !(state & UI_TEXTINPUT)) { + /* Override default widget's colors. */ + bTheme *btheme = UI_GetTheme(); + wt->wcol_theme = &btheme->tui.wcol_list_item; + } + wt->wcol = *(wt->wcol_theme); - + if (state & UI_SELECT) { copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index d79a40aa615..dcf51cdceaf 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -97,7 +97,7 @@ static const char *rna_translate_ui_text(const char *text, const char *text_ctxt static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, const char *text_ctxt, int translate, int icon, int expand, int slider, int toggle, int icon_only, int event, - int full_event, int emboss, int index) + int full_event, int emboss, int index, int icon_value) { PropertyRNA *prop = RNA_struct_find_property(ptr, propname); int flag = 0; @@ -107,6 +107,10 @@ static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, return; } + if (icon_value && !icon) { + icon = icon_value; + } + /* Get translated name (label). */ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); @@ -511,6 +515,10 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_int(func, "index", -1, -2, INT_MAX, "", "The index of this button, when set a single member of an array can be accessed, " "when set to -1 all array members are used", -2, INT_MAX); /* RNA_NO_INDEX == -1 */ + parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED); + RNA_def_property_ui_text(parm, "Icon Value", + "Override automatic icon of the item " + "(use it e.g. with custom material icons returned by icon()...)"); func = RNA_def_function(srna, "props_enum", "uiItemsEnumR"); api_ui_item_rna_common(func); |