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')
-rw-r--r--source/blender/editors/interface/interface_handlers.c52
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_ops.c106
-rw-r--r--source/blender/editors/interface/interface_regions.c23
4 files changed, 133 insertions, 50 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b3f13ccdb35..3be0c9c0524 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -385,7 +385,7 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val)
}
}
-static bool ui_but_is_editable(const uiBut *but)
+bool ui_but_is_editable(const uiBut *but)
{
return !ELEM(but->type, LABEL, SEPR, SEPRLINE, ROUNDBOX, LISTBOX, PROGRESSBAR);
}
@@ -7199,6 +7199,17 @@ void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but)
ui_do_button(C, but->block, but, &event);
}
+/**
+ * Simulate moving the mouse over a button (or navigating to it with arrow keys).
+ *
+ * exported so menus can start with a highlighted button,
+ * even if the mouse isnt over it
+ */
+void ui_button_activate_over(bContext *C, ARegion *ar, uiBut *but)
+{
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+}
+
void ui_button_execute_begin(struct bContext *UNUSED(C), struct ARegion *ar, uiBut *but, void **active_back)
{
/* note: ideally we would not have to change 'but->active' however
@@ -7261,12 +7272,20 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
retval = WM_UI_HANDLER_CONTINUE;
break;
case MOUSEMOVE:
- /* verify if we are still over the button, if not exit */
- if (!ui_mouse_inside_button(ar, but, event->x, event->y)) {
- data->cancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
+ {
+ uiBut *but_other = ui_but_find_mouse_over(ar, event);
+ bool exit = false;
+
+ if (!ui_block_is_menu(block) &&
+ !ui_mouse_inside_button(ar, but, event->x, event->y))
+ {
+ exit = true;
}
- else if (ui_but_find_mouse_over(ar, event) != but) {
+ else if (but_other && ui_but_is_editable(but_other) && (but_other != but)) {
+ exit = true;
+ }
+
+ if (exit) {
data->cancel = true;
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
@@ -7277,6 +7296,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
}
break;
+ }
case TIMER:
{
/* handle tooltip timer */
@@ -7860,6 +7880,22 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
int retval;
if (but) {
+ /* Its possible there is an active menu item NOT under the mouse,
+ * in this case ignore mouse clicks outside the button (but Enter etc is accepted) */
+ if (event->val == KM_RELEASE) {
+ /* pass, needed so we can exit active menu-items when click-dragging out of them */
+ }
+ else if (!ui_mouse_inside_region(but->active->region, event->x, event->y)) {
+ /* pass, needed to click-exit outside of non-flaoting menus */
+ }
+ else if ((event->type != MOUSEMOVE) && ISMOUSE(event->type)) {
+ if (!ui_mouse_inside_button(but->active->region, but, event->x, event->y)) {
+ but = NULL;
+ }
+ }
+ }
+
+ if (but) {
ScrArea *ctx_area = CTX_wm_area(C);
ARegion *ctx_region = CTX_wm_region(C);
@@ -8268,6 +8304,10 @@ static int ui_handle_menu_event(
(inside && is_floating && inside_title))
{
if (!but || !ui_mouse_inside_button(ar, but, event->x, event->y)) {
+ if (but) {
+ button_timers_tooltip_remove(C, but);
+ }
+
menu->is_grab = true;
copy_v2_v2_int(menu->grab_xy_prev, &event->x);
retval = WM_UI_HANDLER_BREAK;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index fa8b6b1ffee..7d03aaea6b3 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -552,6 +552,7 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol
PointerRNA *ui_handle_afterfunc_add_operator(struct wmOperatorType *ot, int opcontext, bool create_props);
extern void ui_pan_to_scroll(const struct wmEvent *event, int *type, int *val);
extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but);
+extern void ui_button_activate_over(struct bContext *C, struct ARegion *ar, uiBut *but);
extern void ui_button_execute_begin(struct bContext *C, struct ARegion *ar, uiBut *but, void **active_back);
extern void ui_button_execute_end(struct bContext *C, struct ARegion *ar, uiBut *but, void *active_back);
extern void ui_button_active_free(const struct bContext *C, uiBut *but);
@@ -559,6 +560,7 @@ extern bool ui_button_is_active(struct ARegion *ar) ATTR_WARN_UNUSED_RESULT;
extern int ui_button_open_menu_direction(uiBut *but);
extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, const bool restore);
extern uiBut *ui_but_find_activated(struct ARegion *ar);
+bool ui_but_is_editable(const uiBut *but);
void ui_button_clipboard_free(void);
void ui_panel_menu(struct bContext *C, ARegion *ar, Panel *pa);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 32b073ba269..458aca444cb 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -262,28 +262,43 @@ static void UI_OT_unset_property_button(wmOperatorType *ot)
/* Copy To Selected Operator ------------------------ */
-static bool copy_to_selected_list(bContext *C, PointerRNA *ptr, ListBase *lb, bool *use_path)
+static bool copy_to_selected_list(
+ bContext *C, PointerRNA *ptr, PropertyRNA *prop,
+ ListBase *r_lb, bool *r_use_path_from_id, char **r_path)
{
- *use_path = false;
+ *r_use_path_from_id = false;
+ *r_path = NULL;
- if (RNA_struct_is_a(ptr->type, &RNA_EditBone))
- *lb = CTX_data_collection_get(C, "selected_editable_bones");
- else if (RNA_struct_is_a(ptr->type, &RNA_PoseBone))
- *lb = CTX_data_collection_get(C, "selected_pose_bones");
- else if (RNA_struct_is_a(ptr->type, &RNA_Sequence))
- *lb = CTX_data_collection_get(C, "selected_editable_sequences");
- else {
+ if (RNA_struct_is_a(ptr->type, &RNA_EditBone)) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_bones");
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) {
+ *r_lb = CTX_data_collection_get(C, "selected_pose_bones");
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
+ }
+ else if (ptr->id.data) {
ID *id = ptr->id.data;
- if (id && GS(id->name) == ID_OB) {
- *lb = CTX_data_collection_get(C, "selected_editable_objects");
- *use_path = true;
+ if (GS(id->name) == ID_OB) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_objects");
+ *r_use_path_from_id = true;
+ *r_path = RNA_path_from_ID_to_property(ptr, prop);
}
- else {
- return false;
+ else if (GS(id->name) == ID_SCE) {
+ /* Sequencer's ID is scene :/ */
+ /* Try to recursively find an RNA_Sequence ancestor, to handle situations like T41062... */
+ if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != NULL) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
+ }
}
+ return (*r_path != NULL);
}
-
+ else {
+ return false;
+ }
+
return true;
}
@@ -307,47 +322,54 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll)
/* if there is a valid property that is editable... */
if (ptr.data && prop) {
char *path = NULL;
- bool use_path;
+ bool use_path_from_id;
CollectionPointerLink *link;
ListBase lb;
- if (!copy_to_selected_list(C, &ptr, &lb, &use_path))
+ if (!copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path))
return success;
- if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) {
- for (link = lb.first; link; link = link->next) {
- if (link->ptr.data != ptr.data) {
- if (use_path) {
- lprop = NULL;
- RNA_id_pointer_create(link->ptr.id.data, &idptr);
- RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
- }
- else {
- lptr = link->ptr;
- lprop = prop;
- }
+ for (link = lb.first; link; link = link->next) {
+ if (link->ptr.data != ptr.data) {
+ if (use_path_from_id) {
+ /* Path relative to ID. */
+ lprop = NULL;
+ RNA_id_pointer_create(link->ptr.id.data, &idptr);
+ RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
+ }
+ else if (path) {
+ /* Path relative to elements from list. */
+ lprop = NULL;
+ RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop);
+ }
+ else {
+ lptr = link->ptr;
+ lprop = prop;
+ }
- if (lprop == prop) {
- if (RNA_property_editable(&lptr, lprop)) {
- if (poll) {
+ if (lptr.data == ptr.data) {
+ /* lptr might not be the same as link->ptr! */
+ continue;
+ }
+
+ if (lprop == prop) {
+ if (RNA_property_editable(&lptr, lprop)) {
+ if (poll) {
+ success = true;
+ break;
+ }
+ else {
+ if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) {
+ RNA_property_update(C, &lptr, prop);
success = true;
- break;
- }
- else {
- if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) {
- RNA_property_update(C, &lptr, prop);
- success = true;
- }
}
}
}
}
}
-
- if (path)
- MEM_freeN(path);
}
+ MEM_SAFE_FREE(path);
BLI_freelistN(&lb);
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 85bf15e15cf..3629c72ce49 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1872,7 +1872,7 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3], bool is
if (rgb_gamma[2] > 1.0f) rgb_gamma[2] = modf(rgb_gamma[2], &intpart);
rgb_float_to_uchar(rgb_gamma_uchar, rgb_gamma);
- BLI_snprintf(col, sizeof(col), "%02X%02X%02X", UNPACK3OP((unsigned int), rgb_gamma_uchar));
+ BLI_snprintf(col, sizeof(col), "%02X%02X%02X", UNPACK3_EX((unsigned int), rgb_gamma_uchar, ));
strcpy(bt->poin, col);
}
@@ -2160,7 +2160,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
}
rgb_float_to_uchar(rgb_gamma_uchar, rgb_gamma);
- BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", UNPACK3OP((unsigned int), rgb_gamma_uchar));
+ BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", UNPACK3_EX((unsigned int), rgb_gamma_uchar, ));
yco = -3.0f * UI_UNIT_Y;
bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)"));
@@ -2408,6 +2408,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
if (pup->popup) {
+ uiBut *but_activate = NULL;
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_NUMSELECT);
uiBlockSetDirection(block, direction);
@@ -2421,6 +2422,10 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
* block to be under the mouse */
offset[0] = -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect));
offset[1] = -(bt->rect.ymin + 0.5f * UI_UNIT_Y);
+
+ if (ui_but_is_editable(bt)) {
+ but_activate = bt;
+ }
}
else {
/* position mouse at 0.8*width of the button and below the tile
@@ -2430,6 +2435,20 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
offset[0] = min_ii(offset[0], -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect)));
offset[1] = 2.1 * UI_UNIT_Y;
+
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ if (ui_but_is_editable(bt)) {
+ but_activate = bt;
+ break;
+ }
+ }
+ }
+
+ /* in rare cases this is needed since moving the popup
+ * to be within the window bounds may move it away from the mouse,
+ * This ensures we set an item to be active. */
+ if (but_activate) {
+ ui_button_activate_over(C, handle->region, but_activate);
}
block->minbounds = minwidth;