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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-23 09:43:50 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-23 09:51:00 +0300
commitbe3adb51de21652d64a6839cd5614c5096064c6a (patch)
treeb76f6346673205ed3aeb33a4768bd2a182a4c605 /source/blender/editors/screen
parent310f288bb03b4197f54b7d7b6d611669f2604d04 (diff)
UI: ignore events in empty region overlap areas
- Resizable areas use 2D view bounds. - Header uses the button bounds. - A margin is added to avoid clicking between buttons. - Region resize edges clamp to the 2D view bounds. Resovles T61554
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r--source/blender/editors/screen/CMakeLists.txt1
-rw-r--r--source/blender/editors/screen/area.c32
-rw-r--r--source/blender/editors/screen/area_query.c123
-rw-r--r--source/blender/editors/screen/screen_edit.c2
4 files changed, 157 insertions, 1 deletions
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt
index daa72ac194c..9576920bcd2 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -39,6 +39,7 @@ set(INC_SYS
set(SRC
area.c
+ area_query.c
area_utils.c
glutil.c
screen_context.c
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 5923d0373d5..ab68b3cfcf8 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -901,33 +901,65 @@ static void fullscreen_azone_initialize(ScrArea *sa, ARegion *ar)
#define AZONEPAD_ICON (0.45f * U.widget_unit)
static void region_azone_edge(AZone *az, ARegion *ar)
{
+ int clip_axis = -1;
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
az->x1 = ar->winrct.xmin;
az->y1 = ar->winrct.ymax - AZONEPAD_EDGE;
az->x2 = ar->winrct.xmax;
az->y2 = ar->winrct.ymax + AZONEPAD_EDGE;
+ if (ar->overlap) {
+ clip_axis = 0;
+ }
break;
case AE_BOTTOM_TO_TOPLEFT:
az->x1 = ar->winrct.xmin;
az->y1 = ar->winrct.ymin + AZONEPAD_EDGE;
az->x2 = ar->winrct.xmax;
az->y2 = ar->winrct.ymin - AZONEPAD_EDGE;
+ if (ar->overlap) {
+ clip_axis = 0;
+ }
break;
case AE_LEFT_TO_TOPRIGHT:
az->x1 = ar->winrct.xmin - AZONEPAD_EDGE;
az->y1 = ar->winrct.ymin;
az->x2 = ar->winrct.xmin + AZONEPAD_EDGE;
az->y2 = ar->winrct.ymax;
+ if (ar->overlap) {
+ clip_axis = 1;
+ }
break;
case AE_RIGHT_TO_TOPLEFT:
az->x1 = ar->winrct.xmax + AZONEPAD_EDGE;
az->y1 = ar->winrct.ymin;
az->x2 = ar->winrct.xmax - AZONEPAD_EDGE;
az->y2 = ar->winrct.ymax;
+ if (ar->overlap) {
+ clip_axis = 1;
+ }
break;
}
+ /* Constrain action zones to usable area of region.
+ * Needed so blank areas of the region are interactive and aciton zones don't get in the way. */
+ if (clip_axis == 0) {
+ az->x1 = max_ii(az->x1,
+ (ar->winrct.xmin + UI_view2d_view_to_region_x(&ar->v2d, ar->v2d.tot.xmin)) -
+ UI_REGION_OVERLAP_MARGIN);
+ az->x2 = min_ii(az->x2,
+ (ar->winrct.xmin + UI_view2d_view_to_region_x(&ar->v2d, ar->v2d.tot.xmax)) +
+ UI_REGION_OVERLAP_MARGIN);
+ }
+ else if (clip_axis == 1) {
+ az->y1 = max_ii(az->y1,
+ (ar->winrct.ymin + UI_view2d_view_to_region_y(&ar->v2d, ar->v2d.tot.ymin)) -
+ UI_REGION_OVERLAP_MARGIN);
+ az->y2 = min_ii(az->y2,
+ (ar->winrct.ymin + UI_view2d_view_to_region_y(&ar->v2d, ar->v2d.tot.ymax)) +
+ UI_REGION_OVERLAP_MARGIN);
+ }
+
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
diff --git a/source/blender/editors/screen/area_query.c b/source/blender/editors/screen/area_query.c
new file mode 100644
index 00000000000..a4bcf622815
--- /dev/null
+++ b/source/blender/editors/screen/area_query.c
@@ -0,0 +1,123 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup edscr
+ *
+ * Query functions for area/region.
+ */
+
+#include "DNA_userdef_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_types.h"
+
+#include "WM_api.h"
+
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_view2d.h"
+
+bool ED_region_overlap_isect_x(const ARegion *ar, const int event_x)
+{
+ BLI_assert(ar->overlap);
+ /* No contents, skip it. */
+ if (ar->v2d.mask.xmin == ar->v2d.mask.xmax) {
+ return false;
+ }
+ return BLI_rctf_isect_x(&ar->v2d.tot,
+ UI_view2d_region_to_view_x(&ar->v2d, event_x - ar->winrct.xmin));
+}
+
+bool ED_region_overlap_isect_y(const ARegion *ar, const int event_y)
+{
+ BLI_assert(ar->overlap);
+ /* No contents, skip it. */
+ if (ar->v2d.mask.ymin == ar->v2d.mask.ymax) {
+ return false;
+ }
+ return BLI_rctf_isect_y(&ar->v2d.tot,
+ UI_view2d_region_to_view_y(&ar->v2d, event_y - ar->winrct.ymin));
+}
+
+bool ED_region_overlap_isect_xy(const ARegion *ar, const int event_xy[2])
+{
+ return (ED_region_overlap_isect_x(ar, event_xy[0]) &&
+ ED_region_overlap_isect_y(ar, event_xy[1]));
+}
+
+bool ED_region_overlap_isect_x_with_margin(const ARegion *ar, const int event_x, const int margin)
+{
+ BLI_assert(ar->overlap);
+ /* No contents, skip it. */
+ if (ar->v2d.mask.xmin == ar->v2d.mask.xmax) {
+ return false;
+ }
+ int region_x = event_x - ar->winrct.xmin;
+ return ((ar->v2d.tot.xmin <= UI_view2d_region_to_view_x(&ar->v2d, region_x + margin)) &&
+ (ar->v2d.tot.xmax >= UI_view2d_region_to_view_x(&ar->v2d, region_x - margin)));
+}
+
+bool ED_region_overlap_isect_y_with_margin(const ARegion *ar, const int event_y, const int margin)
+{
+ BLI_assert(ar->overlap);
+ /* No contents, skip it. */
+ if (ar->v2d.mask.ymin == ar->v2d.mask.ymax) {
+ return false;
+ }
+ int region_y = event_y - ar->winrct.ymin;
+ return ((ar->v2d.tot.ymin <= UI_view2d_region_to_view_y(&ar->v2d, region_y + margin)) &&
+ (ar->v2d.tot.ymax >= UI_view2d_region_to_view_y(&ar->v2d, region_y - margin)));
+}
+
+bool ED_region_overlap_isect_xy_with_margin(const ARegion *ar,
+ const int event_xy[2],
+ const int margin)
+{
+ return (ED_region_overlap_isect_x_with_margin(ar, event_xy[0], margin) &&
+ ED_region_overlap_isect_y_with_margin(ar, event_xy[1], margin));
+}
+
+bool ED_region_contains_xy(const ARegion *ar, const int event_xy[2])
+{
+ /* Only use the margin when inside the region. */
+ if (BLI_rcti_isect_pt_v(&ar->winrct, event_xy)) {
+ if (ar->overlap) {
+ const int overlap_margin = UI_REGION_OVERLAP_MARGIN;
+ /* Note the View2D.tot isn't reliable for headers with spacers otherwise
+ * we'd check #ED_region_overlap_isect_xy_with_margin for both bases. */
+ if (ar->v2d.keeptot == V2D_KEEPTOT_STRICT) {
+ /* Header. */
+ rcti rect;
+ BLI_rcti_init_pt_radius(&rect, event_xy, overlap_margin);
+ if (UI_region_but_find_rect_over(ar, &rect) == NULL) {
+ return false;
+ }
+ }
+ else {
+ /* Side-bar & any other kind of overlapping region. */
+ if (!ED_region_overlap_isect_xy_with_margin(ar, event_xy, overlap_margin)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 95bade1da64..50f0ab9b96b 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -683,7 +683,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
if (sa) {
/* make overlap active when mouse over */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (BLI_rcti_isect_pt_v(&ar->winrct, xy)) {
+ if (ED_region_contains_xy(ar, xy)) {
scr->active_region = ar;
break;
}