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.c549
1 files changed, 238 insertions, 311 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 1bb479935c8..bb54f26131a 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -38,11 +38,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_brush_types.h"
-#include "DNA_sensor_types.h"
-#include "DNA_controller_types.h"
-#include "DNA_actuator_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -72,6 +68,7 @@
#include "ED_undo.h"
#include "UI_interface.h"
+#include "UI_view2d.h"
#include "BLF_api.h"
@@ -109,8 +106,6 @@
#define UI_MAX_PASSWORD_STR 128
/* proto */
-static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to);
-static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to);
static int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, const wmEvent *event);
static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but_b);
static void ui_textedit_string_set(uiBut *but, struct uiHandleButtonData *data, const char *str);
@@ -125,7 +120,7 @@ static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEve
#define BUTTON_FLASH_DELAY 0.020
#define MENU_SCROLL_INTERVAL 0.1
#define PIE_MENU_INTERVAL 0.01
-#define BUTTON_AUTO_OPEN_THRESH 0.3
+#define BUTTON_AUTO_OPEN_THRESH 0.2
#define BUTTON_MOUSE_TOWARDS_THRESH 1.0
/* pixels to move the cursor to get out of keyboard navigation */
#define BUTTON_KEYNAV_PX_LIMIT 8
@@ -276,6 +271,7 @@ typedef struct uiHandleButtonData {
/* booleans (could be made into flags) */
bool cancel, escapecancel;
bool applied, applied_interactive;
+ bool changed_cursor;
wmTimer *flashtimer;
/* edited value */
@@ -501,6 +497,16 @@ bool ui_but_is_toggle(const uiBut *but)
);
}
+#ifdef USE_UI_POPOVER_ONCE
+bool ui_but_is_popover_once_compat(const uiBut *but)
+{
+ return (
+ (but->type == UI_BTYPE_BUT) ||
+ ui_but_is_toggle(but)
+ );
+}
+#endif
+
static uiBut *ui_but_prev(uiBut *but)
{
while (but->prev) {
@@ -649,11 +655,8 @@ PointerRNA *ui_handle_afterfunc_add_operator(wmOperatorType *ot, int opcontext,
static void popup_check(bContext *C, wmOperator *op)
{
- if (op && op->type->check && op->type->check(C, op)) {
- /* check for popup and re-layout buttons */
- ARegion *ar_menu = CTX_wm_menu(C);
- if (ar_menu)
- ED_region_tag_refresh_ui(ar_menu);
+ if (op && op->type->check) {
+ op->type->check(C, op);
}
}
@@ -734,8 +737,7 @@ static void ui_apply_but_undo(uiBut *but)
const char *str = NULL;
/* define which string to use for undo */
- if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) str = "Add button link";
- else if (but->type == UI_BTYPE_MENU) str = but->drawstr;
+ if (but->type == UI_BTYPE_MENU) str = but->drawstr;
else if (but->drawstr[0]) str = but->drawstr;
else str = but->tip;
@@ -947,6 +949,20 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data)
data->applied = true;
}
+static void ui_apply_but_TAB(bContext *C, uiBut *but, uiHandleButtonData *data)
+{
+ if (data->str) {
+ ui_but_string_set(C, but, data->str);
+ ui_but_update_edited(but);
+ }
+ else {
+ ui_apply_but_func(C, but);
+ }
+
+ data->retval = but->retval;
+ data->applied = true;
+}
+
static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data)
{
if (data->str) {
@@ -1249,6 +1265,9 @@ static bool ui_drag_toggle_but_is_supported(const uiBut *but)
if (ui_but_is_bool(but)) {
return true;
}
+ else if (UI_but_is_decorator(but)) {
+ return ELEM(but->icon, ICON_SPACE2, ICON_SPACE3, ICON_DOT, ICON_LIBRARY_DATA_OVERRIDE);
+ }
else {
return false;
}
@@ -1259,6 +1278,9 @@ static bool ui_drag_toggle_but_is_pushed(uiBut *but)
if (ui_but_is_bool(but)) {
return ui_but_is_pushed(but);
}
+ else if (UI_but_is_decorator(but)) {
+ return (but->icon == ICON_SPACE2);
+ }
else {
return false;
}
@@ -1269,7 +1291,6 @@ typedef struct uiDragToggleHandle {
bool is_init;
bool is_set;
float but_cent_start[2];
- eButType but_type_start;
bool xy_lock[2];
int xy_init[2];
@@ -1277,7 +1298,7 @@ typedef struct uiDragToggleHandle {
} uiDragToggleHandle;
static bool ui_drag_toggle_set_xy_xy(
- bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
+ bContext *C, ARegion *ar, const bool is_set,
const int xy_src[2], const int xy_dst[2])
{
/* popups such as layers won't re-evaluate on redraw */
@@ -1301,7 +1322,7 @@ static bool ui_drag_toggle_set_xy_xy(
if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
/* execute the button */
- if (ui_drag_toggle_but_is_supported(but) && but->type == but_type_start) {
+ if (ui_drag_toggle_but_is_supported(but)) {
/* is it pressed? */
bool is_set_but = ui_drag_toggle_but_is_pushed(but);
if (is_set_but != is_set) {
@@ -1373,7 +1394,7 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const
/* 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);
+ do_draw = ui_drag_toggle_set_xy_xy(C, ar, drag_info->is_set, drag_info->xy_last, xy);
if (do_draw) {
ED_region_tag_redraw(ar);
@@ -1752,7 +1773,6 @@ static bool ui_but_drag_init(
drag_info->is_set = ui_drag_toggle_but_is_pushed(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_init, &event->x);
copy_v2_v2_int(drag_info->xy_last, &event->x);
@@ -1819,223 +1839,6 @@ static bool ui_but_drag_init(
/* ********************** linklines *********************** */
-static void ui_linkline_remove_active(uiBlock *block)
-{
- uiBut *but;
- uiLink *link;
- uiLinkLine *line, *nline;
- int a, b;
-
- for (but = block->buttons.first; but; but = but->next) {
- if (but->type == UI_BTYPE_LINK && but->link) {
- for (line = but->link->lines.first; line; line = nline) {
- nline = line->next;
-
- if (line->flag & UI_SELECT) {
- BLI_remlink(&but->link->lines, line);
-
- link = line->from->link;
-
- /* are there more pointers allowed? */
- if (link->ppoin) {
-
- if (*(link->totlink) == 1) {
- *(link->totlink) = 0;
- MEM_freeN(*(link->ppoin));
- *(link->ppoin) = NULL;
- }
- else {
- b = 0;
- for (a = 0; a < (*(link->totlink)); a++) {
-
- if ((*(link->ppoin))[a] != line->to->poin) {
- (*(link->ppoin))[b] = (*(link->ppoin))[a];
- b++;
- }
- }
- (*(link->totlink))--;
- }
- }
- else {
- *(link->poin) = NULL;
- }
-
- MEM_freeN(line);
- }
- }
- }
- }
-}
-
-
-static uiLinkLine *ui_but_find_link(uiBut *from, uiBut *to)
-{
- uiLinkLine *line;
- uiLink *link;
-
- link = from->link;
- if (link) {
- for (line = link->lines.first; line; line = line->next) {
- if (line->from == from && line->to == to) {
- return line;
- }
- }
- }
- return NULL;
-}
-
-/* XXX BAD BAD HACK, fixme later **************** */
-/* Try to add an AND Controller between the sensor and the actuator logic bricks and to connect them all */
-static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to)
-{
- Object *ob = NULL;
- bSensor *sens_iter;
- bActuator *act_to, *act_iter;
- bController *cont;
- bController ***sens_from_links;
- uiBut *tmp_but;
-
- uiLink *link = from->link;
-
- PointerRNA props_ptr, object_ptr;
-
- if (link->ppoin)
- sens_from_links = (bController ***)(link->ppoin);
- else return;
-
- act_to = (bActuator *)(to->poin);
-
- /* (1) get the object */
- CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects)
- {
- for (sens_iter = ob_iter->sensors.first; sens_iter; sens_iter = sens_iter->next) {
- if (&(sens_iter->links) == sens_from_links) {
- ob = ob_iter;
- break;
- }
- }
- if (ob) break;
- } CTX_DATA_END;
-
- if (!ob) return;
-
- /* (2) check if the sensor and the actuator are from the same object */
- for (act_iter = ob->actuators.first; act_iter; act_iter = (bActuator *)act_iter->next) {
- if (act_iter == act_to)
- break;
- }
-
- /* only works if the sensor and the actuator are from the same object */
- if (!act_iter) return;
-
- /* in case the linked controller is not the active one */
- RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
-
- WM_operator_properties_create(&props_ptr, "LOGIC_OT_controller_add");
- RNA_string_set(&props_ptr, "object", ob->id.name + 2);
-
- /* (3) add a new controller */
- if (WM_operator_name_call(C, "LOGIC_OT_controller_add", WM_OP_EXEC_DEFAULT, &props_ptr) & OPERATOR_FINISHED) {
- cont = (bController *)ob->controllers.last;
- /* Quick fix to make sure we always have an AND controller.
- * It might be nicer to make sure the operator gives us the right one though... */
- cont->type = CONT_LOGIC_AND;
-
- /* (4) link the sensor->controller->actuator */
- tmp_but = MEM_callocN(sizeof(uiBut), "uiBut");
- UI_but_link_set(
- tmp_but, (void **)&cont, (void ***)&(cont->links),
- &cont->totlinks, from->link->tocode, (int)to->hardmin);
- tmp_but->hardmin = from->link->tocode;
- tmp_but->poin = (char *)cont;
-
- tmp_but->type = UI_BTYPE_INLINK;
- ui_but_link_add(C, from, tmp_but);
-
- tmp_but->type = UI_BTYPE_LINK;
- ui_but_link_add(C, tmp_but, to);
-
- /* (5) garbage collection */
- MEM_freeN(tmp_but->link);
- MEM_freeN(tmp_but);
- }
- WM_operator_properties_free(&props_ptr);
-}
-
-static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to)
-{
- /* in 'from' we have to add a link to 'to' */
- uiLink *link;
- uiLinkLine *line;
- void **oldppoin;
- int a;
-
- if ((line = ui_but_find_link(from, to))) {
- line->flag |= UI_SELECT;
- ui_linkline_remove_active(from->block);
- return;
- }
-
- if (from->type == UI_BTYPE_INLINK && to->type == UI_BTYPE_INLINK) {
- return;
- }
- else if (from->type == UI_BTYPE_LINK && to->type == UI_BTYPE_INLINK) {
- if (from->link->tocode != (int)to->hardmin) {
- ui_but_smart_controller_add(C, from, to);
- return;
- }
- }
- else if (from->type == UI_BTYPE_INLINK && to->type == UI_BTYPE_LINK) {
- if (to->link->tocode == (int)from->hardmin) {
- return;
- }
- }
-
- link = from->link;
-
- /* are there more pointers allowed? */
- if (link->ppoin) {
- oldppoin = *(link->ppoin);
-
- (*(link->totlink))++;
- *(link->ppoin) = MEM_callocN(*(link->totlink) * sizeof(void *), "new link");
-
- for (a = 0; a < (*(link->totlink)) - 1; a++) {
- (*(link->ppoin))[a] = oldppoin[a];
- }
- (*(link->ppoin))[a] = to->poin;
-
- if (oldppoin) MEM_freeN(oldppoin);
- }
- else {
- *(link->poin) = to->poin;
- }
-
-}
-
-
-static void ui_apply_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data)
-{
- ARegion *ar = CTX_wm_region(C);
- uiBut *bt;
-
- for (bt = but->block->buttons.first; bt; bt = bt->next) {
- if (ui_but_contains_point_px(ar, bt, but->linkto[0] + ar->winrct.xmin, but->linkto[1] + ar->winrct.ymin) )
- break;
- }
- if (bt && bt != but) {
- if (!ELEM(bt->type, UI_BTYPE_LINK, UI_BTYPE_INLINK) || !ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK))
- return;
-
- if (but->type == UI_BTYPE_LINK) ui_but_link_add(C, but, bt);
- else ui_but_link_add(C, bt, but);
-
- ui_apply_but_func(C, but);
- data->retval = but->retval;
- }
- data->applied = true;
-}
-
static void ui_apply_but_IMAGE(bContext *C, uiBut *but, uiHandleButtonData *data)
{
ui_apply_but_func(C, but);
@@ -2154,6 +1957,9 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
case UI_BTYPE_LISTROW:
ui_apply_but_ROW(C, block, but, data);
break;
+ case UI_BTYPE_TAB:
+ ui_apply_but_TAB(C, but, data);
+ break;
case UI_BTYPE_SCROLL:
case UI_BTYPE_GRIP:
case UI_BTYPE_NUM:
@@ -2189,10 +1995,6 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
case UI_BTYPE_HOTKEY_EVENT:
ui_apply_but_BUT(C, but, data);
break;
- case UI_BTYPE_LINK:
- case UI_BTYPE_INLINK:
- ui_apply_but_LINK(C, but, data);
- break;
case UI_BTYPE_IMAGE:
ui_apply_but_IMAGE(C, but, data);
break;
@@ -3206,6 +3008,9 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data)
ui_searchbox_free(C, data->searchbox);
data->searchbox = NULL;
+ if (but->free_search_arg) {
+ MEM_SAFE_FREE(but->search_arg);
+ }
}
but->editstr = NULL;
@@ -3677,6 +3482,7 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
uiBlockCreateFunc func = NULL;
uiBlockHandleCreateFunc handlefunc = NULL;
uiMenuCreateFunc menufunc = NULL;
+ uiMenuCreateFunc popoverfunc = NULL;
void *arg = NULL;
switch (but->type) {
@@ -3696,6 +3502,11 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
menufunc = but->menu_create_func;
arg = but->poin;
break;
+ case UI_BTYPE_POPOVER:
+ BLI_assert(but->menu_create_func);
+ popoverfunc = but->menu_create_func;
+ arg = but->poin;
+ break;
case UI_BTYPE_COLOR:
ui_but_v3_get(but, data->origvec);
copy_v3_v3(data->vec, data->origvec);
@@ -3720,6 +3531,11 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
if (but->block->handle)
data->menu->popup = but->block->handle->popup;
}
+ else if (popoverfunc) {
+ data->menu = ui_popover_panel_create(C, data->region, but, popoverfunc, arg);
+ if (but->block->handle)
+ data->menu->popup = but->block->handle->popup;
+ }
#ifdef USE_ALLSELECT
{
@@ -3966,6 +3782,43 @@ static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, c
return BLI_rcti_isect_pt(&icon_rect, x, y);
}
+static int ui_do_but_TAB(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if ((event->type == LEFTMOUSE) &&
+ ((event->val == KM_DBL_CLICK) || event->ctrl))
+ {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && (event->val == KM_CLICK)) {
+ const bool has_icon_extra = ui_but_icon_extra_get(but) == UI_BUT_ICONEXTRA_CLEAR;
+
+ if (has_icon_extra && ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) {
+ uiButTab *tab = (uiButTab *)but;
+ wmOperatorType *ot_backup = but->optype;
+
+ but->optype = tab->unlink_ot;
+ /* Force calling unlink/delete operator. */
+ ui_apply_but(C, block, but, data, true);
+ but->optype = ot_backup;
+ }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_TEXT_EDITING) {
+ ui_do_but_textedit(C, block, but, data, event);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (data->state == BUTTON_STATE_TEXT_SELECTING) {
+ ui_do_but_textedit_select(C, block, but, data, event);
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
static int ui_do_but_TEX(
bContext *C, uiBlock *block, uiBut *but,
uiHandleButtonData *data, const wmEvent *event)
@@ -4394,6 +4247,54 @@ static bool ui_numedit_but_NUM(
return changed;
}
+static void ui_numedit_set_active(uiBut *but)
+{
+ int oldflag = but->drawflag;
+ but->drawflag &= ~(UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT);
+
+ uiHandleButtonData *data = but->active;
+ if (!data) {
+ return;
+ }
+
+ /* Ignore once we start dragging. */
+ if (data->dragchange == false) {
+ const float handle_width = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect) * 0.7f);
+ /* we can click on the side arrows to increment/decrement,
+ * or click inside to edit the value directly */
+ int mx = data->window->eventstate->x;
+ int my = data->window->eventstate->x;
+ ui_window_to_block(data->region, but->block, &mx, &my);
+
+ if (mx < (but->rect.xmin + handle_width)) {
+ but->drawflag |= UI_BUT_ACTIVE_LEFT;
+ }
+ else if (mx > (but->rect.xmax - handle_width)) {
+ but->drawflag |= UI_BUT_ACTIVE_RIGHT;
+ }
+ }
+
+ /* Don't change the cursor once pressed. */
+ if ((but->flag & UI_SELECT) == 0) {
+ if ((but->drawflag & (UI_BUT_ACTIVE_LEFT)) || (but->drawflag & (UI_BUT_ACTIVE_RIGHT))) {
+ if (data->changed_cursor) {
+ WM_cursor_modal_restore(data->window);
+ data->changed_cursor = false;
+ }
+ }
+ else {
+ if (data->changed_cursor == false) {
+ WM_cursor_modal_set(data->window, CURSOR_X_MOVE);
+ data->changed_cursor = true;
+ }
+ }
+ }
+
+ if (but->drawflag != oldflag) {
+ ED_region_tag_redraw(data->region);
+ }
+}
+
static int ui_do_but_NUM(
bContext *C, uiBlock *block, uiBut *but,
uiHandleButtonData *data, const wmEvent *event)
@@ -4407,6 +4308,7 @@ static int ui_do_but_NUM(
my = screen_my = event->y;
ui_window_to_block(data->region, block, &mx, &my);
+ ui_numedit_set_active(but);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
int type = event->type, val = event->val;
@@ -4420,10 +4322,14 @@ static int ui_do_but_NUM(
retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
else if (type == WHEELDOWNMOUSE && event->ctrl) {
mx = but->rect.xmin;
+ but->drawflag &= ~UI_BUT_ACTIVE_RIGHT;
+ but->drawflag |= UI_BUT_ACTIVE_LEFT;
click = 1;
}
else if (type == WHEELUPMOUSE && event->ctrl) {
mx = but->rect.xmax;
+ but->drawflag &= ~UI_BUT_ACTIVE_LEFT;
+ but->drawflag |= UI_BUT_ACTIVE_RIGHT;
click = 1;
}
else if (event->val == KM_PRESS) {
@@ -4516,16 +4422,13 @@ static int ui_do_but_NUM(
/* we can click on the side arrows to increment/decrement,
* or click inside to edit the value directly */
float tempf, softmin, softmax;
- float handlewidth;
int temp;
softmin = but->softmin;
softmax = but->softmax;
- handlewidth = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect));
-
if (!ui_but_is_float(but)) {
- if (mx < (but->rect.xmin + handlewidth)) {
+ if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
temp = (int)data->value - 1;
@@ -4536,7 +4439,7 @@ static int ui_do_but_NUM(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
- else if (mx > (but->rect.xmax - handlewidth)) {
+ else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
temp = (int)data->value + 1;
@@ -4552,7 +4455,7 @@ static int ui_do_but_NUM(
}
}
else {
- if (mx < (but->rect.xmin + handlewidth)) {
+ if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
tempf = (float)data->value - (UI_PRECISION_FLOAT_SCALE * but->a1);
@@ -4561,7 +4464,7 @@ static int ui_do_but_NUM(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
- else if (mx > but->rect.xmax - handlewidth) {
+ else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
tempf = (float)data->value + (UI_PRECISION_FLOAT_SCALE * but->a1);
@@ -5284,7 +5187,8 @@ static int ui_do_but_COLOR(
if (!event->ctrl) {
float color[3];
Scene *scene = CTX_data_scene(C);
- Paint *paint = BKE_paint_get_active(scene);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Paint *paint = BKE_paint_get_active(scene, view_layer);
Brush *brush = BKE_paint_brush(paint);
if (brush->flag & BRUSH_USE_GRADIENT) {
@@ -6201,6 +6105,7 @@ static int ui_do_but_CURVE(
int mx, my, a;
bool changed = false;
Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
mx = event->x;
my = event->y;
@@ -6329,7 +6234,7 @@ static int ui_do_but_CURVE(
}
else {
curvemapping_changed(cumap, true); /* remove doubles */
- BKE_paint_invalidate_cursor_overlay(scene, cumap);
+ BKE_paint_invalidate_cursor_overlay(scene, view_layer, cumap);
}
}
@@ -6495,35 +6400,6 @@ static int ui_do_but_WAVEFORM(
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_LINK(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- VECCOPY2D(but->linkto, event->mval);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_RELEASE);
- return WM_UI_HANDLER_BREAK;
- }
- else if (event->type == LEFTMOUSE && but->block->handle) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
-
- if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- if (!(but->flag & UI_SELECT))
- data->cancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- }
-
- return WM_UI_HANDLER_CONTINUE;
-}
-
static bool ui_numedit_but_TRACKPREVIEW(
bContext *C, uiBut *but, uiHandleButtonData *data,
int mx, int my,
@@ -6667,6 +6543,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
case UI_BTYPE_HOTKEY_EVENT:
retval = ui_do_but_HOTKEYEVT(C, but, data, event);
break;
+ case UI_BTYPE_TAB:
+ retval = ui_do_but_TAB(C, block, but, data, event);
+ break;
case UI_BTYPE_BUT_TOGGLE:
case UI_BTYPE_TOGGLE:
case UI_BTYPE_ICON_TOGGLE:
@@ -6724,6 +6603,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
retval = ui_do_but_TEX(C, block, but, data, event);
break;
case UI_BTYPE_MENU:
+ case UI_BTYPE_POPOVER:
case UI_BTYPE_BLOCK:
case UI_BTYPE_PULLDOWN:
retval = ui_do_but_BLOCK(C, but, data, event);
@@ -6752,10 +6632,6 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
case UI_BTYPE_HSVCIRCLE:
retval = ui_do_but_HSVCIRCLE(C, block, but, data, event);
break;
- case UI_BTYPE_LINK:
- case UI_BTYPE_INLINK:
- retval = ui_do_but_LINK(C, but, data, event);
- break;
case UI_BTYPE_TRACK_PREVIEW:
retval = ui_do_but_TRACKPREVIEW(C, block, but, data, event);
break;
@@ -6763,6 +6639,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
/* quiet warnings for unhandled types */
case UI_BTYPE_SEPR:
case UI_BTYPE_SEPR_LINE:
+ case UI_BTYPE_SEPR_SPACER:
case UI_BTYPE_EXTRA:
break;
}
@@ -6939,12 +6816,11 @@ bool ui_but_is_active(ARegion *ar)
/* is called by notifier */
void UI_screen_free_active_but(const bContext *C, bScreen *screen)
{
- ScrArea *sa = screen->areabase.first;
+ wmWindow *win = CTX_wm_window(C);
- for (; sa; sa = sa->next) {
- ARegion *ar = sa->regionbase.first;
- for (; ar; ar = ar->next) {
- uiBut *but = ui_but_find_active_in_region(ar);
+ ED_screen_areas_iter(win, screen, area) {
+ for (ARegion *region = area->regionbase.first; region; region = region->next) {
+ uiBut *but = ui_but_find_active_in_region(region);
if (but) {
uiHandleButtonData *data = but->active;
@@ -7030,7 +6906,7 @@ static bool ui_region_contains_point_px(ARegion *ar, int x, int y)
ui_window_to_region(ar, &mx, &my);
/* check if in the rect */
- if (!BLI_rcti_isect_pt(&v2d->mask, mx, my)) {
+ if (!BLI_rcti_isect_pt(&v2d->mask, mx, my) || UI_view2d_mouse_in_scrollers(ar, &ar->v2d, x, y)) {
return false;
}
}
@@ -7185,7 +7061,7 @@ void UI_but_tooltip_refresh(bContext *C, uiBut *but)
{
uiHandleButtonData *data = but->active;
if (data) {
- bScreen *sc = data->window->screen;
+ bScreen *sc = WM_window_get_active_screen(data->window);
if (sc->tool_tip && sc->tool_tip->region) {
WM_tooltip_refresh(C, data->window);
}
@@ -7254,7 +7130,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
button_tooltip_timer_reset(C, but);
/* automatic open pulldown block timer */
- if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) {
+ if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) {
if (data->used_mouse && !data->autoopentimer) {
int time;
@@ -7464,6 +7340,9 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
WM_cursor_modal_set(data->window, horizontal ? CURSOR_X_MOVE : CURSOR_Y_MOVE);
}
+ else if (but->type == UI_BTYPE_NUM) {
+ ui_numedit_set_active(but);
+ }
}
static void button_activate_exit(
@@ -7557,8 +7436,13 @@ static void button_activate_exit(
ui_selectcontext_end(but, &data->select_others);
#endif
- /* redraw (data is but->active!) */
+ if (data->changed_cursor) {
+ WM_cursor_modal_restore(data->window);
+ }
+
+ /* redraw and refresh (for popups) */
ED_region_tag_redraw(data->region);
+ ED_region_tag_refresh_ui(data->region);
/* clean up button */
if (but->active) {
@@ -7744,6 +7628,11 @@ void UI_context_update_anim_flag(const bContext *C)
for (block = ar->uiblocks.first; block; block = block->next) {
for (but = block->buttons.first; but; but = but->next) {
ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
+ ui_but_override_flag(but);
+ if (UI_but_is_decorator(but)) {
+ ui_but_anim_decorate_update_from_flag(but);
+ }
+
ED_region_tag_redraw(ar);
if (but->active) {
@@ -7931,8 +7820,29 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
case EVT_BUT_CANCEL:
data->cancel = true;
button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval = WM_UI_HANDLER_CONTINUE;
break;
+#ifdef USE_UI_POPOVER_ONCE
+ case LEFTMOUSE:
+ {
+ if (event->val == KM_RELEASE) {
+ if (block->flag & UI_BLOCK_POPOVER_ONCE) {
+ if (!(but->flag & UI_BUT_DISABLED)) {
+ if (ui_but_is_popover_once_compat(but)) {
+ data->cancel = false;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval = WM_UI_HANDLER_BREAK;
+ block->handle->menuretval = UI_RETURN_OK;
+ }
+ else if (ui_but_is_editable_as_text(but)) {
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_TEXT_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ }
+ break;
+ }
+#endif
case MOUSEMOVE:
{
uiBut *but_other = ui_but_find_mouse_over(ar, event);
@@ -7971,7 +7881,6 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
}
- retval = WM_UI_HANDLER_CONTINUE;
break;
}
/* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
@@ -7982,10 +7891,11 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
UI_but_tooltip_timer_remove(C, but);
ATTR_FALLTHROUGH;
default:
- /* handle button type specific events */
- retval = ui_do_button(C, block, but, event);
break;
}
+
+ /* handle button type specific events */
+ retval = ui_do_button(C, block, but, event);
}
else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
switch (event->type) {
@@ -8014,12 +7924,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
break;
}
case MOUSEMOVE:
- if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) {
- but->flag |= UI_SELECT;
- ui_do_button(C, block, but, event);
- ED_region_tag_redraw(ar);
- }
- else {
+ {
/* deselect the button when moving the mouse away */
/* also de-activate for buttons that only show higlights */
if (ui_but_contains_point_px(ar, but, event->x, event->y)) {
@@ -8282,13 +8187,8 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar,
}
if (redraw) {
- if (listbox->block->flag & UI_BLOCK_POPUP) {
- /* popups need special refreshing */
- ED_region_tag_refresh_ui(ar);
- }
- else {
- ED_region_tag_redraw(ar);
- }
+ ED_region_tag_redraw(ar);
+ ED_region_tag_refresh_ui(ar);
}
return retval;
@@ -8547,6 +8447,9 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD;
}
+ /* remember scroll offset for refreshes */
+ block->handle->scrolloffset += dy;
+
/* apply scroll offset */
for (bt = block->buttons.first; bt; bt = bt->next) {
bt->rect.ymin += dy;
@@ -8699,7 +8602,7 @@ static int ui_handle_menu_event(
add_v2_v2v2_int(menu->popup_create_vars.event_xy, menu->popup_create_vars.event_xy, mdiff);
- ui_popup_translate(C, ar, mdiff);
+ ui_popup_translate(ar, mdiff);
}
return retval;
@@ -9083,6 +8986,15 @@ static int ui_handle_menu_event(
retval = ui_handle_menu_button(C, event, menu);
}
+#ifdef USE_UI_POPOVER_ONCE
+ if (block->flag & UI_BLOCK_POPOVER_ONCE) {
+ if ((event->type == LEFTMOUSE) && (event->val == KM_RELEASE)) {
+ UI_popover_once_clear(menu->popup_create_vars.arg);
+ block->flag &= ~UI_BLOCK_POPOVER_ONCE;
+ }
+ }
+#endif
+
/* Don't handle double click events, rehandle as regular press/release. */
if (retval == WM_UI_HANDLER_CONTINUE && event->val == KM_DBL_CLICK) {
return retval;
@@ -9702,10 +9614,10 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
if ((data->state == BUTTON_STATE_MENU_OPEN) &&
(is_inside_menu == false) && /* make sure mouse isn't inside another menu (see T43247) */
- (but->type == UI_BTYPE_PULLDOWN) &&
+ (ELEM(but->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) &&
(but_other = ui_but_find_mouse_over(ar, event)) &&
(but != but_other) &&
- (but->type == but_other->type))
+ (ELEM(but_other->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)))
{
/* if mouse moves to a different root-level menu button,
* open it to replace the current menu */
@@ -9962,3 +9874,18 @@ void ui_but_clipboard_free(void)
{
curvemapping_free_data(&but_copypaste_curve);
}
+
+bool UI_but_is_tool(const uiBut *but)
+{
+ /* very evil! */
+ if (but->optype != NULL) {
+ static wmOperatorType *ot = NULL;
+ if (ot == NULL) {
+ ot = WM_operatortype_find("WM_OT_tool_set_by_name", false);
+ }
+ if (but->optype == ot) {
+ return true;
+ }
+ }
+ return false;
+}