Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/interface/interface_handlers.c')
-rw-r--r--source/blender/editors/interface/interface_handlers.c1072
1 files changed, 751 insertions, 321 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b80025e0d77..b34f4c9653f 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -44,6 +44,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -80,10 +81,13 @@
/* place the mouse at the scaled down location when un-grabbing */
#define USE_CONT_MOUSE_CORRECT
+/* support dragging toggle buttons */
+#define USE_DRAG_TOGGLE
/* proto */
static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to);
static void ui_add_link(bContext *C, uiBut *from, uiBut *to);
+static int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, const wmEvent *event);
/***************** structs and defines ****************/
@@ -149,6 +153,7 @@ typedef struct uiHandleButtonData {
int maxlen, selextend, selstartx;
/* number editing / dragging */
+ /* coords are Window/uiBlock relative (depends on the button) */
int draglastx, draglasty;
int dragstartx, dragstarty;
int dragchange, draglock, dragsel;
@@ -213,12 +218,45 @@ typedef struct uiAfterFunc {
static int ui_but_contains_pt(uiBut *but, int mx, int my);
static int ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y);
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
-static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata);
+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);
static void button_timers_tooltip_remove(bContext *C, uiBut *but);
/* ******************** menu navigation helpers ************** */
+/* assumes event type is MOUSEPAN */
+void ui_pan_to_scroll(const wmEvent *event, int *type, int *val)
+{
+ static int lastdy = 0;
+ int dy = event->prevy - event->y;
+
+ /* This event should be originally from event->type,
+ * converting wrong event into wheel is bad, see [#33803] */
+ BLI_assert(*type == MOUSEPAN);
+
+ /* sign differs, reset */
+ if ((dy > 0 && lastdy < 0) || (dy < 0 && lastdy > 0)) {
+ lastdy = dy;
+ }
+ else {
+ lastdy += dy;
+
+ if (ABS(lastdy) > (int)UI_UNIT_Y) {
+ if (U.uiflag2 & USER_TRACKPAD_NATURAL)
+ dy = -dy;
+
+ *val = KM_PRESS;
+
+ if (dy > 0)
+ *type = WHEELUPMOUSE;
+ else
+ *type = WHEELDOWNMOUSE;
+
+ lastdy = 0;
+ }
+ }
+}
+
static int ui_but_editable(uiBut *but)
{
return ELEM5(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR);
@@ -266,15 +304,15 @@ static uiBut *ui_but_last(uiBlock *block)
return NULL;
}
-static int ui_is_a_warp_but(uiBut *but)
+static bool ui_is_a_warp_but(uiBut *but)
{
if (U.uiflag & USER_CONTINUOUS_MOUSE) {
- if (ELEM6(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW, HSVCUBE, BUT_CURVE)) {
- return TRUE;
+ if (ELEM7(but->type, NUM, NUMSLI, NUMABS, HSVCIRCLE, TRACKPREVIEW, HSVCUBE, BUT_CURVE)) {
+ return true;
}
}
- return FALSE;
+ return false;
}
static float ui_mouse_scale_warp_factor(const short shift)
@@ -370,9 +408,9 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
}
}
-static void ui_apply_autokey_undo(bContext *C, uiBut *but)
+/* typically call ui_apply_undo(), ui_apply_autokey() */
+static void ui_apply_undo(uiBut *but)
{
- Scene *scene = CTX_data_scene(C);
uiAfterFunc *after;
if (but->flag & UI_BUT_UNDO) {
@@ -394,9 +432,25 @@ static void ui_apply_autokey_undo(bContext *C, uiBut *but)
BLI_strncpy(after->undostr, str, sizeof(after->undostr));
BLI_addtail(&UIAfterFuncs, after);
}
+}
+
+static void ui_apply_autokey(bContext *C, uiBut *but)
+{
+ Scene *scene = CTX_data_scene(C);
/* try autokey */
ui_but_anim_autokey(C, but, scene, scene->r.cfra);
+
+ /* make a little report about what we've done! */
+ if (but->rnaprop) {
+ char *buf = WM_prop_pystring_assign(C, &but->rnapoin, but->rnaprop, but->rnaindex);
+ if (buf) {
+ BKE_report(CTX_wm_reports(C), RPT_PROPERTY, buf);
+ MEM_freeN(buf);
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
+ }
+ }
}
static void ui_apply_but_funcs_after(bContext *C)
@@ -685,7 +739,152 @@ static void ui_apply_but_CHARTAB(bContext *C, uiBut *but, uiHandleButtonData *da
/* ****************** drag drop code *********************** */
-static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event)
+#ifdef USE_DRAG_TOGGLE
+
+typedef struct uiDragToggleHandle {
+ /* init */
+ bool is_set;
+ float but_cent_start[2];
+ eButType but_type_start;
+
+ bool xy_lock[2];
+ int xy_last[2];
+} uiDragToggleHandle;
+
+static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
+ const int xy_src[2], const int xy_dst[2])
+{
+ bool change = false;
+ uiBlock *block;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ uiBut *but;
+
+ float xy_a_block[2] = {UNPACK2(xy_src)};
+ float xy_b_block[2] = {UNPACK2(xy_dst)};
+
+ ui_window_to_block_fl(ar, block, &xy_a_block[0], &xy_a_block[1]);
+ 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)) {
+ if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
+
+ /* execute the button */
+ if (ui_is_but_bool(but) && but->type == but_type_start) {
+ /* is it pressed? */
+ bool is_set_but = ui_is_but_push(but);
+ BLI_assert(ui_is_but_bool(but) == true);
+ if (is_set_but != is_set) {
+ uiButExecute(C, but);
+ change = true;
+ }
+ }
+ /* done */
+
+ }
+ }
+ }
+ }
+
+ return change;
+}
+
+static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const int xy_input[2])
+{
+ ARegion *ar = CTX_wm_region(C);
+ bool do_draw = false;
+ int xy[2];
+
+ /**
+ * Initialize Locking:
+ *
+ * Check if we need to initialize the lock axis by finding if the first
+ * button we mouse over is X or Y aligned, then lock the mouse to that axis after.
+ */
+ if (drag_info->xy_lock[0] == false && drag_info->xy_lock[1] == false) {
+ /* first store the buttons original coords */
+ uiBut *but = ui_but_find_mouse_over(ar, xy_input[0], xy_input[1]);
+ if (but) {
+ const float but_cent_new[2] = {BLI_rctf_cent_x(&but->rect),
+ BLI_rctf_cent_y(&but->rect)};
+
+ /* check if this is a different button, chances are high the button wont move about :) */
+ if (len_manhattan_v2v2(drag_info->but_cent_start, but_cent_new) > 1.0f) {
+ if (fabsf(drag_info->but_cent_start[0] - but_cent_new[0]) <
+ fabsf(drag_info->but_cent_start[1] - but_cent_new[1]))
+ {
+ drag_info->xy_lock[0] = true;
+ }
+ else {
+ drag_info->xy_lock[1] = true;
+ }
+ }
+ }
+ }
+ /* 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];
+
+
+ /* touch all buttons between last mouse coord and this one */
+ do_draw = ui_drag_toggle_set_xy_xy(C, ar, drag_info->is_set, drag_info->but_type_start, drag_info->xy_last, xy);
+
+ if (do_draw) {
+ ED_region_tag_redraw(ar);
+ }
+
+ copy_v2_v2_int(drag_info->xy_last, xy);
+}
+
+static void ui_handler_region_drag_toggle_remove(bContext *UNUSED(C), void *userdata)
+{
+ uiDragToggleHandle *drag_info = userdata;
+ MEM_freeN(drag_info);
+}
+
+static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void *userdata)
+{
+ uiDragToggleHandle *drag_info = userdata;
+ bool done = false;
+
+ switch (event->type) {
+ case LEFTMOUSE:
+ {
+ if (event->val != KM_PRESS) {
+ done = true;
+ }
+ break;
+ }
+ case MOUSEMOVE:
+ {
+ ui_drag_toggle_set(C, drag_info, &event->x);
+ break;
+ }
+ }
+
+ if (done) {
+ wmWindow *win = CTX_wm_window(C);
+ WM_event_remove_ui_handler(&win->modalhandlers,
+ ui_handler_region_drag_toggle,
+ ui_handler_region_drag_toggle_remove,
+ drag_info, false);
+ ui_handler_region_drag_toggle_remove(C, drag_info);
+
+ WM_event_add_mousemove(C);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+}
+
+#endif /* USE_DRAG_TOGGLE */
+
+
+static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *event)
{
rcti rect;
int x = event->x, y = event->y;
@@ -709,20 +908,39 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event)
return BLI_rcti_isect_pt(&rect, x, y);
}
-static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
/* prevent other WM gestures to start while we try to drag */
WM_gestures_remove(C);
if (ABS(data->dragstartx - event->x) + ABS(data->dragstarty - event->y) > U.dragthreshold) {
- wmDrag *drag;
-
+
button_activate_state(C, but, BUTTON_STATE_EXIT);
data->cancel = TRUE;
-
- drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but));
- if (but->imb)
- WM_event_drag_image(drag, but->imb, but->imb_scale, BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect));
+#ifdef USE_DRAG_TOGGLE
+ if (ui_is_but_bool(but)) {
+ uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
+
+ drag_info->is_set = ui_is_but_push(but);
+ drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
+ drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
+ drag_info->but_type_start = but->type;
+ copy_v2_v2_int(drag_info->xy_last, &event->x);
+
+ WM_event_add_ui_handler(C, &data->window->modalhandlers,
+ ui_handler_region_drag_toggle,
+ ui_handler_region_drag_toggle_remove,
+ drag_info);
+ }
+ else
+#endif
+ {
+ wmDrag *drag;
+
+ drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but));
+ if (but->imb)
+ WM_event_drag_image(drag, but->imb, but->imb_scale, BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect));
+ }
return 1;
}
@@ -1026,6 +1244,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;
@@ -1051,8 +1270,6 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
case NUMSLI:
ui_apply_but_NUM(C, but, data);
break;
- case HSVSLI:
- break;
case TOG3:
ui_apply_but_TOG3(C, but, data);
break;
@@ -1125,7 +1342,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
/* ******************* drop event ******************** */
/* only call if event type is EVT_DROP */
-static void ui_but_drop(bContext *C, wmEvent *event, uiBut *but, uiHandleButtonData *data)
+static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleButtonData *data)
{
wmDrag *wmd;
ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */
@@ -1133,7 +1350,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) {}
@@ -1174,13 +1391,17 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
/* numeric value */
- if (ELEM4(but->type, NUM, NUMABS, NUMSLI, HSVSLI)) {
+ if (ELEM3(but->type, NUM, NUMABS, NUMSLI)) {
if (but->poin == NULL && but->rnapoin.data == NULL) {
/* pass */
}
else if (mode == 'c') {
- ui_get_but_string(but, buf, sizeof(buf));
+ /* Get many decimal places, then strip trailing zeros.
+ * note: too high values start to give strange results (6 or so is ok) */
+ ui_get_but_string_ex(but, buf, sizeof(buf), 6);
+ BLI_str_rstrip_float_zero(buf, '\0');
+
WM_clipboard_text_set(buf, 0);
}
else {
@@ -1197,37 +1418,44 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* RGB triple */
else if (but->type == COLOR) {
- float rgb[3];
+ float rgba[4];
if (but->poin == NULL && but->rnapoin.data == NULL) {
/* pass */
}
else if (mode == 'c') {
-
- ui_get_but_vectorf(but, rgb);
+ if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
+ rgba[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
+ else
+ rgba[3] = 1.0f;
+
+ ui_get_but_vectorf(but, rgba);
/* convert to linear color to do compatible copy between gamma and non-gamma */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
- srgb_to_linearrgb_v3_v3(rgb, rgb);
+ srgb_to_linearrgb_v3_v3(rgba, rgba);
- BLI_snprintf(buf, sizeof(buf), "[%f, %f, %f]", rgb[0], rgb[1], rgb[2]);
+ BLI_snprintf(buf, sizeof(buf), "[%f, %f, %f, %f]", rgba[0], rgba[1], rgba[2], rgba[3]);
WM_clipboard_text_set(buf, 0);
}
else {
- if (sscanf(buf, "[%f, %f, %f]", &rgb[0], &rgb[1], &rgb[2]) == 3) {
+ if (sscanf(buf, "[%f, %f, %f, %f]", &rgba[0], &rgba[1], &rgba[2], &rgba[3]) == 4) {
/* assume linear colors in buffer */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
- linearrgb_to_srgb_v3_v3(rgb, rgb);
+ linearrgb_to_srgb_v3_v3(rgba, rgba);
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- ui_set_but_vectorf(but, rgb);
+ ui_set_but_vectorf(but, rgba);
+ if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
+ RNA_property_float_set_index(&but->rnapoin, but->rnaprop, 3, rgba[3]);
+
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
}
/* 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) {
@@ -1246,7 +1474,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);
}
@@ -1372,11 +1600,11 @@ static int ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
}
/* note, but->block->aspect is used here, when drawing button style is getting scaled too */
-static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, short x)
+static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, const float x)
{
uiStyle *style = UI_GetStyle(); // XXX pass on as arg
uiFontStyle *fstyle = &style->widget;
- int startx = but->rect.xmin;
+ float startx = but->rect.xmin;
char *origstr, password_str[UI_MAX_DRAW_STR];
uiStyleFontSet(fstyle);
@@ -1386,24 +1614,27 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
ui_button_text_password_hide(password_str, but, FALSE);
- origstr = MEM_callocN(sizeof(char) * data->maxlen, "ui_textedit origstr");
+ origstr = MEM_mallocN(sizeof(char) * data->maxlen, "ui_textedit origstr");
BLI_strncpy(origstr, but->drawstr, data->maxlen);
- /* XXX solve generic */
- if (but->type == NUM || but->type == NUMSLI)
+ /* XXX solve generic, see: #widget_draw_text_icon */
+ 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)) {
- startx += 5;
- if (but->flag & UI_HAS_ICON)
+ }
+ else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (but->flag & UI_HAS_ICON) {
startx += UI_DPI_ICON_SIZE;
+ }
+ /* but this extra .05 makes clicks inbetween characters feel nicer */
+ startx += ((UI_TEXT_MARGIN_X + 0.05f) * U.widget_unit);
}
/* mouse dragged outside the widget to the left */
- if (x < startx && but->ofs > 0) {
+ if (x < startx) {
int i = but->ofs;
- origstr[but->ofs] = 0;
+ origstr[but->ofs] = '\0';
while (i > 0) {
if (BLI_str_cursor_step_prev_utf8(origstr, but->ofs, &i)) {
@@ -1419,21 +1650,18 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
but->ofs = i;
but->pos = but->ofs;
}
- /* mouse inside the widget */
- else if (x >= startx) {
+ /* mouse inside the widget, mouse coords mapped in widget space */
+ else { /* (x >= startx) */
int pos_i;
/* keep track of previous distance from the cursor to the char */
float cdist, cdist_prev = 0.0f;
short pos_prev;
-
- const float aspect_sqrt = sqrtf(but->block->aspect);
but->pos = pos_prev = strlen(origstr) - but->ofs;
- while (TRUE) {
- /* XXX does not take zoom level into account */
- cdist = startx + aspect_sqrt * BLF_width(fstyle->uifont_id, origstr + but->ofs);
+ while (true) {
+ cdist = startx + BLF_width(fstyle->uifont_id, origstr + but->ofs);
/* check if position is found */
if (cdist < x) {
@@ -1469,7 +1697,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
MEM_freeN(origstr);
}
-static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, short x)
+static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, const float x)
{
if (x > data->selstartx) data->selextend = EXTEND_RIGHT;
else if (x < data->selstartx) data->selextend = EXTEND_LEFT;
@@ -1556,7 +1784,7 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, strCursorJump
}
else {
int pos_i = but->pos;
- BLI_str_cursor_step_utf8(str, len, &pos_i, direction, jump);
+ BLI_str_cursor_step_utf8(str, len, &pos_i, direction, jump, true);
but->pos = pos_i;
if (select) {
@@ -1625,7 +1853,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
else if (but->pos >= 0 && but->pos < len) {
int pos = but->pos;
int step;
- BLI_str_cursor_step_utf8(str, len, &pos, direction, jump);
+ BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true);
step = pos - but->pos;
memmove(&str[but->pos], &str[but->pos + step], (len + 1) - but->pos);
changed = 1;
@@ -1640,7 +1868,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
int pos = but->pos;
int step;
- BLI_str_cursor_step_utf8(str, len, &pos, direction, jump);
+ BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true);
step = but->pos - pos;
memmove(&str[but->pos - step], &str[but->pos], (len + 1) - but->pos);
but->pos -= step;
@@ -1674,10 +1902,11 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste
{
char buf[UI_MAX_DRAW_STR] = {0};
char *str, *p, *pbuf;
- int len, x, i, changed = 0;
+ int x, changed = 0;
+ int str_len, buf_len;
str = data->str;
- len = strlen(str);
+ str_len = strlen(str);
/* paste */
if (paste) {
@@ -1687,28 +1916,28 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste
if (p && p[0]) {
unsigned int y;
- i = 0;
- while (*p && *p != '\r' && *p != '\n' && i < UI_MAX_DRAW_STR - 1) {
- buf[i++] = *p;
+ buf_len = 0;
+ while (*p && *p != '\r' && *p != '\n' && buf_len < UI_MAX_DRAW_STR - 1) {
+ buf[buf_len++] = *p;
p++;
}
- buf[i] = 0;
+ buf[buf_len] = 0;
/* paste over the current selection */
if ((but->selend - but->selsta) > 0) {
ui_textedit_delete_selection(but, data);
- len = strlen(str);
+ str_len = strlen(str);
}
- for (y = 0; y < strlen(buf); y++) {
+ for (y = 0; y < buf_len; y++) {
/* add contents of buffer */
- if (len + 1 < data->maxlen) {
+ if (str_len + 1 < data->maxlen) {
for (x = data->maxlen; x > but->pos; x--)
str[x] = str[x - 1];
str[but->pos] = buf[y];
but->pos++;
- len++;
- str[len] = '\0';
+ str_len++;
+ str[str_len] = '\0';
}
}
@@ -1754,6 +1983,10 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
data->str = MEM_callocN(sizeof(char) * data->maxlen + 1, "textedit str");
ui_get_but_string(but, data->str, data->maxlen);
+ if (ui_is_but_float(but) && !ui_is_but_unit(but)) {
+ BLI_str_rstrip_float_zero(data->str, '\0');
+ }
+
if (ELEM3(but->type, NUM, NUMABS, NUMSLI)) {
ui_convert_to_unit_alt_name(but, data->str, data->maxlen);
}
@@ -1772,7 +2005,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 */
}
@@ -1818,7 +2051,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 (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1827,7 +2060,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 (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1846,7 +2079,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 (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1855,7 +2088,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 (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1866,7 +2099,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
-static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my, changed = 0, inbox = 0, update = 0, retval = WM_UI_HANDLER_CONTINUE;
@@ -1874,6 +2107,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
case MOUSEMOVE:
+ case MOUSEPAN:
if (data->searchbox)
ui_searchbox_event(C, data->searchbox, but, event);
@@ -2057,7 +2291,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
ED_region_tag_redraw(data->region);
}
-static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my, retval = WM_UI_HANDLER_CONTINUE;
@@ -2096,7 +2330,7 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
data->coba = (ColorBand *)but->poin;
but->editcoba = data->coba;
}
- else if (ELEM3(but->type, BUT_NORMAL, HSVCUBE, HSVCIRCLE)) {
+ else if (ELEM4(but->type, BUT_NORMAL, HSVCUBE, HSVCIRCLE, COLOR)) {
ui_get_but_vectorf(but, data->origvec);
copy_v3_v3(data->vec, data->origvec);
but->editvec = data->vec;
@@ -2246,7 +2480,7 @@ int ui_button_open_menu_direction(uiBut *but)
/* ***************** events for different button types *************** */
-static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
@@ -2274,7 +2508,7 @@ static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEv
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
@@ -2335,7 +2569,7 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
@@ -2360,7 +2594,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, w
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
@@ -2385,8 +2619,54 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const 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, const wmEvent *event)
{
+#ifdef USE_DRAG_TOGGLE
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_is_but_bool(but)) {
+ data->togdual = event->ctrl;
+ data->togonly = !event->shift;
+ ui_apply_button(C, but->block, but, data, true);
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_WAIT_DRAG) {
+ /* note: the 'BUTTON_STATE_WAIT_DRAG' part of 'ui_do_but_EXIT' could be refactored into its own function */
+ data->applied = false;
+ return ui_do_but_EXIT(C, but, data, event);
+ }
+#endif
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
data->togdual = event->ctrl;
@@ -2398,7 +2678,7 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEv
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
@@ -2415,7 +2695,15 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
return WM_UI_HANDLER_CONTINUE;
}
}
-
+#ifdef USE_DRAG_TOGGLE
+ if (event->type == LEFTMOUSE && ui_is_but_bool(but)) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_CONTINUE;
+ }
+#endif
+
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
int ret = WM_UI_HANDLER_BREAK;
/* XXX (a bit ugly) Special case handling for filebrowser drag button */
@@ -2519,6 +2807,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
{
float deler, tempf, softmin, softmax, softrange;
int lvalue, temp, changed = 0;
+ const bool is_float = ui_is_but_float(but);
if (mx == data->draglastx)
return changed;
@@ -2540,7 +2829,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
if (ui_is_a_warp_but(but)) {
/* Mouse location isn't screen clamped to the screen so use a linear mapping
* 2px == 1-int, or 1px == 1-ClickStep */
- if (ui_is_but_float(but)) {
+ if (is_float) {
fac *= 0.01f * but->a1;
tempf = (float)data->startvalue + ((float)(mx - data->dragstartx) * fac);
tempf = ui_numedit_apply_snapf(but, tempf, softmin, softmax, softrange, snap);
@@ -2597,21 +2886,21 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
else {
/* Use a non-linear mapping of the mouse drag especially for large floats (normal behavior) */
deler = 500;
- if (!ui_is_but_float(but)) {
+ if (!is_float) {
/* prevent large ranges from getting too out of control */
- if (softrange > 600) deler = powf(softrange, 0.75);
- else if (softrange < 100) deler = 200.0;
+ if (softrange > 600) deler = powf(softrange, 0.75f);
else if (softrange < 25) deler = 50.0;
+ else if (softrange < 100) deler = 100.0;
}
deler /= fac;
- if (softrange > 11) {
+ if ((is_float == true) && (softrange > 11)) {
/* non linear change in mouse input- good for high precicsion */
- data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(data->dragstartx - mx) * 0.002f);
+ data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(mx - data->dragstartx) / 500.0f);
}
- else if (softrange > 129) { /* only scale large int buttons */
+ else if ((is_float == false) && (softrange > 129)) { /* only scale large int buttons */
/* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
- data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(data->dragstartx - mx) * 0.004f);
+ data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(mx - data->dragstartx) / 250.0f);
}
else {
/*no scaling */
@@ -2623,7 +2912,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
tempf = (softmin + data->dragf * softrange);
- if (!ui_is_but_float(but)) {
+ if (!is_float) {
temp = floorf(tempf + 0.5f);
temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
@@ -2655,7 +2944,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
return changed;
}
-static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my; /* mouse location scaled to fit the UI */
int screen_mx, screen_my; /* mouse location kept at screen pixel coords */
@@ -2668,12 +2957,20 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_window_to_block(data->region, block, &mx, &my);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ int type = event->type, val = event->val;
+
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+ }
+
/* XXX hardcoded keymap check.... */
- if (event->type == WHEELDOWNMOUSE && event->alt) {
+ if (type == MOUSEPAN && event->alt)
+ retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
+ else if (type == WHEELDOWNMOUSE && event->alt) {
mx = but->rect.xmin;
click = 1;
}
- else if (event->type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->alt) {
mx = but->rect.xmax;
click = 1;
}
@@ -2801,36 +3098,59 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return retval;
}
-static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short shift, const short ctrl, int mx)
+static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
+ const bool is_horizontal, const bool shift, const bool ctrl, int mx)
{
float deler, f, tempf, softmin, softmax, softrange;
- int temp, lvalue, changed = 0;
+ int temp, lvalue;
+ bool changed = false;
+ float mx_fl, my_fl;
+ /* note, 'offs' is really from the widget drawing rounded corners see 'widget_numslider' */
+ float offs;
softmin = but->softmin;
softmax = but->softmax;
softrange = softmax - softmin;
+ /* yes, 'mx' as both x/y is intentional */
+ ui_mouse_scale_warp(data, mx, mx, &mx_fl, &my_fl, shift);
+
if (but->type == NUMSLI) {
- deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect);
- }
- else if (but->type == HSVSLI) {
- deler = (BLI_rctf_size_x(&but->rect) / 2.0f - 5.0f * but->aspect);
+ offs = (BLI_rctf_size_y(&but->rect) / 2.0f) * but->aspect;
+ deler = BLI_rctf_size_x(&but->rect) - offs;
}
else if (but->type == SCROLL) {
- int horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
- float size = (horizontal) ? BLI_rctf_size_x(&but->rect) : -BLI_rctf_size_y(&but->rect);
+ const float size = (is_horizontal) ? BLI_rctf_size_x(&but->rect) : -BLI_rctf_size_y(&but->rect);
deler = size * (but->softmax - but->softmin) / (but->softmax - but->softmin + but->a1);
+ offs = 0.0;
}
else {
- deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect);
+ offs = (BLI_rctf_size_y(&but->rect) / 2.0f) * but->aspect;
+ deler = (BLI_rctf_size_x(&but->rect) - offs);
}
- f = (float)(mx - data->dragstartx) / deler + data->dragfstart;
-
- if (shift)
- f = (f - data->dragfstart) / 10.0f + data->dragfstart;
-
+ f = (mx_fl - data->dragstartx) / deler + data->dragfstart;
CLAMP(f, 0.0f, 1.0f);
+
+
+ /* deal with mouse correction */
+#ifdef USE_CONT_MOUSE_CORRECT
+ if (ui_is_a_warp_but(but)) {
+ /* OK but can go outside bounds */
+ if (is_horizontal) {
+ data->ungrab_mval[0] = (but->rect.xmin + offs / but->aspect) + (f * deler);
+ data->ungrab_mval[1] = BLI_rctf_cent_y(&but->rect);
+ }
+ else {
+ data->ungrab_mval[1] = (but->rect.ymin + offs / but->aspect) + (f * deler);
+ data->ungrab_mval[0] = BLI_rctf_cent_x(&but->rect);
+ }
+ BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
+ }
+#endif
+ /* done correcting mouse */
+
+
tempf = softmin + f * softrange;
temp = floorf(tempf + 0.5f);
@@ -2866,7 +3186,7 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short
if (temp != lvalue) {
data->value = temp;
data->dragchange = 1;
- changed = 1;
+ changed = true;
}
}
else {
@@ -2875,14 +3195,14 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short
if (tempf != (float)data->value) {
data->value = tempf;
data->dragchange = 1;
- changed = 1;
+ changed = true;
}
}
return changed;
}
-static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my, click = 0;
int retval = WM_UI_HANDLER_CONTINUE;
@@ -2892,12 +3212,20 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_window_to_block(data->region, block, &mx, &my);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ int type = event->type, val = event->val;
+
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+ }
+
/* XXX hardcoded keymap check.... */
- if (event->type == WHEELDOWNMOUSE && event->alt) {
+ if (type == MOUSEPAN && event->alt)
+ retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
+ else if (type == WHEELDOWNMOUSE && event->alt) {
mx = but->rect.xmin;
click = 2;
}
- else if (event->type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->alt) {
mx = but->rect.xmax;
click = 2;
}
@@ -2945,7 +3273,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
click = 1;
}
else if (event->type == MOUSEMOVE) {
- if (ui_numedit_but_SLI(but, data, event->shift, event->ctrl, mx))
+ if (ui_numedit_but_SLI(but, data, true, event->shift, event->ctrl, mx))
ui_numedit_apply(C, block, but, data);
}
retval = WM_UI_HANDLER_BREAK;
@@ -3018,11 +3346,11 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return retval;
}
-static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my /*, click = 0 */;
int retval = WM_UI_HANDLER_CONTINUE;
- int horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
+ bool horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
mx = event->x;
my = event->y;
@@ -3059,7 +3387,7 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (event->type == MOUSEMOVE) {
- if (ui_numedit_but_SLI(but, data, 0, 0, (horizontal) ? mx : my))
+ if (ui_numedit_but_SLI(but, data, horizontal, false, false, (horizontal) ? mx : my))
ui_numedit_apply(C, block, but, data);
}
@@ -3070,7 +3398,7 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
}
-static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
@@ -3084,7 +3412,14 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
return WM_UI_HANDLER_BREAK;
}
}
-
+#ifdef USE_DRAG_TOGGLE
+ if (event->type == LEFTMOUSE && ui_is_but_bool(but)) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_BREAK;
+ }
+#endif
/* regular open menu */
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
@@ -3123,7 +3458,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
}
}
else if (but->type == COLOR) {
- if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ if (ELEM3(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
float *hsv = ui_block_hsv_get(but->block);
float col[3];
@@ -3132,8 +3467,12 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
if (event->type == WHEELDOWNMOUSE)
hsv[2] = CLAMPIS(hsv[2] - 0.05f, 0.0f, 1.0f);
- else
+ else if (event->type == WHEELUPMOUSE)
hsv[2] = CLAMPIS(hsv[2] + 0.05f, 0.0f, 1.0f);
+ else {
+ float fac = 0.005 * (event->y - event->prevy);
+ hsv[2] = CLAMPIS(hsv[2] + fac, 0.0f, 1.0f);
+ }
hsv_to_rgb_v(hsv, data->vec);
ui_set_but_vectorf(but, data->vec);
@@ -3229,7 +3568,7 @@ static int ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, i
return changed;
}
-static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -3269,6 +3608,19 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
return WM_UI_HANDLER_CONTINUE;
}
+/* scales a vector so no axis exceeds max
+ * (could become BLI_math func) */
+static void clamp_axis_max_v3(float v[3], const float max)
+{
+ const float v_max = max_fff(v[0], v[1], v[2]);
+ if (v_max > max) {
+ mul_v3_fl(v, max / v_max);
+ if (v[0] > max) v[0] = max;
+ if (v[1] > max) v[1] = max;
+ if (v[2] > max) v[2] = max;
+ }
+}
+
static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my, const short shift)
{
float rgb[3];
@@ -3345,6 +3697,11 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
if (color_profile && ((int)but->a1 != UI_GRAD_SV))
ui_block_to_scene_linear_v3(but->block, rgb);
+ /* clamp because with color conversion we can exceed range [#34295] */
+ if ((int)but->a1 == UI_GRAD_V_ALT) {
+ clamp_axis_max_v3(rgb, but->softmax);
+ }
+
copy_v3_v3(data->vec, rgb);
data->draglastx = mx;
@@ -3415,7 +3772,7 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOF
ui_set_but_vectorf(but, data->vec);
}
-static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -3615,7 +3972,7 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmND
}
-static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
mx = event->x;
@@ -3734,7 +4091,7 @@ static int ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx
return changed;
}
-static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
ColorBand *coba;
CBData *cbd;
@@ -3795,20 +4152,27 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
- float mx, float my, const short shift)
+static int ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData *data, int snap,
+ int evtx, int evty, const short shift)
{
CurveMapping *cumap = (CurveMapping *)but->poin;
CurveMap *cuma = cumap->cm + cumap->cur;
CurveMapPoint *cmp = cuma->curve;
- float fx, fy, zoomx, zoomy /*, offsx, offsy */ /* UNUSED */;
+ float fx, fy, zoomx, zoomy;
+ int mx, my, dragx, dragy;
int a, changed = 0;
+ /* evtx evty and drag coords are absolute mousecoords, prevents errors when editing when layout changes */
+ mx = evtx;
+ my = evty;
+ ui_window_to_block(data->region, block, &mx, &my);
+ dragx = data->draglastx;
+ dragy = data->draglasty;
+ ui_window_to_block(data->region, block, &dragx, &dragy);
+
zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&cumap->curr);
zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&cumap->curr);
- /* offsx = cumap->curr.xmin; */
- /* offsy = cumap->curr.ymin; */
-
+
if (snap) {
float d[2];
@@ -3824,8 +4188,8 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
const float mval_factor = ui_mouse_scale_warp_factor(shift);
int moved_point = 0; /* for ctrl grid, can't use orig coords because of sorting */
- fx = (mx - data->draglastx) / zoomx;
- fy = (my - data->draglasty) / zoomy;
+ fx = (mx - dragx) / zoomx;
+ fy = (my - dragy) / zoomy;
fx *= mval_factor;
fy *= mval_factor;
@@ -3849,8 +4213,8 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
curvemapping_changed(cumap, FALSE);
if (moved_point) {
- data->draglastx = mx;
- data->draglasty = my;
+ data->draglastx = evtx;
+ data->draglasty = evty;
changed = 1;
#ifdef USE_CONT_MOUSE_CORRECT
@@ -3869,8 +4233,8 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
data->dragchange = 1; /* mark for selection */
}
else {
- fx = (mx - data->draglastx) / zoomx;
- fy = (my - data->draglasty) / zoomy;
+ fx = (mx - dragx) / zoomx;
+ fy = (my - dragy) / zoomy;
/* clamp for clip */
if (cumap->flag & CUMA_DO_CLIP) {
@@ -3889,8 +4253,8 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
cumap->curr.xmax -= fx;
cumap->curr.ymax -= fy;
- data->draglastx = mx;
- data->draglasty = my;
+ data->draglastx = evtx;
+ data->draglasty = evty;
changed = 1;
}
@@ -3898,14 +4262,14 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
return changed;
}
-static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my, a, changed = 0;
mx = event->x;
my = event->y;
ui_window_to_block(data->region, block, &mx, &my);
-
+
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
CurveMapping *cumap = (CurveMapping *)but->poin;
@@ -3995,11 +4359,11 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt
}
data->dragsel = sel;
-
- data->dragstartx = mx;
- data->dragstarty = my;
- data->draglastx = mx;
- data->draglasty = my;
+
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ data->draglastx = event->x;
+ data->draglasty = event->y;
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
return WM_UI_HANDLER_BREAK;
@@ -4007,8 +4371,9 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt
}
else if (data->state == BUTTON_STATE_NUM_EDITING) {
if (event->type == MOUSEMOVE) {
- if (mx != data->draglastx || my != data->draglasty) {
- if (ui_numedit_but_CURVE(but, data, event->ctrl, mx, my, event->shift))
+ if (event->x != data->draglastx || event->y != data->draglasty) {
+
+ if (ui_numedit_but_CURVE(block, but, data, event->ctrl, event->x, event->y, event->shift))
ui_numedit_apply(C, block, but, data);
}
}
@@ -4063,7 +4428,7 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx
if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
/* resize histogram widget itself */
- hist->height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my);
+ hist->height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
}
else {
/* scale histogram values (dy / 10 for better control) */
@@ -4080,7 +4445,7 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx
return changed;
}
-static int ui_do_but_HISTOGRAM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_HISTOGRAM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -4147,7 +4512,7 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx,
if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
/* resize waveform widget itself */
- scopes->wavefrm_height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my);
+ scopes->wavefrm_height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
}
else {
/* scale waveform values */
@@ -4163,7 +4528,7 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx,
return changed;
}
-static int ui_do_but_WAVEFORM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_WAVEFORM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -4229,7 +4594,7 @@ static int ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int
if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
/* resize vectorscope widget itself */
- scopes->vecscope_height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my);
+ scopes->vecscope_height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
}
data->draglastx = mx;
@@ -4238,7 +4603,7 @@ static int ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int
return changed;
}
-static int ui_do_but_VECTORSCOPE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_VECTORSCOPE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -4283,7 +4648,7 @@ static int ui_do_but_VECTORSCOPE(bContext *C, uiBlock *block, uiBut *but, uiHand
}
#ifdef WITH_INTERNATIONAL
-static int ui_do_but_CHARTAB(bContext *UNUSED(C), uiBlock *UNUSED(block), uiBut *UNUSED(but), uiHandleButtonData *UNUSED(data), wmEvent *UNUSED(event))
+static int ui_do_but_CHARTAB(bContext *UNUSED(C), uiBlock *UNUSED(block), uiBut *UNUSED(but), uiHandleButtonData *UNUSED(data), const wmEvent *UNUSED(event))
{
/* XXX 2.50 bad global and state access */
#if 0
@@ -4388,7 +4753,7 @@ static int ui_do_but_CHARTAB(bContext *UNUSED(C), uiBlock *UNUSED(block), uiBut
#endif
-static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
VECCOPY2D(but->linkto, event->mval);
@@ -4432,7 +4797,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa
if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
/* resize preview widget itself */
- scopes->track_preview_height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my);
+ scopes->track_preview_height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
}
else {
if (!scopes->track_locked) {
@@ -4455,7 +4820,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa
return changed;
}
-static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -4530,7 +4895,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
wmKeyMapItem *kmi;
PointerRNA ptr;
uiLayout *layout;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km);
@@ -4562,7 +4927,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
wmKeyMapItem *kmi;
PointerRNA ptr;
uiLayout *layout;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int kmi_id;
@@ -4629,10 +4994,9 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
static int ui_but_menu(bContext *C, uiBut *but)
{
- ARegion *ar = CTX_wm_region(C);
uiPopupMenu *pup;
uiLayout *layout;
- int length;
+ bool is_array, is_array_component;
const char *name;
uiStringInfo label = {BUT_GET_LABEL, NULL};
@@ -4653,18 +5017,20 @@ static int ui_but_menu(bContext *C, uiBut *but)
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
if (but->rnapoin.data && but->rnaprop) {
- short is_anim = RNA_property_animateable(&but->rnapoin, but->rnaprop);
+ bool is_anim = RNA_property_animateable(&but->rnapoin, but->rnaprop);
/* second slower test, saved people finding keyframe items in menus when its not possible */
if (is_anim)
is_anim = RNA_property_path_from_ID_check(&but->rnapoin, but->rnaprop);
- length = RNA_property_array_length(&but->rnapoin, but->rnaprop);
+ /* determine if we can key a single component of an array */
+ is_array = RNA_property_array_length(&but->rnapoin, but->rnaprop) != 0;
+ is_array_component = (is_array && but->rnaindex != -1);
/* Keyframes */
if (but->flag & UI_BUT_ANIMATED_KEY) {
/* replace/delete keyfraemes */
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframes"),
ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Single Keyframe"),
@@ -4676,9 +5042,9 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
+ ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 0);
+ ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 1);
}
/* keyframe settings */
@@ -4690,7 +5056,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
/* pass */
}
else if (is_anim) {
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframes"),
ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Single Keyframe"),
@@ -4698,12 +5064,12 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
+ ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 1);
}
}
if (but->flag & UI_BUT_ANIMATED) {
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Single Keyframes"),
@@ -4711,7 +5077,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
- ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 0);
+ ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 1);
}
}
@@ -4719,7 +5085,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
if (but->flag & UI_BUT_DRIVEN) {
uiItemS(layout);
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Drivers"),
ICON_NONE, "ANIM_OT_driver_button_remove", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Driver"),
@@ -4727,7 +5093,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Driver"),
- ICON_NONE, "ANIM_OT_driver_button_remove", "all", 0);
+ ICON_NONE, "ANIM_OT_driver_button_remove", "all", 1);
}
uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Driver"),
@@ -4743,7 +5109,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
else if (is_anim) {
uiItemS(layout);
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Drivers"),
ICON_NONE, "ANIM_OT_driver_button_add", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single Driver"),
@@ -4751,7 +5117,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Driver"),
- ICON_NONE, "ANIM_OT_driver_button_add", "all", 0);
+ ICON_NONE, "ANIM_OT_driver_button_add", "all", 1);
}
if (ANIM_driver_can_paste()) {
@@ -4765,7 +5131,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
if (is_anim) {
uiItemS(layout);
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add All to Keying Set"),
ICON_NONE, "ANIM_OT_keyingset_button_add", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single to Keying Set"),
@@ -4775,7 +5141,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Keying Set"),
- ICON_NONE, "ANIM_OT_keyingset_button_add", "all", 0);
+ ICON_NONE, "ANIM_OT_keyingset_button_add", "all", 1);
uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
ICON_NONE, "ANIM_OT_keyingset_button_remove");
}
@@ -4788,15 +5154,15 @@ static int ui_but_menu(bContext *C, uiBut *but)
/* Copy Property Value
* Paste Property Value */
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset All to Default Values"),
ICON_NONE, "UI_OT_reset_default_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset Single to Default Value"),
ICON_NONE, "UI_OT_reset_default_button", "all", 0);
}
else {
- uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
- ICON_NONE, "UI_OT_reset_default_button");
+ uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
+ ICON_NONE, "UI_OT_reset_default_button", "all", 1);
}
uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"),
@@ -4845,9 +5211,13 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
/* Show header tools for header buttons. */
- if (ar->regiontype == RGN_TYPE_HEADER) {
- uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
- uiItemS(layout);
+ if (CTX_wm_region(C)) {
+ ARegion *ar = CTX_wm_region(C);
+ if (ar->regiontype == RGN_TYPE_HEADER) {
+
+ uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
+ uiItemS(layout);
+ }
}
{ /* Docs */
@@ -4912,7 +5282,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
return 1;
}
-static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
+static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event)
{
uiHandleButtonData *data;
int retval;
@@ -5047,7 +5417,6 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
break;
case SLI:
case NUMSLI:
- case HSVSLI:
retval = ui_do_but_SLI(C, block, but, data, event);
break;
case ROUNDBOX:
@@ -5058,6 +5427,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
case LISTROW:
case BUT_IMAGE:
case PROGRESSBAR:
+ case NODESOCKET:
retval = ui_do_but_EXIT(C, but, data, event);
break;
case HISTOGRAM:
@@ -5074,6 +5444,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:
@@ -5187,7 +5560,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;
}
@@ -5226,32 +5599,15 @@ static int ui_mouse_inside_region(ARegion *ar, int x, int y)
*/
if (ar->v2d.mask.xmin != ar->v2d.mask.xmax) {
View2D *v2d = &ar->v2d;
- rcti mask_rct;
int mx, my;
/* convert window coordinates to region coordinates */
mx = x;
my = y;
ui_window_to_region(ar, &mx, &my);
-
- /* make a copy of the mask rect, and tweak accordingly for hidden scrollbars */
- mask_rct = v2d->mask;
-
- if (v2d->scroll & (V2D_SCROLL_VERTICAL_HIDE | V2D_SCROLL_VERTICAL_FULLR)) {
- if (v2d->scroll & V2D_SCROLL_LEFT)
- mask_rct.xmin = v2d->vert.xmin;
- else if (v2d->scroll & V2D_SCROLL_RIGHT)
- mask_rct.xmax = v2d->vert.xmax;
- }
- if (v2d->scroll & (V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_HORIZONTAL_FULLR)) {
- if (v2d->scroll & (V2D_SCROLL_BOTTOM | V2D_SCROLL_BOTTOM_O))
- mask_rct.ymin = v2d->hor.ymin;
- else if (v2d->scroll & V2D_SCROLL_TOP)
- mask_rct.ymax = v2d->hor.ymax;
- }
-
+
/* check if in the rect */
- if (!BLI_rcti_isect_pt(&mask_rct, mx, my))
+ if (!BLI_rcti_isect_pt(&v2d->mask, mx, my))
return 0;
}
@@ -5271,7 +5627,25 @@ static int ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y)
return 1;
}
-static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
+/**
+ * Can we mouse over the button or is it hidden/disabled/layout.
+ */
+bool ui_is_but_interactive(uiBut *but)
+{
+ /* note, LABEL is included for highlights, this allows drags */
+ if (but->type == LABEL && but->dragpoin == NULL)
+ return false;
+ if (ELEM3(but->type, ROUNDBOX, SEPR, LISTBOX))
+ return false;
+ if (but->flag & UI_HIDDEN)
+ return false;
+ if (but->flag & UI_SCROLLED)
+ return false;
+
+ return true;
+}
+
+uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
{
uiBlock *block;
uiBut *but, *butover = NULL;
@@ -5288,17 +5662,11 @@ static 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) {
- /* note, LABEL is included for highlights, this allows drags */
- if (but->type == LABEL && but->dragpoin == NULL)
- continue;
- if (ELEM3(but->type, ROUNDBOX, SEPR, LISTBOX))
- continue;
- if (but->flag & UI_HIDDEN)
- continue;
- if (but->flag & UI_SCROLLED)
- continue;
- if (ui_but_contains_pt(but, mx, my))
- butover = but;
+ if (ui_is_but_interactive(but)) {
+ if (ui_but_contains_pt(but, mx, my)) {
+ butover = but;
+ }
+ }
}
/* CLIP_EVENTS prevents the event from reaching other blocks */
@@ -5530,7 +5898,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 {
@@ -5585,7 +5953,8 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
}
-static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *but, int mousemove, int onfree)
+static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *data,
+ const bool mousemove, const bool onfree)
{
uiBlock *block = but->block;
uiBut *bt;
@@ -5613,7 +5982,8 @@ static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *b
if (!onfree && !data->cancel) {
/* autokey & undo push */
- ui_apply_autokey_undo(C, but);
+ ui_apply_undo(but);
+ ui_apply_autokey(C, but);
/* popup menu memory */
if (block->flag & UI_BLOCK_POPUP_MEMORY)
@@ -5638,10 +6008,13 @@ static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *b
/* redraw (data is but->active!) */
ED_region_tag_redraw(data->region);
-
+
/* clean up button */
- MEM_freeN(but->active);
- but->active = NULL;
+ if (but->active) {
+ MEM_freeN(but->active);
+ but->active = NULL;
+ }
+
but->flag &= ~(UI_ACTIVE | UI_SELECT);
but->flag |= UI_BUT_LAST_ACTIVE;
if (!onfree)
@@ -5664,7 +6037,7 @@ void ui_button_active_free(const bContext *C, uiBut *but)
if (but->active) {
data = but->active;
data->cancel = TRUE;
- button_activate_exit((bContext *)C, data, but, 0, 1);
+ button_activate_exit((bContext *)C, but, data, false, true);
}
}
@@ -5839,7 +6212,7 @@ void uiContextAnimUpdate(const bContext *C)
/************** handle activating a button *************/
-static uiBut *uit_but_find_open_event(ARegion *ar, wmEvent *event)
+static uiBut *uit_but_find_open_event(ARegion *ar, const wmEvent *event)
{
uiBlock *block;
uiBut *but;
@@ -5852,7 +6225,7 @@ static uiBut *uit_but_find_open_event(ARegion *ar, wmEvent *event)
return NULL;
}
-static int ui_handle_button_over(bContext *C, wmEvent *event, ARegion *ar)
+static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *ar)
{
uiBut *but;
@@ -5890,6 +6263,21 @@ void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but)
ui_do_button(C, but->block, but, &event);
}
+void ui_button_execute_do(struct bContext *C, struct ARegion *ar, uiBut *but)
+{
+ /* note: ideally we would not have to change 'but->active' howevwer
+ * some functions we call don't use data (as they should be doing) */
+ void *active_back = but->active;
+ uiHandleButtonData *data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData_Fake");
+ but->active = data;
+ data->region = ar;
+ ui_apply_button(C, but->block, but, data, true);
+ /* use onfree event so undo is handled by caller and apply is already done above */
+ ui_apply_autokey(C, but);
+ button_activate_exit((bContext *)C, but, data, false, true);
+ but->active = active_back;
+}
+
static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type)
{
uiBut *oldbut;
@@ -5899,7 +6287,7 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu
if (oldbut) {
data = oldbut->active;
data->cancel = TRUE;
- button_activate_exit(C, data, oldbut, 0, 0);
+ button_activate_exit(C, oldbut, data, false, false);
}
button_activate_init(C, ar, but, type);
@@ -5907,16 +6295,14 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu
/************ handle events for an activated button ***********/
-static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
+static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
{
- uiHandleButtonData *data;
+ uiHandleButtonData *data = but->active;
+ const uiHandleButtonState state_orig = data->state;
uiBlock *block;
ARegion *ar;
- uiBut *postbut;
- uiButtonActivateType posttype;
int retval;
- data = but->active;
block = but->block;
ar = data->region;
@@ -5968,19 +6354,18 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
retval = WM_UI_HANDLER_CONTINUE;
break;
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- case MIDDLEMOUSE:
- /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
- if (data->tooltiptimer) {
- WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
- data->tooltiptimer = NULL;
- }
- /* pass on purposedly */
- default:
- /* handle button type specific events */
- retval = ui_do_button(C, block, but, event);
}
+ /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
+ case WHEELUPMOUSE:
+ case WHEELDOWNMOUSE:
+ case MIDDLEMOUSE:
+ case MOUSEPAN:
+ button_timers_tooltip_remove(C, but);
+
+ /* pass on purposedly */
+ default:
+ /* handle button type specific events */
+ retval = ui_do_button(C, block, but, event);
}
}
else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
@@ -6069,82 +6454,113 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
}
if (data->state == BUTTON_STATE_EXIT) {
- postbut = data->postbut;
- posttype = data->posttype;
+ uiBut *post_but = data->postbut;
+ uiButtonActivateType post_type = data->posttype;
- button_activate_exit(C, data, but, (postbut == NULL), 0);
+ button_activate_exit(C, but, data, (post_but == NULL), false);
/* for jumping to the next button with tab while text editing */
- if (postbut)
- button_activate_init(C, ar, postbut, posttype);
+ if (post_but) {
+ button_activate_init(C, ar, post_but, post_type);
+ }
+ else {
+ /* XXX issue is because WM_event_add_mousemove(C) is a bad hack and not reliable,
+ *if that gets coded better this bypass can go away too.
+ *
+ * This is needed to make sure if a button was active,
+ * 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) {
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+ }
+ }
+ }
}
return retval;
}
-static int ui_handle_list_event(bContext *C, wmEvent *event, ARegion *ar)
+static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
{
uiBut *but = ui_list_find_mouse_over(ar, event->x, event->y);
int retval = WM_UI_HANDLER_CONTINUE;
int value, min, max;
+ int type = event->type, val = event->val;
- if (but && (event->val == KM_PRESS)) {
- Panel *pa = but->block->panel;
+ if (but) {
+ uiList *ui_list = but->custom_data;
- if (ELEM(event->type, UPARROWKEY, DOWNARROWKEY) ||
- ((ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
- {
- /* activate up/down the list */
- value = RNA_property_int_get(&but->rnapoin, but->rnaprop);
+ if (ui_list) {
+
+ /* convert pan to scrollwheel */
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+
+ /* if type still is mousepan, we call it handled, since delta-y accumulate */
+ /* also see wm_event_system.c do_wheel_ui hack */
+ if (type == MOUSEPAN)
+ retval = WM_UI_HANDLER_BREAK;
+ }
+
+ if (val == KM_PRESS) {
+
+ if (ELEM(type, UPARROWKEY, DOWNARROWKEY) ||
+ ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
+ {
+ /* activate up/down the list */
+ value = RNA_property_int_get(&but->rnapoin, but->rnaprop);
- if (ELEM(event->type, UPARROWKEY, WHEELUPMOUSE))
- value--;
- else
- value++;
+ if (ELEM(type, UPARROWKEY, WHEELUPMOUSE))
+ value--;
+ else
+ value++;
- CLAMP(value, 0, pa->list_last_len - 1);
+ CLAMP(value, 0, ui_list->list_last_len - 1);
- if (value < pa->list_scroll)
- pa->list_scroll = value;
- else if (value >= pa->list_scroll + pa->list_size)
- pa->list_scroll = value - pa->list_size + 1;
+ if (value < ui_list->list_scroll)
+ ui_list->list_scroll = value;
+ else if (value >= ui_list->list_scroll + ui_list->list_size)
+ ui_list->list_scroll = value - ui_list->list_size + 1;
- RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
- value = CLAMPIS(value, min, max);
+ RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
+ value = CLAMPIS(value, min, max);
- RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
- RNA_property_update(C, &but->rnapoin, but->rnaprop);
- ED_region_tag_redraw(ar);
+ RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+ ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
- /* silly replacement for proper grip */
- if (pa->list_grip_size == 0)
- pa->list_grip_size = pa->list_size;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
+ /* silly replacement for proper grip */
+ if (ui_list->list_grip_size == 0)
+ ui_list->list_grip_size = ui_list->list_size;
- if (event->type == WHEELUPMOUSE)
- pa->list_grip_size--;
- else
- pa->list_grip_size++;
+ if (type == WHEELUPMOUSE)
+ ui_list->list_grip_size--;
+ else
+ ui_list->list_grip_size++;
- pa->list_grip_size = MAX2(pa->list_grip_size, 1);
+ ui_list->list_grip_size = MAX2(ui_list->list_grip_size, 1);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
- if (pa->list_last_len > pa->list_size) {
- /* list template will clamp */
- if (event->type == WHEELUPMOUSE)
- pa->list_scroll--;
- else
- pa->list_scroll++;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
+ if (ui_list->list_last_len > ui_list->list_size) {
+ /* list template will clamp */
+ if (type == WHEELUPMOUSE)
+ ui_list->list_scroll--;
+ else
+ ui_list->list_scroll++;
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
}
}
}
@@ -6152,7 +6568,7 @@ static int ui_handle_list_event(bContext *C, wmEvent *event, ARegion *ar)
return retval;
}
-static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *but)
+static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, uiBut *but)
{
uiHandleButtonData *data;
uiPopupBlockHandle *menu;
@@ -6184,7 +6600,7 @@ static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *
if (menu->menuretval != UI_RETURN_OK)
data->cancel = TRUE;
- button_activate_exit(C, data, but, 1, 0);
+ button_activate_exit(C, but, data, true, false);
}
else if (menu->menuretval & UI_RETURN_OUT) {
if (event->type == MOUSEMOVE && ui_mouse_inside_button(data->region, but, event->x, event->y)) {
@@ -6198,7 +6614,7 @@ static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *
}
else {
data->cancel = TRUE;
- button_activate_exit(C, data, but, 1, 0);
+ button_activate_exit(C, but, data, true, false);
}
}
}
@@ -6324,7 +6740,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
for (bt = block->buttons.first; bt; bt = bt->next)
ymax = max_ff(ymax, bt->rect.ymax);
- if (ymax + dy - UI_UNIT_Y*0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD)
+ if (ymax + dy - UI_UNIT_Y * 0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD)
dy = block->rect.ymax - ymax - UI_MENU_SCROLL_PAD;
}
else {
@@ -6334,7 +6750,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
for (bt = block->buttons.first; bt; bt = bt->next)
ymin = min_ff(ymin, bt->rect.ymin);
- if (ymin + dy + UI_UNIT_Y*0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD)
+ if (ymin + dy + UI_UNIT_Y * 0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD)
dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD;
}
@@ -6355,7 +6771,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
return 0;
}
-static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int level)
+static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu, int level)
{
ARegion *ar;
uiBlock *block;
@@ -6377,7 +6793,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 */
@@ -6403,7 +6819,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) {
@@ -6450,31 +6866,40 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
case DOWNARROWKEY:
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
+ case MOUSEPAN:
/* arrowkeys: only handle for block_loop blocks */
if (event->alt || event->shift || event->ctrl || event->oskey) {
/* pass */
}
else if (inside || (block->flag & UI_BLOCK_LOOP)) {
- if (event->val == KM_PRESS) {
+ int type = event->type;
+ int val = event->val;
+
+ /* convert pan to scrollwheel */
+ if (type == MOUSEPAN)
+ ui_pan_to_scroll(event, &type, &val);
+
+ if (val == KM_PRESS) {
+ const eButType type_flip = BUT | ROW;
PASS_EVENT_TO_PARENT_IF_NONACTIVE;
but = ui_but_find_activated(ar);
if (but) {
/* is there a situation where UI_LEFT or UI_RIGHT would also change navigation direction? */
- if (((ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_DOWN)) ||
- ((ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_RIGHT)) ||
- ((ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_TOP)))
+ if (((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_DOWN)) ||
+ ((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_RIGHT)) ||
+ ((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_TOP)))
{
/* the following is just a hack - uiBut->type set to BUT and BUTM have there menus built
* opposite ways - this should be changed so that all popup-menus use the same uiBlock->direction */
- if (but->type & BUT)
+ if (but->type & type_flip)
but = ui_but_next(but);
else
but = ui_but_prev(but);
}
else {
- if (but->type & BUT)
+ if (but->type & type_flip)
but = ui_but_prev(but);
else
but = ui_but_next(but);
@@ -6487,11 +6912,11 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
}
if (!but) {
- if (((ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_DOWN)) ||
- ((ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_RIGHT)) ||
- ((ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_TOP)))
+ if (((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_DOWN)) ||
+ ((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_RIGHT)) ||
+ ((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_TOP)))
{
- if ((bt = ui_but_first(block)) && (bt->type & BUT)) {
+ if ((bt = ui_but_first(block)) && (bt->type & type_flip)) {
bt = ui_but_last(block);
}
else {
@@ -6499,7 +6924,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
}
}
else {
- if ((bt = ui_but_first(block)) && (bt->type & BUT)) {
+ if ((bt = ui_but_first(block)) && (bt->type & type_flip)) {
/* keep ui_but_first() */
}
else {
@@ -6757,7 +7182,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
return retval;
}
-static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlockHandle *menu)
+static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu)
{
ARegion *ar;
uiBut *but;
@@ -6806,7 +7231,7 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo
return WM_UI_HANDLER_BREAK;
}
-static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int level)
+static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu, int level)
{
uiBut *but;
uiHandleButtonData *data;
@@ -6828,7 +7253,7 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa
retval = ui_handle_menu_return_submenu(C, event, menu);
submenu = NULL; /* hint not to use this, it may be freed by call above */
(void)submenu;
- /* we may wan't to quit the submenu and handle the even in this menu,
+ /* we may want to quit the submenu and handle the even in this menu,
* if its important to use it, check 'data->menu' first */
if ((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) {
retval = ui_handle_menu_event(C, event, menu, level);
@@ -6844,7 +7269,7 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa
/* *************** UI event handlers **************** */
-static int ui_handler_region(bContext *C, wmEvent *event, void *UNUSED(userdata))
+static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(userdata))
{
ARegion *ar;
uiBut *but;
@@ -6902,12 +7327,10 @@ static void ui_handler_remove_region(bContext *C, void *UNUSED(userdata))
ui_apply_but_funcs_after(C);
}
-static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(userdata))
+static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSED(userdata))
{
ARegion *ar;
uiBut *but;
- uiHandleButtonData *data;
- int retval;
/* here we handle buttons at the window level, modal, for example
* while number sliding, text editing, or when a menu block is open */
@@ -6918,17 +7341,24 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user
but = ui_but_find_activated(ar);
if (but) {
+ uiHandleButtonData *data;
+
/* handle activated button events */
data = but->active;
if (data->state == BUTTON_STATE_MENU_OPEN) {
+ int retval;
+
/* handle events for menus and their buttons recursively,
* this will handle events from the top to the bottom menu */
- retval = ui_handle_menus_recursive(C, event, data->menu, 0);
+ if (data->menu)
+ retval = ui_handle_menus_recursive(C, event, data->menu, 0);
/* handle events for the activated button */
- if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
- if (data->menu->menuretval)
+ if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) ||
+ (event->type == TIMER))
+ {
+ if (data->menu && data->menu->menuretval)
ui_handle_button_return_submenu(C, event, but);
else
ui_handle_button_event(C, event, but);
@@ -6952,7 +7382,7 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user
}
/* two types of popups, one with operator + enum, other with regular callbacks */
-static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
+static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
{
uiPopupBlockHandle *menu = userdata;
@@ -6985,7 +7415,7 @@ static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
WM_operator_name_call(C, temp.optype->idname, temp.opcontext, NULL);
}
else if (temp.cancel_func)
- temp.cancel_func(temp.popup_arg);
+ temp.cancel_func(C, temp.popup_arg);
}
else {
/* re-enable tooltips */