Usability fix:
Blender's data link button (typically with menu and searching options) now has a X icon to clear its contents. Before you had to click, delete text, enter. For example: - Object Parent - Modifier objects or vertexgroups This fix saves each user 100 clicks per day, with 100k users that's 3 billion clicks per year!
This commit is contained in:
@@ -254,7 +254,8 @@ typedef enum {
|
||||
HISTOGRAM = (48 << 9),
|
||||
WAVEFORM = (49 << 9),
|
||||
VECTORSCOPE = (50 << 9),
|
||||
PROGRESSBAR = (51 << 9)
|
||||
PROGRESSBAR = (51 << 9),
|
||||
SEARCH_MENU_UNLINK = (52 << 9)
|
||||
} eButType;
|
||||
|
||||
#define BUTTYPE (63 << 9)
|
||||
|
||||
@@ -1605,7 +1605,7 @@ void ui_set_but_val(uiBut *but, double value)
|
||||
|
||||
int ui_get_but_string_max_length(uiBut *but)
|
||||
{
|
||||
if (ELEM(but->type, TEX, SEARCH_MENU))
|
||||
if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK))
|
||||
return but->hardmax;
|
||||
else if (but->type == IDPOIN)
|
||||
return MAX_ID_NAME - 2;
|
||||
@@ -1688,7 +1688,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
|
||||
|
||||
void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
|
||||
{
|
||||
if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
|
||||
if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
PropertyType type;
|
||||
const char *buf = NULL;
|
||||
int buf_len;
|
||||
@@ -1742,7 +1742,7 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
|
||||
BLI_strncpy(str, but->poin, maxlen);
|
||||
return;
|
||||
}
|
||||
else if (but->type == SEARCH_MENU) {
|
||||
else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
/* string */
|
||||
BLI_strncpy(str, but->poin, maxlen);
|
||||
return;
|
||||
@@ -1833,7 +1833,7 @@ int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double
|
||||
|
||||
int ui_set_but_string(bContext *C, uiBut *but, const char *str)
|
||||
{
|
||||
if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
|
||||
if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
|
||||
PropertyType type;
|
||||
|
||||
@@ -1890,7 +1890,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if (but->type == SEARCH_MENU) {
|
||||
else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
/* string */
|
||||
BLI_strncpy(but->poin, str, but->hardmax);
|
||||
return 1;
|
||||
@@ -2360,6 +2360,7 @@ void ui_check_but(uiBut *but)
|
||||
case IDPOIN:
|
||||
case TEX:
|
||||
case SEARCH_MENU:
|
||||
case SEARCH_MENU_UNLINK:
|
||||
if (!but->editstr) {
|
||||
char str[UI_MAX_DRAW_STR];
|
||||
|
||||
@@ -2741,7 +2742,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
|
||||
}
|
||||
|
||||
if ((block->flag & UI_BLOCK_LOOP) ||
|
||||
ELEM8(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR))
|
||||
ELEM9(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK))
|
||||
{
|
||||
but->flag |= (UI_TEXT_LEFT | UI_ICON_LEFT);
|
||||
}
|
||||
|
||||
@@ -1062,6 +1062,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
|
||||
ui_apply_but_BUT(C, but, data);
|
||||
break;
|
||||
case TEX:
|
||||
case SEARCH_MENU_UNLINK:
|
||||
case SEARCH_MENU:
|
||||
ui_apply_but_TEX(C, but, data);
|
||||
break;
|
||||
@@ -1169,7 +1170,7 @@ static void ui_but_drop(bContext *C, wmEvent *event, uiBut *but, uiHandleButtonD
|
||||
for (wmd = drags->first; wmd; wmd = wmd->next) {
|
||||
if (wmd->type == WM_DRAG_ID) {
|
||||
/* align these types with UI_but_active_drop_name */
|
||||
if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
|
||||
if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
ID *id = (ID *)wmd->poin;
|
||||
|
||||
if (but->poin == NULL && but->rnapoin.data == NULL) {}
|
||||
@@ -1270,7 +1271,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
|
||||
}
|
||||
|
||||
/* text/string and ID data */
|
||||
else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
|
||||
else if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
uiHandleButtonData *active_data = but->active;
|
||||
|
||||
if (but->poin == NULL && but->rnapoin.data == NULL) {
|
||||
@@ -1289,7 +1290,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
|
||||
if (ui_is_but_utf8(but)) BLI_strncpy_utf8(active_data->str, buf, active_data->maxlen);
|
||||
else BLI_strncpy(active_data->str, buf, active_data->maxlen);
|
||||
|
||||
if (but->type == SEARCH_MENU) {
|
||||
if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
/* else uiSearchboxData.active member is not updated [#26856] */
|
||||
ui_searchbox_update(C, data->searchbox, but, 1);
|
||||
}
|
||||
@@ -1436,7 +1437,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
|
||||
/* XXX solve generic */
|
||||
if (but->type == NUM || but->type == NUMSLI)
|
||||
startx += (int)(0.5f * (BLI_rctf_size_y(&but->rect)));
|
||||
else if (ELEM(but->type, TEX, SEARCH_MENU)) {
|
||||
else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
startx += 5;
|
||||
if (but->flag & UI_HAS_ICON)
|
||||
startx += UI_DPI_ICON_SIZE;
|
||||
@@ -1816,7 +1817,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
|
||||
but->selend = len;
|
||||
|
||||
/* optional searchbox */
|
||||
if (but->type == SEARCH_MENU) {
|
||||
if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
data->searchbox = ui_searchbox_create(C, data->region, but);
|
||||
ui_searchbox_update(C, data->searchbox, but, 1); /* 1 = reset */
|
||||
}
|
||||
@@ -1862,7 +1863,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
|
||||
return;
|
||||
|
||||
for (but = actbut->next; but; but = but->next) {
|
||||
if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
|
||||
if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
if (!(but->flag & UI_BUT_DISABLED)) {
|
||||
data->postbut = but;
|
||||
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
|
||||
@@ -1871,7 +1872,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
|
||||
}
|
||||
}
|
||||
for (but = block->buttons.first; but != actbut; but = but->next) {
|
||||
if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
|
||||
if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
if (!(but->flag & UI_BUT_DISABLED)) {
|
||||
data->postbut = but;
|
||||
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
|
||||
@@ -1890,7 +1891,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
|
||||
return;
|
||||
|
||||
for (but = actbut->prev; but; but = but->prev) {
|
||||
if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
|
||||
if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
if (!(but->flag & UI_BUT_DISABLED)) {
|
||||
data->postbut = but;
|
||||
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
|
||||
@@ -1899,7 +1900,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
|
||||
}
|
||||
}
|
||||
for (but = block->buttons.last; but != actbut; but = but->prev) {
|
||||
if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
|
||||
if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
if (!(but->flag & UI_BUT_DISABLED)) {
|
||||
data->postbut = but;
|
||||
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
|
||||
@@ -2430,6 +2431,34 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
|
||||
{
|
||||
/* unlink icon is on right */
|
||||
if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
rcti rect;
|
||||
int x = event->x, y = event->y;
|
||||
|
||||
ui_window_to_block(ar, but->block, &x, &y);
|
||||
|
||||
BLI_rcti_rctf_copy(&rect, &but->rect);
|
||||
|
||||
rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
|
||||
if ( BLI_rcti_isect_pt(&rect, x, y) ) {
|
||||
/* most likely NULL, but let's check, and give it temp zero string */
|
||||
if (data->str == NULL)
|
||||
data->str = MEM_callocN(16, "temp str");
|
||||
data->str[0] = 0;
|
||||
|
||||
ui_apply_but_TEX(C, but, data);
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
return ui_do_but_TEX(C, block, but, data, event);
|
||||
}
|
||||
|
||||
static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
|
||||
{
|
||||
if (data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||
@@ -5138,6 +5167,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
|
||||
case SEARCH_MENU:
|
||||
retval = ui_do_but_TEX(C, block, but, data, event);
|
||||
break;
|
||||
case SEARCH_MENU_UNLINK:
|
||||
retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
|
||||
break;
|
||||
case MENU:
|
||||
case ICONROW:
|
||||
case ICONTEXTROW:
|
||||
@@ -5251,7 +5283,7 @@ int UI_but_active_drop_name(bContext *C)
|
||||
uiBut *but = ui_but_find_activated(ar);
|
||||
|
||||
if (but) {
|
||||
if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU))
|
||||
if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK))
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5577,7 +5609,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
|
||||
copy_v2_fl(data->ungrab_mval, FLT_MAX);
|
||||
#endif
|
||||
|
||||
if (ELEM(but->type, BUT_CURVE, SEARCH_MENU)) {
|
||||
if (ELEM3(but->type, BUT_CURVE, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
/* XXX curve is temp */
|
||||
}
|
||||
else {
|
||||
@@ -6440,7 +6472,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
|
||||
|
||||
/* if there's an active modal button, don't check events or outside, except for search menu */
|
||||
but = ui_but_find_activated(ar);
|
||||
if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU) {
|
||||
if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK) {
|
||||
/* if a button is activated modal, always reset the start mouse
|
||||
* position of the towards mechanism to avoid loosing focus,
|
||||
* and don't handle events */
|
||||
@@ -6466,7 +6498,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
|
||||
if (block->block_event_func && block->block_event_func(C, block, event)) {
|
||||
/* pass */
|
||||
} /* events not for active search menu button */
|
||||
else if (but == NULL || but->type != SEARCH_MENU) {
|
||||
else if (but == NULL || (but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK)) {
|
||||
switch (event->type) {
|
||||
|
||||
|
||||
|
||||
@@ -1386,7 +1386,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
|
||||
|
||||
/* turn button into search button */
|
||||
if (searchprop) {
|
||||
but->type = SEARCH_MENU;
|
||||
but->type = SEARCH_MENU_UNLINK;
|
||||
but->hardmax = MAX2(but->hardmax, 256.0f);
|
||||
but->rnasearchpoin = *searchptr;
|
||||
but->rnasearchprop = searchprop;
|
||||
|
||||
@@ -466,7 +466,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
|
||||
data->totline++;
|
||||
}
|
||||
|
||||
if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
|
||||
if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
/* full string */
|
||||
ui_get_but_string(but, buf, sizeof(buf));
|
||||
if (buf[0]) {
|
||||
|
||||
@@ -897,7 +897,7 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti
|
||||
}
|
||||
}
|
||||
else if (but->block->flag & UI_BLOCK_LOOP) {
|
||||
if (but->type == SEARCH_MENU)
|
||||
if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK))
|
||||
xs = rect->xmin + 4.0f * ofs;
|
||||
else
|
||||
xs = rect->xmin + ofs;
|
||||
@@ -1283,7 +1283,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
|
||||
else if (ELEM4(but->type, NUM, NUMABS, NUMSLI, SLI)) {
|
||||
ui_text_clip_right_label(fstyle, but, rect);
|
||||
}
|
||||
else if (ELEM(but->type, TEX, SEARCH_MENU)) {
|
||||
else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
|
||||
ui_text_clip_left(fstyle, but, rect);
|
||||
}
|
||||
else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) {
|
||||
@@ -1331,6 +1331,14 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
|
||||
else if ((but->flag & UI_TEXT_LEFT)) {
|
||||
rect->xmin += (0.4f * U.widget_unit) / but->block->aspect;
|
||||
}
|
||||
|
||||
/* unlink icon for this button type */
|
||||
if (but->type == SEARCH_MENU_UNLINK && but->drawstr[0]) {
|
||||
rcti temp = *rect;
|
||||
|
||||
temp.xmin = temp.xmax - BLI_rcti_size_y(rect);
|
||||
widget_draw_icon(but, ICON_X, 1.0f, &temp);
|
||||
}
|
||||
|
||||
/* always draw text for textbutton cursor */
|
||||
widget_draw_text(fstyle, wcol, but, rect);
|
||||
@@ -3215,7 +3223,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
|
||||
case TEX:
|
||||
wt = widget_type(UI_WTYPE_NAME);
|
||||
break;
|
||||
|
||||
|
||||
case SEARCH_MENU_UNLINK:
|
||||
case SEARCH_MENU:
|
||||
wt = widget_type(UI_WTYPE_NAME);
|
||||
if (but->block->flag & UI_BLOCK_LOOP)
|
||||
|
||||
Reference in New Issue
Block a user