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:
authorSeverin <eiseljulian@gmail.com>2018-06-30 22:12:19 +0300
committerSeverin <eiseljulian@gmail.com>2018-06-30 22:12:19 +0300
commite5f49598b037ef8476efd458d060d3db348b9b60 (patch)
treeb3a3fe2796ad1ad2ba831e53b944e98013df0648 /source/blender/editors/screen
parentb088a387915950c9419d5326e7269bea3869d140 (diff)
parent7d48a342d66cc7664b008ff512bd00e740eb7629 (diff)
Merge branch 'blender2.8' into temp-tab_drag_drop
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r--source/blender/editors/screen/CMakeLists.txt2
-rw-r--r--source/blender/editors/screen/area.c718
-rw-r--r--source/blender/editors/screen/glutil.c23
-rw-r--r--source/blender/editors/screen/screen_context.c51
-rw-r--r--source/blender/editors/screen/screen_draw.c31
-rw-r--r--source/blender/editors/screen/screen_edit.c716
-rw-r--r--source/blender/editors/screen/screen_geometry.c462
-rw-r--r--source/blender/editors/screen/screen_intern.h32
-rw-r--r--source/blender/editors/screen/screen_ops.c1328
-rw-r--r--source/blender/editors/screen/screen_user_menu.c196
-rw-r--r--source/blender/editors/screen/screendump.c286
-rw-r--r--source/blender/editors/screen/workspace_edit.c26
-rw-r--r--source/blender/editors/screen/workspace_layout_edit.c14
13 files changed, 2212 insertions, 1673 deletions
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt
index 29b9971eabb..4be65f60b21 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -46,7 +46,9 @@ set(SRC
screen_context.c
screen_draw.c
screen_edit.c
+ screen_geometry.c
screen_ops.c
+ screen_user_menu.c
screendump.c
workspace_edit.c
workspace_layout_edit.c
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index ad4f6b0179d..207047c2ad3 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -4,7 +4,7 @@
* 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.
+ * 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
@@ -18,7 +18,7 @@
* The Original Code is Copyright (C) 2008 Blender Foundation.
* All rights reserved.
*
- *
+ *
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
@@ -52,6 +52,7 @@
#include "WM_api.h"
#include "WM_types.h"
#include "WM_message.h"
+#include "WM_toolsystem.h"
#include "ED_screen.h"
#include "ED_screen_types.h"
@@ -61,6 +62,8 @@
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
#include "GPU_draw.h"
+#include "GPU_state.h"
+#include "GPU_framebuffer.h"
#include "BLF_api.h"
@@ -96,8 +99,8 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct, int sides)
rect.ymax = scirct->ymax - ar->winrct.ymin;
/* set transp line */
- glEnable(GL_BLEND);
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+ GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
float color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color);
@@ -136,7 +139,7 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct, int sides)
immEnd();
immUnbindProgram();
- glDisable(GL_BLEND);
+ GPU_blend(false);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
@@ -225,7 +228,7 @@ void ED_area_azones_update(ScrArea *sa, const int mouse_xy[2])
if (changed) {
sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE;
- ED_area_tag_redraw(sa);
+ ED_area_tag_redraw_no_rebuild(sa);
}
}
@@ -295,7 +298,7 @@ static void draw_azone_plus(float x1, float y1, float x2, float y2)
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- glEnable(GL_BLEND);
+ GPU_blend(true);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4f(0.8f, 0.8f, 0.8f, 0.4f);
@@ -304,13 +307,13 @@ static void draw_azone_plus(float x1, float y1, float x2, float y2)
immRectf(pos, (x1 + x2 + width) * 0.5f, (y1 + y2 - width) * 0.5f, x2 - pad, (y1 + y2 + width) * 0.5f);
immUnbindProgram();
- glDisable(GL_BLEND);
+ GPU_blend(false);
}
static void region_draw_azone_tab_plus(AZone *az)
{
- glEnable(GL_BLEND);
-
+ GPU_blend(true);
+
/* add code to draw region hidden as 'too small' */
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
@@ -345,13 +348,13 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
if (!sa)
return;
- glLineWidth(1.0f);
- glEnable(GL_BLEND);
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_line_width(1.0f);
+ GPU_blend(true);
+ GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
gpuPushMatrix();
gpuTranslate2f(-ar->winrct.xmin, -ar->winrct.ymin);
-
+
for (az = sa->actionzones.first; az; az = az->next) {
/* test if action zone is over this region */
rcti azrct;
@@ -387,7 +390,7 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
gpuPopMatrix();
- glDisable(GL_BLEND);
+ GPU_blend(false);
}
/* Follow wmMsgNotifyFn spec */
@@ -418,6 +421,17 @@ void ED_area_do_msg_notify_tag_refresh(
ED_area_tag_refresh(sa);
}
+/**
+ * Although there's no general support for minimizing areas, the status-bar can
+ * be snapped to be only a few pixels high. A few pixels rather than 0 so it
+ * can be un-minimized again. We consider it pseudo-minimalized and don't draw
+ * it then.
+ */
+static bool area_is_pseudo_minimized(const ScrArea *area)
+{
+ return (area->winx < 3) || (area->winy < 3);
+}
+
/* only exported for WM */
void ED_region_do_layout(bContext *C, ARegion *ar)
{
@@ -429,7 +443,7 @@ void ED_region_do_layout(bContext *C, ARegion *ar)
return;
}
- if (at->do_lock) {
+ if (at->do_lock || (sa && area_is_pseudo_minimized(sa))) {
return;
}
@@ -451,19 +465,24 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
return;
ar->do_draw |= RGN_DRAWING;
-
+
/* Set viewport, scissor, ortho and ar->drawrct. */
wmPartialViewport(&ar->drawrct, &ar->winrct, &ar->drawrct);
wmOrtho2_region_pixelspace(ar);
-
+
UI_SetTheme(sa ? sa->spacetype : 0, at->regionid);
-
+
+ if (sa && area_is_pseudo_minimized(sa)) {
+ UI_ThemeClearColor(TH_EDITOR_OUTLINE);
+ glClear(GL_COLOR_BUFFER_BIT);
+ return;
+ }
/* optional header info instead? */
- if (ar->headerstr) {
+ else if (ar->headerstr) {
UI_ThemeClearColor(TH_HEADER);
glClear(GL_COLOR_BUFFER_BIT);
-
+
UI_FontThemeColor(BLF_default(), TH_TEXT);
BLF_draw_default(UI_UNIT_X, 0.4f * UI_UNIT_Y, 0.0f, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX);
}
@@ -480,7 +499,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
/* for debugging unneeded area redraws and partial redraw */
#if 0
- glEnable(GL_BLEND);
+ GPU_blend(true);
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -488,11 +507,11 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
immRectf(pos, ar->drawrct.xmin - ar->winrct.xmin, ar->drawrct.ymin - ar->winrct.ymin,
ar->drawrct.xmax - ar->winrct.xmin, ar->drawrct.ymax - ar->winrct.ymin);
immUnbindProgram();
- glDisable(GL_BLEND);
+ GPU_blend(false);
#endif
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
-
+
UI_blocklist_free_inactive(C, &ar->uiblocks);
if (sa) {
@@ -550,7 +569,7 @@ void ED_region_tag_redraw(ARegion *ar)
* but python scripts can cause this to happen indirectly */
if (ar && !(ar->do_draw & RGN_DRAWING)) {
/* zero region means full region redraw */
- ar->do_draw &= ~RGN_DRAW_PARTIAL;
+ ar->do_draw &= ~(RGN_DRAW_PARTIAL | RGN_DRAW_NO_REBUILD);
ar->do_draw |= RGN_DRAW;
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
}
@@ -562,6 +581,15 @@ void ED_region_tag_redraw_overlay(ARegion *ar)
ar->do_draw_overlay = RGN_DRAW;
}
+void ED_region_tag_redraw_no_rebuild(ARegion *ar)
+{
+ if (ar && !(ar->do_draw & (RGN_DRAWING | RGN_DRAW))) {
+ ar->do_draw &= ~RGN_DRAW_PARTIAL;
+ ar->do_draw |= RGN_DRAW_NO_REBUILD;
+ memset(&ar->drawrct, 0, sizeof(ar->drawrct));
+ }
+}
+
void ED_region_tag_refresh_ui(ARegion *ar)
{
if (ar) {
@@ -572,7 +600,7 @@ void ED_region_tag_refresh_ui(ARegion *ar)
void ED_region_tag_redraw_partial(ARegion *ar, const rcti *rct)
{
if (ar && !(ar->do_draw & RGN_DRAWING)) {
- if (!(ar->do_draw & (RGN_DRAW | RGN_DRAW_PARTIAL))) {
+ if (!(ar->do_draw & (RGN_DRAW | RGN_DRAW_NO_REBUILD | RGN_DRAW_PARTIAL))) {
/* no redraw set yet, set partial region */
ar->do_draw |= RGN_DRAW_PARTIAL;
ar->drawrct = *rct;
@@ -583,7 +611,7 @@ void ED_region_tag_redraw_partial(ARegion *ar, const rcti *rct)
BLI_rcti_union(&ar->drawrct, rct);
}
else {
- BLI_assert((ar->do_draw & RGN_DRAW) != 0);
+ BLI_assert((ar->do_draw & (RGN_DRAW | RGN_DRAW_NO_REBUILD)) != 0);
/* Else, full redraw is already requested, nothing to do here. */
}
}
@@ -592,16 +620,25 @@ void ED_region_tag_redraw_partial(ARegion *ar, const rcti *rct)
void ED_area_tag_redraw(ScrArea *sa)
{
ARegion *ar;
-
+
if (sa)
for (ar = sa->regionbase.first; ar; ar = ar->next)
ED_region_tag_redraw(ar);
}
+void ED_area_tag_redraw_no_rebuild(ScrArea *sa)
+{
+ ARegion *ar;
+
+ if (sa)
+ for (ar = sa->regionbase.first; ar; ar = ar->next)
+ ED_region_tag_redraw_no_rebuild(ar);
+}
+
void ED_area_tag_redraw_regiontype(ScrArea *sa, int regiontype)
{
ARegion *ar;
-
+
if (sa) {
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->regiontype == regiontype) {
@@ -620,7 +657,7 @@ void ED_area_tag_refresh(ScrArea *sa)
/* *************************************************************** */
/* use NULL to disable it */
-void ED_area_headerprint(ScrArea *sa, const char *str)
+void ED_area_status_text(ScrArea *sa, const char *str)
{
ARegion *ar;
@@ -644,13 +681,41 @@ void ED_area_headerprint(ScrArea *sa, const char *str)
}
}
+void ED_workspace_status_text(bContext *C, const char *str)
+{
+ wmWindow *win = CTX_wm_window(C);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+
+ /* Can be NULL when running operators in background mode. */
+ if (workspace == NULL)
+ return;
+
+ if (str) {
+ if (workspace->status_text == NULL)
+ workspace->status_text = MEM_mallocN(UI_MAX_DRAW_STR, "headerprint");
+ BLI_strncpy(workspace->status_text, str, UI_MAX_DRAW_STR);
+ }
+ else if (workspace->status_text) {
+ MEM_freeN(workspace->status_text);
+ workspace->status_text = NULL;
+ }
+
+ /* Redraw status bar. */
+ for (ScrArea *sa = win->global_areas.areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype == SPACE_STATUSBAR) {
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ }
+}
+
/* ************************************************************ */
static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea *sa)
{
AZone *az;
-
+
/* reinitalize entirely, regions and fullscreen add azones too */
BLI_freelistN(&sa->actionzones);
@@ -775,11 +840,11 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
{
AZone *azt;
int tot = 0, add;
-
+
for (azt = sa->actionzones.first; azt; azt = azt->next) {
if (azt->edge == az->edge) tot++;
}
-
+
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
add = (ar->winrct.ymax == sa->totrct.ymin) ? 1 : 0;
@@ -809,7 +874,7 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
}
/* rect needed for mouse pointer test */
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
-}
+}
static void region_azone_edge_initialize(ScrArea *sa, ARegion *ar, AZEdge edge, const bool is_fullscreen)
{
@@ -829,7 +894,7 @@ static void region_azone_edge_initialize(ScrArea *sa, ARegion *ar, AZEdge edge,
if (is_hidden) {
region_azone_tab_plus(sa, az, ar);
}
- else {
+ else if (!is_hidden && (ar->regiontype != RGN_TYPE_HEADER)) {
region_azone_edge(az, ar);
}
}
@@ -934,6 +999,9 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar)
}
if (ar1->overlap && ((ar1->alignment & RGN_SPLIT_PREV) == 0)) {
+ if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) {
+ continue;
+ }
align1 = ar1->alignment;
if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) {
if (align1 != align) {
@@ -975,6 +1043,9 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar)
if (ar1->flag & (RGN_FLAG_HIDDEN)) {
continue;
}
+ if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) {
+ continue;
+ }
if (ar1->overlap && (ar1->alignment & RGN_SPLIT_PREV) == 0) {
if ((ar1->alignment != align) && BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) {
@@ -987,19 +1058,22 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar)
}
/* overlapping regions only in the following restricted cases */
-static bool region_is_overlap(ScrArea *sa, ARegion *ar)
+bool ED_region_is_overlap(int spacetype, int regiontype)
{
+ if (regiontype == RGN_TYPE_HUD) {
+ return 1;
+ }
if (U.uiflag2 & USER_REGION_OVERLAP) {
- if (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ, SPACE_IMAGE)) {
- if (ELEM(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS))
+ if (ELEM(spacetype, SPACE_VIEW3D, SPACE_SEQ, SPACE_IMAGE)) {
+ if (ELEM(regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS))
return 1;
- if (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) {
- if (ar->regiontype == RGN_TYPE_HEADER)
+ if (ELEM(spacetype, SPACE_VIEW3D, SPACE_IMAGE)) {
+ if (regiontype == RGN_TYPE_HEADER)
return 1;
}
- else if (sa->spacetype == SPACE_SEQ) {
- if (ar->regiontype == RGN_TYPE_PREVIEW)
+ else if (spacetype == SPACE_SEQ) {
+ if (regiontype == RGN_TYPE_PREVIEW)
return 1;
}
}
@@ -1008,33 +1082,34 @@ static bool region_is_overlap(ScrArea *sa, ARegion *ar)
return 0;
}
-static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti *remainder, rcti *overlap_remainder, int quad)
+static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, rcti *overlap_remainder, int quad)
{
rcti *remainder_prev = remainder;
int prefsizex, prefsizey;
int alignment;
-
+
if (ar == NULL)
return;
-
+
/* no returns in function, winrct gets set in the end again */
BLI_rcti_init(&ar->winrct, 0, 0, 0, 0);
-
+
/* for test; allow split of previously defined region */
if (ar->alignment & RGN_SPLIT_PREV)
if (ar->prev)
remainder = &ar->prev->winrct;
-
+
alignment = ar->alignment & ~RGN_SPLIT_PREV;
-
+
/* set here, assuming userpref switching forces to call this again */
- ar->overlap = region_is_overlap(sa, ar);
+ ar->overlap = ED_region_is_overlap(sa->spacetype, ar->regiontype);
/* clear state flags first */
ar->flag &= ~RGN_FLAG_TOO_SMALL;
/* user errors */
- if (ar->next == NULL && alignment != RGN_ALIGN_QSPLIT)
+ if ((ar->next == NULL) && !ELEM(alignment, RGN_ALIGN_QSPLIT, RGN_ALIGN_FLOAT)) {
alignment = RGN_ALIGN_NONE;
+ }
/* prefsize, taking into account DPI */
prefsizex = UI_DPI_FAC * ((ar->sizex > 1) ? ar->sizex + 0.5f : ar->type->prefsizex);
@@ -1057,7 +1132,28 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
/* hidden is user flag */
}
else if (alignment == RGN_ALIGN_FLOAT) {
- /* XXX floating area region, not handled yet here */
+ /**
+ * \note Currently this window type is only used for #RGN_TYPE_HUD,
+ * We expect the panel to resize it's self to be larger.
+ *
+ * This aligns to the lower left of the area.
+ */
+ rcti overlap_remainder_margin = *overlap_remainder;
+ BLI_rcti_resize(
+ &overlap_remainder_margin,
+ max_ii(0, BLI_rcti_size_x(overlap_remainder) - UI_UNIT_X / 2),
+ max_ii(0, BLI_rcti_size_y(overlap_remainder) - UI_UNIT_Y / 2));
+ ar->winrct.xmin = overlap_remainder_margin.xmin;
+ ar->winrct.ymin = overlap_remainder_margin.ymin;
+ ar->winrct.xmax = ar->winrct.xmin + ar->sizex - 1;
+ ar->winrct.ymax = ar->winrct.ymin + ar->sizey - 1;
+
+ BLI_rcti_isect(&ar->winrct, &overlap_remainder_margin, &ar->winrct);
+ if (BLI_rcti_size_x(&ar->winrct) < UI_UNIT_X ||
+ BLI_rcti_size_y(&ar->winrct) < UI_UNIT_Y)
+ {
+ ar->flag |= RGN_FLAG_TOO_SMALL;
+ }
}
else if (rct_fits(remainder, 'v', 1) < 0 || rct_fits(remainder, 'h', 1) < 0) {
/* remainder is too small for any usage */
@@ -1070,7 +1166,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
}
else if (alignment == RGN_ALIGN_TOP || alignment == RGN_ALIGN_BOTTOM) {
rcti *winrct = (ar->overlap) ? overlap_remainder : remainder;
-
+
if (rct_fits(winrct, 'v', prefsizey) < 0) {
ar->flag |= RGN_FLAG_TOO_SMALL;
}
@@ -1079,9 +1175,9 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
if (fac < 0)
prefsizey += fac;
-
+
ar->winrct = *winrct;
-
+
if (alignment == RGN_ALIGN_TOP) {
ar->winrct.ymin = ar->winrct.ymax - prefsizey + 1;
winrct->ymax = ar->winrct.ymin - 1;
@@ -1094,18 +1190,18 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
}
else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
rcti *winrct = (ar->overlap) ? overlap_remainder : remainder;
-
+
if (rct_fits(winrct, 'h', prefsizex) < 0) {
ar->flag |= RGN_FLAG_TOO_SMALL;
}
else {
int fac = rct_fits(winrct, 'h', prefsizex);
-
+
if (fac < 0)
prefsizex += fac;
-
+
ar->winrct = *winrct;
-
+
if (alignment == RGN_ALIGN_RIGHT) {
ar->winrct.xmin = ar->winrct.xmax - prefsizex + 1;
winrct->xmax = ar->winrct.xmin - 1;
@@ -1119,7 +1215,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
else if (alignment == RGN_ALIGN_VSPLIT || alignment == RGN_ALIGN_HSPLIT) {
/* percentage subdiv*/
ar->winrct = *remainder;
-
+
if (alignment == RGN_ALIGN_HSPLIT) {
if (rct_fits(remainder, 'h', prefsizex) > 4) {
ar->winrct.xmax = BLI_rcti_cent_x(remainder);
@@ -1141,18 +1237,18 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
}
else if (alignment == RGN_ALIGN_QSPLIT) {
ar->winrct = *remainder;
-
+
/* test if there's still 4 regions left */
if (quad == 0) {
ARegion *artest = ar->next;
int count = 1;
-
+
while (artest) {
artest->alignment = RGN_ALIGN_QSPLIT;
artest = artest->next;
count++;
}
-
+
if (count != 4) {
/* let's stop adding regions */
BLI_rcti_init(remainder, 0, 0, 0, 0);
@@ -1185,25 +1281,25 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
quad++;
}
}
-
+
/* for speedup */
ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
-
+
/* if region opened normally, we store this for hide/reveal usage */
/* prevent rounding errors for UI_DPI_FAC mult and divide */
if (ar->winx > 1) ar->sizex = (ar->winx + 0.5f) / UI_DPI_FAC;
if (ar->winy > 1) ar->sizey = (ar->winy + 0.5f) / UI_DPI_FAC;
-
+
/* exception for multiple overlapping regions on same spot */
- if (ar->overlap) {
+ if (ar->overlap & (alignment != RGN_ALIGN_FLOAT)) {
region_overlap_fix(sa, ar);
}
/* set winrect for azones */
if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) {
ar->winrct = (ar->overlap) ? *overlap_remainder : *remainder;
-
+
switch (alignment) {
case RGN_ALIGN_TOP:
ar->winrct.ymin = ar->winrct.ymax;
@@ -1237,10 +1333,10 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
*overlap_remainder = *remainder;
}
- region_rect_recursive(win, sa, ar->next, remainder, overlap_remainder, quad);
+ region_rect_recursive(sa, ar->next, remainder, overlap_remainder, quad);
}
-static void area_calc_totrct(ScrArea *sa, int window_size_x, int window_size_y)
+static void area_calc_totrct(ScrArea *sa, const rcti *window_rect)
{
short px = (short)U.pixelsize;
@@ -1250,16 +1346,16 @@ static void area_calc_totrct(ScrArea *sa, int window_size_x, int window_size_y)
sa->totrct.ymax = sa->v2->vec.y;
/* scale down totrct by 1 pixel on all sides not matching window borders */
- if (sa->totrct.xmin > 0) {
+ if (sa->totrct.xmin > window_rect->xmin) {
sa->totrct.xmin += px;
}
- if (sa->totrct.xmax < (window_size_x - 1)) {
+ if (sa->totrct.xmax < (window_rect->xmax - 1)) {
sa->totrct.xmax -= px;
}
- if (sa->totrct.ymin > 0) {
+ if (sa->totrct.ymin > window_rect->ymin) {
sa->totrct.ymin += px;
}
- if (sa->totrct.ymax < (window_size_y - 1)) {
+ if (sa->totrct.ymax < (window_rect->ymax - 1)) {
sa->totrct.ymax -= px;
}
/* Although the following asserts are correct they lead to a very unstable Blender.
@@ -1309,7 +1405,7 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
if (flag & ED_KEYMAP_MARKERS) {
/* time-markers */
wmKeyMap *keymap = WM_keymap_find(wm->defaultconf, "Markers", 0, 0);
-
+
/* use a boundbox restricted map */
ARegion *ar;
/* same local check for all areas */
@@ -1332,16 +1428,16 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
}
if (flag & ED_KEYMAP_GPENCIL) {
/* grease pencil */
- /* NOTE: This is now 2 keymaps - One for basic functionality,
- * and one that only applies when "Edit Mode" is enabled
+ /* NOTE: This is now 2 keymaps - One for basic functionality,
+ * and one that only applies when "Edit Mode" is enabled
* for strokes.
*
- * For now, it's easier to just include both,
+ * For now, it's easier to just include both,
* since you hardly want one without the other.
*/
wmKeyMap *keymap_general = WM_keymap_find(wm->defaultconf, "Grease Pencil", 0, 0);
wmKeyMap *keymap_edit = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0);
-
+
WM_event_add_keymap_handler(handlers, keymap_general);
WM_event_add_keymap_handler(handlers, keymap_edit);
}
@@ -1354,20 +1450,20 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *area)
{
+ rcti rect, overlap_rect;
+ rcti window_rect;
+
if (!(area->flag & AREA_FLAG_REGION_SIZE_UPDATE)) {
return;
}
- const int size_x = WM_window_pixels_x(win);
- const int size_y = WM_window_pixels_y(win);
- rcti rect, overlap_rect;
-
- area_calc_totrct(area, size_x, size_y);
+ WM_window_rect_calc(win, &window_rect);
+ area_calc_totrct(area, &window_rect);
/* region rect sizes */
rect = area->totrct;
overlap_rect = rect;
- region_rect_recursive(win, area, area->regionbase.first, &rect, &overlap_rect, 0);
+ region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0);
for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) {
region_subwindow(ar);
@@ -1384,36 +1480,38 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
/* called in screen_refresh, or screens_init, also area size changes */
void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
{
- const bScreen *screen = WM_window_get_active_screen(win);
- const int window_size_x = WM_window_pixels_x(win);
- const int window_size_y = WM_window_pixels_y(win);
+ WorkSpace *workspace = WM_window_get_active_workspace(win);
+ const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
+ Scene *scene = WM_window_get_active_scene(win);
ARegion *ar;
rcti rect, overlap_rect;
+ rcti window_rect;
if (ED_area_is_global(sa) && (sa->global->flag & GLOBAL_AREA_IS_HIDDEN)) {
return;
}
+ WM_window_rect_calc(win, &window_rect);
/* set typedefinitions */
sa->type = BKE_spacetype_from_id(sa->spacetype);
-
+
if (sa->type == NULL) {
sa->spacetype = SPACE_VIEW3D;
sa->type = BKE_spacetype_from_id(sa->spacetype);
}
for (ar = sa->regionbase.first; ar; ar = ar->next)
- ar->type = BKE_regiontype_from_id(sa->type, ar->regiontype);
+ ar->type = BKE_regiontype_from_id_or_first(sa->type, ar->regiontype);
/* area sizes */
- area_calc_totrct(sa, window_size_x, window_size_y);
+ area_calc_totrct(sa, &window_rect);
/* region rect sizes */
rect = sa->totrct;
overlap_rect = rect;
- region_rect_recursive(win, sa, sa->regionbase.first, &rect, &overlap_rect, 0);
+ region_rect_recursive(sa, sa->regionbase.first, &rect, &overlap_rect, 0);
sa->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE;
-
+
/* default area handlers */
ed_default_handlers(wm, sa, &sa->handlers, sa->type->keymapflag);
/* checks spacedata, adds own handlers */
@@ -1426,7 +1524,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
/* region windows, default and own handlers */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
region_subwindow(ar);
-
+
if (ar->visible) {
/* default region handlers */
ed_default_handlers(wm, sa, &ar->handlers, ar->type->keymapflag);
@@ -1443,6 +1541,8 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
/* Some AZones use View2D data which is only updated in region init, so call that first! */
region_azones_add(screen, sa, ar, ar->alignment & ~RGN_SPLIT_PREV);
}
+
+ WM_toolsystem_refresh_screen_area(workspace, scene, sa);
}
static void region_update_rect(ARegion *ar)
@@ -1457,13 +1557,13 @@ static void region_update_rect(ARegion *ar)
/**
* Call to move a popup window (keep OpenGL context free!)
*/
-void ED_region_update_rect(bContext *UNUSED(C), ARegion *ar)
+void ED_region_update_rect(ARegion *ar)
{
region_update_rect(ar);
}
/* externally called for floating regions like menus */
-void ED_region_init(bContext *UNUSED(C), ARegion *ar)
+void ED_region_init(ARegion *ar)
{
/* refresh can be called before window opened */
region_subwindow(ar);
@@ -1477,6 +1577,9 @@ void ED_region_cursor_set(wmWindow *win, ScrArea *sa, ARegion *ar)
ar->type->cursor(win, sa, ar);
}
else {
+ if (WM_cursor_set_from_tool(win, sa, ar)) {
+ return;
+ }
WM_cursor_set(win, CURSOR_STD);
}
}
@@ -1485,10 +1588,10 @@ void ED_region_cursor_set(wmWindow *win, ScrArea *sa, ARegion *ar)
void ED_region_visibility_change_update(bContext *C, ARegion *ar)
{
ScrArea *sa = CTX_wm_area(C);
-
+
if (ar->flag & RGN_FLAG_HIDDEN)
WM_event_remove_handlers(C, &ar->handlers);
-
+
ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
ED_area_tag_redraw(sa);
}
@@ -1497,9 +1600,9 @@ void ED_region_visibility_change_update(bContext *C, ARegion *ar)
void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade)
{
ScrArea *sa = CTX_wm_area(C);
-
+
ar->flag ^= RGN_FLAG_HIDDEN;
-
+
if (do_fade && ar->overlap) {
/* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */
region_blend_start(C, sa, ar);
@@ -1524,7 +1627,7 @@ void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free)
ARegion *ar;
const char spacetype = sa_dst->spacetype;
const short flag_copy = HEADER_NO_PULLDOWN;
-
+
sa_dst->spacetype = sa_src->spacetype;
sa_dst->type = sa_src->type;
@@ -1582,7 +1685,7 @@ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2)
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(C);
-
+
ED_area_tag_redraw(sa1);
ED_area_tag_refresh(sa1);
ED_area_tag_redraw(sa2);
@@ -1631,7 +1734,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exi
for (sl = sa->spacedata.first; sl; sl = sl->next)
if (sl->spacetype == type)
break;
-
+
/* old spacedata... happened during work on 2.50, remove */
if (sl && BLI_listbase_is_empty(&sl->regionbase)) {
st->free(sl);
@@ -1647,7 +1750,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exi
slold->regionbase = sa->regionbase;
sa->regionbase = sl->regionbase;
BLI_listbase_clear(&sl->regionbase);
-
+
/* put in front of list */
BLI_remlink(&sa->spacedata, sl);
BLI_addhead(&sa->spacedata, sl);
@@ -1668,7 +1771,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exi
Scene *scene = WM_window_get_active_scene(win);
sl = st->new(sa, scene);
BLI_addhead(&sa->spacedata, sl);
-
+
/* swap regions */
if (slold)
slold->regionbase = sa->regionbase;
@@ -1676,18 +1779,18 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exi
BLI_listbase_clear(&sl->regionbase);
}
}
-
+
ED_area_initialize(CTX_wm_manager(C), win, sa);
-
+
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(C);
-
+
/* send space change notifier */
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CHANGED, sa);
-
+
ED_area_tag_refresh(sa);
}
-
+
/* also redraw when re-used */
ED_area_tag_redraw(sa);
}
@@ -1727,7 +1830,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
RNA_pointer_create(&(scr->id), &RNA_Area, sa, &areaptr);
uiDefButR(block, UI_BTYPE_MENU, 0, "", xco, yco, 1.6 * U.widget_unit, U.widget_unit,
- &areaptr, "type", 0, 0.0f, 0.0f, 0.0f, 0.0f, "");
+ &areaptr, "ui_type", 0, 0.0f, 0.0f, 0.0f, 0.0f, "");
return xco + 1.7 * U.widget_unit;
}
@@ -1755,46 +1858,162 @@ static ThemeColorID region_background_color_id(const bContext *C, const ARegion
static void region_clear_color(const bContext *C, const ARegion *ar, ThemeColorID colorid)
{
- if (ar->overlap) {
+ if (ar->alignment == RGN_ALIGN_FLOAT) {
+ /* handle our own drawing. */
+ }
+ else if (ar->overlap) {
/* view should be in pixelspace */
UI_view2d_view_restore(C);
float back[4];
UI_GetThemeColor4fv(colorid, back);
- glClearColor(back[3] * back[0], back[3] * back[1], back[3] * back[2], back[3]);
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear_color(back[3] * back[0], back[3] * back[1], back[3] * back[2], back[3]);
+ GPU_clear(GPU_COLOR_BIT);
}
else {
UI_ThemeClearColor(colorid);
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear(GPU_COLOR_BIT);
}
}
-void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int contextnr, const bool vertical)
+BLI_INLINE bool streq_array_any(const char *s, const char *arr[])
{
+ for (uint i = 0; arr[i]; i++) {
+ if (STREQ(arr[i], s)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static void ed_panel_draw(
+ const bContext *C,
+ ScrArea *sa,
+ ARegion *ar,
+ ListBase *lb,
+ PanelType *pt,
+ Panel *panel,
+ int w,
+ int em,
+ bool vertical)
+{
+ uiStyle *style = UI_style_get_dpi();
+
+ /* draw panel */
+ uiBlock *block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS);
+
+ bool open;
+ panel = UI_panel_begin(sa, ar, lb, block, pt, panel, &open);
+
+ /* bad fixed values */
+ int xco, yco, h = 0;
+
+ if (pt->draw_header_preset && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
+ /* for preset menu */
+ panel->layout = UI_block_layout(
+ block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
+ 0, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style);
+
+ pt->draw_header_preset(C, panel);
+
+ int headerend = w - UI_UNIT_X;
+
+ UI_block_layout_resolve(block, &xco, &yco);
+ UI_block_translate(block, headerend - xco, 0);
+ panel->layout = NULL;
+ }
+
+ if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
+ int labelx, labely;
+ UI_panel_label_offset(block, &labelx, &labely);
+
+ /* for enabled buttons */
+ panel->layout = UI_block_layout(
+ block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
+ labelx, labely, UI_UNIT_Y, 1, 0, style);
+
+ pt->draw_header(C, panel);
+
+ UI_block_layout_resolve(block, &xco, &yco);
+ panel->labelofs = xco - labelx;
+ panel->layout = NULL;
+ }
+ else {
+ panel->labelofs = 0;
+ }
+
+ if (open) {
+ short panelContext;
+
+ /* panel context can either be toolbar region or normal panels region */
+ if (ar->regiontype == RGN_TYPE_TOOLS)
+ panelContext = UI_LAYOUT_TOOLBAR;
+ else
+ panelContext = UI_LAYOUT_PANEL;
+
+ panel->layout = UI_block_layout(
+ block, UI_LAYOUT_VERTICAL, panelContext,
+ style->panelspace, 0, w - 2 * style->panelspace, em, 0, style);
+
+ pt->draw(C, panel);
+
+ UI_block_layout_resolve(block, &xco, &yco);
+ panel->layout = NULL;
+
+ if (yco != 0) {
+ h = -yco + 2 * style->panelspace;
+ }
+ }
+
+ UI_block_end(C, block);
+
+ /* Draw child panels. */
+ if (open) {
+ for (LinkData *link = pt->children.first; link; link = link->next) {
+ PanelType *child_pt = link->data;
+ Panel *child_panel = UI_panel_find_by_type(&panel->children, child_pt);
+
+ if (child_pt->draw && (!child_pt->poll || child_pt->poll(C, child_pt))) {
+ ed_panel_draw(C, sa, ar, &panel->children, child_pt, child_panel, w, em, vertical);
+ }
+ }
+ }
+
+ UI_panel_end(block, w, h);
+}
+
+/**
+ * \param contexts: A NULL terminated array of context strings to match against.
+ * Matching against any of these strings will draw the panel.
+ * Can be NULL to skip context checks.
+ */
+void ED_region_panels_layout_ex(
+ const bContext *C, ARegion *ar,
+ const char *contexts[], int contextnr, const bool vertical)
+{
+ ar->runtime.category = NULL;
+
const WorkSpace *workspace = CTX_wm_workspace(C);
ScrArea *sa = CTX_wm_area(C);
- uiStyle *style = UI_style_get_dpi();
- uiBlock *block;
PanelType *pt;
- Panel *panel;
View2D *v2d = &ar->v2d;
- View2DScrollers *scrollers;
- int x, y, xco, yco, w, em, triangle;
+ int x, y, w, em;
bool is_context_new = 0;
int scroll;
- bool use_category_tabs = (ELEM(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI)); /* XXX, should use some better check? */
+ /* XXX, should use some better check? */
+ bool use_category_tabs = (ELEM(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI));
/* offset panels for small vertical tab area */
const char *category = NULL;
const int category_tabs_width = UI_PANEL_CATEGORY_MARGIN_WIDTH;
int margin_x = 0;
+ const bool region_layout_based = ar->flag & RGN_FLAG_DYNAMIC_SIZE;
BLI_SMALLSTACK_DECLARE(pt_stack, PanelType *);
if (contextnr != -1)
is_context_new = UI_view2d_tab_set(v2d, contextnr);
-
+
/* before setting the view */
if (vertical) {
/* only allow scrolling in vertical direction */
@@ -1817,8 +2036,13 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
/* collect panels to draw */
for (pt = ar->type->paneltypes.last; pt; pt = pt->prev) {
+ /* Only draw top level panels. */
+ if (pt->parent) {
+ continue;
+ }
+
/* verify context */
- if (context && pt->context[0] && !STREQ(context, pt->context)) {
+ if (contexts && pt->context[0] && !streq_array_any(pt->context, contexts)) {
continue;
}
@@ -1878,9 +2102,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
BLI_SMALLSTACK_ITER_BEGIN(pt_stack, pt)
{
- bool open;
-
- panel = UI_panel_find_by_type(ar, pt);
+ Panel *panel = UI_panel_find_by_type(&ar->panels, pt);
if (use_category_tabs && pt->category[0] && !STREQ(category, pt->category)) {
if ((panel == NULL) || ((panel->flag & PNL_PIN) == 0)) {
@@ -1888,56 +2110,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
}
}
- /* draw panel */
- block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS);
- panel = UI_panel_begin(sa, ar, block, pt, panel, &open);
-
- /* bad fixed values */
- triangle = (int)(UI_UNIT_Y * 1.1f);
-
- if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
- /* for enabled buttons */
- panel->layout = UI_block_layout(
- block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
- triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style);
-
- pt->draw_header(C, panel);
-
- UI_block_layout_resolve(block, &xco, &yco);
- panel->labelofs = xco - triangle;
- panel->layout = NULL;
- }
- else {
- panel->labelofs = 0;
- }
-
- if (open) {
- short panelContext;
-
- /* panel context can either be toolbar region or normal panels region */
- if (ar->regiontype == RGN_TYPE_TOOLS)
- panelContext = UI_LAYOUT_TOOLBAR;
- else
- panelContext = UI_LAYOUT_PANEL;
-
- panel->layout = UI_block_layout(
- block, UI_LAYOUT_VERTICAL, panelContext,
- style->panelspace, 0, w - 2 * style->panelspace, em, 0, style);
-
- pt->draw(C, panel);
-
- UI_block_layout_resolve(block, &xco, &yco);
- panel->layout = NULL;
-
- yco -= 2 * style->panelspace;
- UI_panel_end(block, w, -yco);
- }
- else {
- yco = 0;
- UI_panel_end(block, w, 0);
- }
-
- UI_block_end(C, block);
+ ed_panel_draw(C, sa, ar, &ar->panels, pt, panel, w, em, vertical);
}
BLI_SMALLSTACK_ITER_END;
@@ -1945,7 +2118,28 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
UI_panels_end(C, ar, &x, &y);
/* before setting the view */
- if (vertical) {
+ if (region_layout_based) {
+ /* XXX, only single panel support atm.
+ * Can't use x/y values calculated above because they're not using the real height of panels,
+ * instead they calculate offsets for the next panel to start drawing. */
+ Panel *panel = ar->panels.last;
+ if (panel != NULL) {
+ int size_dyn[2] = {
+ UI_UNIT_X * ((panel->flag & PNL_CLOSED) ? 8 : 14),
+ UI_panel_size_y(panel),
+ };
+ /* region size is layout based and needs to be updated */
+ if ((ar->sizex != size_dyn[0]) ||
+ (ar->sizey != size_dyn[1]))
+ {
+ ar->sizex = size_dyn[0];
+ ar->sizey = size_dyn[1];
+ sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE;
+ }
+ y = ABS(ar->sizey - 1);
+ }
+ }
+ else if (vertical) {
/* we always keep the scroll offset - so the total view gets increased with the scrolled away part */
if (v2d->cur.ymax < -FLT_EPSILON) {
/* Clamp to lower view boundary */
@@ -1986,10 +2180,25 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
#endif
}
- region_clear_color(C, ar, (ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
-
+ if (use_category_tabs) {
+ ar->runtime.category = category;
+ }
+}
+void ED_region_panels_layout(const bContext *C, ARegion *ar)
+{
+ ED_region_panels_layout_ex(C, ar, NULL, -1, true);
+}
+
+void ED_region_panels_draw(const bContext *C, ARegion *ar)
+{
+ View2D *v2d = &ar->v2d;
+
+ if (ar->alignment != RGN_ALIGN_FLOAT) {
+ region_clear_color(C, ar, (ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
+ }
+
/* reset line width for drawing tabs */
- glLineWidth(1.0f);
+ GPU_line_width(1.0f);
/* set the view */
UI_view2d_view_ortho(v2d);
@@ -1999,17 +2208,35 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
/* restore view matrix */
UI_view2d_view_restore(C);
-
- if (use_category_tabs) {
- UI_panel_category_draw_all(ar, category);
+
+ /* Set in layout. */
+ if (ar->runtime.category) {
+ UI_panel_category_draw_all(ar, ar->runtime.category);
}
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
+ View2DScrollers *scrollers = UI_view2d_scrollers_calc(
+ C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
}
+void ED_region_panels_ex(
+ const bContext *C, ARegion *ar,
+ const char *contexts[], int contextnr, const bool vertical)
+{
+ /* TODO: remove? */
+ ED_region_panels_layout_ex(C, ar, contexts, contextnr, vertical);
+ ED_region_panels_draw(C, ar);
+}
+
+void ED_region_panels(const bContext *C, ARegion *ar)
+{
+ /* TODO: remove? */
+ ED_region_panels_layout(C, ar);
+ ED_region_panels_draw(C, ar);
+}
+
void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
@@ -2027,33 +2254,39 @@ void ED_region_header_layout(const bContext *C, ARegion *ar)
uiLayout *layout;
HeaderType *ht;
Header header = {NULL};
- int maxco, xco, yco;
- int headery = ED_area_headersize();
- const int start_ofs = 0.4f * UI_UNIT_X;
bool region_layout_based = ar->flag & RGN_FLAG_DYNAMIC_SIZE;
- /* set view2d view matrix for scrolling (without scrollers) */
- UI_view2d_view_ortho(&ar->v2d);
+ /* Height of buttons and scaling needed to achieve it. */
+ const int buttony = min_ii(UI_UNIT_Y, ar->winy - 2 * UI_DPI_FAC);
+ const float buttony_scale = buttony / (float)UI_UNIT_Y;
- xco = maxco = start_ofs;
- yco = headery + (ar->winy - headery) / 2 - floor(0.2f * UI_UNIT_Y);
+ /* Vertically center buttons. */
+ int xco = UI_HEADER_OFFSET;
+ int yco = buttony + (ar->winy - buttony) / 2;
+ int maxco = xco;
/* XXX workaround for 1 px alignment issue. Not sure what causes it... Would prefer a proper fix - Julian */
- if (CTX_wm_area(C)->spacetype == SPACE_TOPBAR) {
- xco += 1;
- yco += 1;
+ if (!ELEM(CTX_wm_area(C)->spacetype, SPACE_TOPBAR, SPACE_STATUSBAR)) {
+ yco -= 1;
}
+ /* set view2d view matrix for scrolling (without scrollers) */
+ UI_view2d_view_ortho(&ar->v2d);
+
/* draw all headers types */
for (ht = ar->type->headertypes.first; ht; ht = ht->next) {
block = UI_block_begin(C, ar, ht->idname, UI_EMBOSS);
- layout = UI_block_layout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, UI_UNIT_Y, 1, 0, style);
+ layout = UI_block_layout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, buttony, 1, 0, style);
+
+ if (buttony_scale != 1.0f) {
+ uiLayoutSetScaleY(layout, buttony_scale);
+ }
if (ht->draw) {
header.type = ht;
header.layout = layout;
ht->draw(C, &header);
-
+
/* for view2d */
xco = uiLayoutGetWidth(layout);
if (xco > maxco)
@@ -2061,12 +2294,12 @@ void ED_region_header_layout(const bContext *C, ARegion *ar)
}
UI_block_layout_resolve(block, &xco, &yco);
-
+
/* for view2d */
if (xco > maxco)
maxco = xco;
- int new_sizex = (maxco + start_ofs) / UI_DPI_FAC;
+ int new_sizex = (maxco + UI_HEADER_OFFSET) / UI_DPI_FAC;
if (region_layout_based && (ar->sizex != new_sizex)) {
/* region size is layout based and needs to be updated */
@@ -2079,8 +2312,12 @@ void ED_region_header_layout(const bContext *C, ARegion *ar)
UI_block_end(C, block);
}
+ if (!region_layout_based) {
+ maxco += UI_HEADER_OFFSET;
+ }
+
/* always as last */
- UI_view2d_totRect_set(&ar->v2d, maxco + (region_layout_based ? 0 : UI_UNIT_X + 80), headery);
+ UI_view2d_totRect_set(&ar->v2d, maxco, ar->winy);
/* restore view matrix */
UI_view2d_view_restore(C);
@@ -2088,11 +2325,11 @@ void ED_region_header_layout(const bContext *C, ARegion *ar)
void ED_region_header_draw(const bContext *C, ARegion *ar)
{
- UI_view2d_view_ortho(&ar->v2d);
-
/* clear */
region_clear_color(C, ar, region_background_color_id(C, ar));
+ UI_view2d_view_ortho(&ar->v2d);
+
/* View2D matrix might have changed due to dynamic sized regions. */
UI_blocklist_update_window_matrix(C, &ar->uiblocks);
@@ -2141,6 +2378,16 @@ int ED_area_global_size_y(const ScrArea *area)
BLI_assert(ED_area_is_global(area));
return round_fl_to_int(area->global->cur_fixed_height * UI_DPI_FAC);
}
+int ED_area_global_min_size_y(const ScrArea *area)
+{
+ BLI_assert(ED_area_is_global(area));
+ return round_fl_to_int(area->global->size_min * UI_DPI_FAC);
+}
+int ED_area_global_max_size_y(const ScrArea *area)
+{
+ BLI_assert(ED_area_is_global(area));
+ return round_fl_to_int(area->global->size_max * UI_DPI_FAC);
+}
bool ED_area_is_global(const ScrArea *area)
{
@@ -2191,7 +2438,7 @@ void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float
const int header_height = UI_UNIT_Y;
uiStyle *style = UI_style_get_dpi();
int fontid = style->widget.uifont_id;
- GLint scissor[4];
+ int scissor[4];
rcti rect;
int num_lines = 0;
@@ -2216,23 +2463,22 @@ void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float
}
}
- rect.ymin = BLI_rcti_size_y(&ar->winrct) - header_height * num_lines;
- rect.ymax = BLI_rcti_size_y(&ar->winrct);
+ rect.ymin = rect.ymax - header_height * num_lines;
/* setup scissor */
- glGetIntegerv(GL_SCISSOR_BOX, scissor);
- glScissor(rect.xmin, rect.ymin,
+ GPU_scissor_geti(scissor);
+ GPU_scissor(rect.xmin, rect.ymin,
BLI_rcti_size_x(&rect) + 1, BLI_rcti_size_y(&rect) + 1);
- glEnable(GL_BLEND);
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+ GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(fill_color);
immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1);
immUnbindProgram();
- glDisable(GL_BLEND);
+ GPU_blend(false);
/* text */
UI_FontThemeColor(fontid, TH_TEXT_HI);
@@ -2252,7 +2498,7 @@ void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float
BLF_disable(fontid, BLF_CLIPPING);
/* restore scissor as it was before */
- glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+ GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
}
void ED_region_info_draw(ARegion *ar, const char *text, float fill_color[4], const bool full_redraw)
@@ -2361,7 +2607,7 @@ static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const
if (metadata_is_valid(ibuf, temp_str, i, len)) {
BLF_position(fontid, xmin + ofs_x, ymin, 0.0f);
BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
-
+
ofs_x += BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX) + UI_UNIT_X;
}
}
@@ -2501,7 +2747,7 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-
+
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShade(TH_BACK, 20);
immRectf(pos, x1, y1, x2, y2);
@@ -2535,14 +2781,14 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
GWN_vertformat_clear(format);
pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
-
+
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
immBegin(GWN_PRIM_LINES, 4 * count_fine + 4 * count_large);
-
+
float theme_color[3];
UI_GetThemeColorShade3fv(TH_BACK, (int)(20.0f * (1.0f - blendfac)), theme_color);
fac = 0.0f;
-
+
/* the fine resolution level */
for (int i = 0; i < count_fine; i++) {
immAttrib3fv(color, theme_color);
@@ -2559,7 +2805,7 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
if (count_large > 0) {
UI_GetThemeColor3fv(TH_BACK, theme_color);
fac = 0.0f;
-
+
/* the large resolution level */
for (int i = 0; i < count_large; i++) {
immAttrib3fv(color, theme_color);
@@ -2584,25 +2830,43 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
void ED_region_visible_rect(ARegion *ar, rcti *rect)
{
ARegion *arn = ar;
-
+
/* allow function to be called without area */
while (arn->prev)
arn = arn->prev;
-
+
*rect = ar->winrct;
-
+
/* check if a region overlaps with the current one */
for (; arn; arn = arn->next) {
if (ar != arn && arn->overlap) {
if (BLI_rcti_isect(rect, &arn->winrct, NULL)) {
-
- /* overlap left, also check 1 pixel offset (2 regions on one side) */
- if (ABS(rect->xmin - arn->winrct.xmin) < 2)
- rect->xmin = arn->winrct.xmax;
-
- /* overlap right */
- if (ABS(rect->xmax - arn->winrct.xmax) < 2)
- rect->xmax = arn->winrct.xmin;
+ if (ELEM(arn->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
+ /* Overlap left, also check 1 pixel offset (2 regions on one side). */
+ if (ABS(rect->xmin - arn->winrct.xmin) < 2) {
+ rect->xmin = arn->winrct.xmax;
+ }
+
+ /* Overlap right. */
+ if (ABS(rect->xmax - arn->winrct.xmax) < 2) {
+ rect->xmax = arn->winrct.xmin;
+ }
+ }
+ else if (ELEM(arn->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
+ /* Same logic as above for vertical regions. */
+ if (ABS(rect->ymin - arn->winrct.ymin) < 2) {
+ rect->ymin = arn->winrct.ymax;
+ }
+ if (ABS(rect->ymax - arn->winrct.ymax) < 2) {
+ rect->ymax = arn->winrct.ymin;
+ }
+ }
+ else if (arn->alignment == RGN_ALIGN_FLOAT) {
+ /* Skip floating. */
+ }
+ else {
+ BLI_assert(!"Region overlap with unknown alignment");
+ }
}
}
}
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 39178af9e4e..6cff82295f0 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -4,7 +4,7 @@
* 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.
+ * 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
@@ -51,6 +51,7 @@
#include "GPU_basic_shader.h"
#include "GPU_immediate.h"
#include "GPU_matrix.h"
+#include "GPU_state.h"
#include "UI_interface.h"
@@ -59,11 +60,11 @@
void setlinestyle(int nr)
{
if (nr == 0) {
- glDisable(GL_LINE_STIPPLE);
+ GPU_line_stipple(false);
}
else {
-
- glEnable(GL_LINE_STIPPLE);
+
+ GPU_line_stipple(true);
if (U.pixelsize > 1.0f)
glLineStipple(nr, 0xCCCC);
else
@@ -72,10 +73,10 @@ void setlinestyle(int nr)
}
/* Invert line handling */
-
+
#define GL_TOGGLE(mode, onoff) (((onoff) ? glEnable : glDisable)(mode))
-void set_inverted_drawing(int enable)
+void set_inverted_drawing(int enable)
{
glLogicOp(enable ? GL_INVERT : GL_COPY);
GL_TOGGLE(GL_COLOR_LOGIC_OP, enable);
@@ -355,18 +356,18 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
void bglPolygonOffset(float viewdist, float dist)
{
static float winmat[16], offset = 0.0f;
-
+
if (dist != 0.0f) {
float offs;
-
+
// glEnable(GL_POLYGON_OFFSET_FILL);
// glPolygonOffset(-1.0, -1.0);
/* hack below is to mimic polygon offset */
gpuGetProjectionMatrix(winmat);
-
+
/* dist is from camera to center point */
-
+
if (winmat[15] > 0.5f) {
#if 1
offs = 0.00001f * dist * viewdist; // ortho tweaking
@@ -391,7 +392,7 @@ void bglPolygonOffset(float viewdist, float dist)
*/
offs = winmat[14] * -0.0025f * dist;
}
-
+
winmat[14] -= offs;
offset += offs;
}
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 85087d58276..fa18826005e 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -4,7 +4,7 @@
* 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.
+ * 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
@@ -80,7 +80,7 @@ const char *screen_context_dir[] = {
"sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */
"gpencil_data", "gpencil_data_owner", /* grease pencil data */
"visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes",
- "active_gpencil_layer", "active_gpencil_frame", "active_gpencil_palette",
+ "active_gpencil_layer", "active_gpencil_frame", "active_gpencil_palette",
"active_gpencil_palettecolor", "active_gpencil_brush",
"active_operator", "selected_editable_fcurves",
NULL};
@@ -115,7 +115,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "selectable_objects")) {
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (((base->flag & BASE_VISIBLED) != 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_VISIBLE) != 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
CTX_data_id_list_add(result, &base->object->id);
}
}
@@ -165,7 +165,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "selectable_bases")) {
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if ((base->flag & BASE_SELECTABLED) != 0) {
+ if ((base->flag & BASE_SELECTABLE) != 0) {
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
@@ -195,7 +195,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "editable_bases")) {
/* Visible + Editable, but not necessarily selected */
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if ((base->flag & BASE_VISIBLED) != 0) {
+ if ((base->flag & BASE_VISIBLE) != 0) {
if (0 == BKE_object_is_libdata(base->object)) {
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
@@ -208,7 +208,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
EditBone *ebone, *flipbone = NULL;
const bool editable_bones = CTX_data_equals(member, "editable_bones");
-
+
if (arm && arm->edbo) {
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
@@ -259,7 +259,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
EditBone *ebone, *flipbone = NULL;
const bool selected_editable_bones = CTX_data_equals(member, "selected_editable_bones");
-
+
if (arm && arm->edbo) {
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
@@ -364,7 +364,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "active_pose_bone")) {
bPoseChannel *pchan;
Object *obpose = BKE_object_pose_armature_get(obact);
-
+
pchan = BKE_pose_channel_active(obpose);
if (pchan) {
CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
@@ -393,7 +393,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
/* convenience for now, 1 object per scene in editmode */
if (obedit)
CTX_data_id_pointer_set(result, &obedit->id);
-
+
return 1;
}
else if (CTX_data_equals(member, "sculpt_object")) {
@@ -465,11 +465,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "gpencil_data")) {
/* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these situations
- * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when
+ * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when
* called from context. For that reason, we end up using an alternative where we pass everything in!
*/
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
CTX_data_id_pointer_set(result, &gpd->id);
return 1;
@@ -477,14 +477,14 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "gpencil_data_owner")) {
/* pointer to which data/datablock owns the reference to the Grease Pencil data being used (as gpencil_data)
- * XXX: see comment for gpencil_data case...
+ * XXX: see comment for gpencil_data case...
*/
bGPdata **gpd_ptr = NULL;
PointerRNA ptr;
-
+
/* get pointer to Grease Pencil Data */
gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, scene, sa, obact, &ptr);
-
+
if (gpd_ptr) {
CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data);
return 1;
@@ -493,10 +493,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "active_gpencil_layer")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
-
+
if (gpl) {
CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl);
return 1;
@@ -544,10 +544,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "active_gpencil_frame")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
-
+
if (gpl) {
CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl->actframe);
return 1;
@@ -557,10 +557,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "visible_gpencil_layers")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl;
-
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if ((gpl->flag & GP_LAYER_HIDE) == 0) {
CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
@@ -573,10 +573,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "editable_gpencil_layers")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl;
-
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpencil_layer_is_editable(gpl)) {
CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
@@ -589,15 +589,15 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "editable_gpencil_strokes")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl;
-
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpencil_layer_is_editable(gpl) && (gpl->actframe)) {
bGPDframe *gpf = gpl->actframe;
bGPDstroke *gps;
-
+
for (gps = gpf->strokes.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use_direct(sa, gps)) {
/* check if the color is editable */
@@ -665,4 +665,3 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return -1; /* found but not available */
}
-
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index fec39ade110..b5b0d16f6a7 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -27,6 +27,7 @@
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_matrix.h"
+#include "GPU_state.h"
#include "BLI_math.h"
@@ -43,11 +44,11 @@
*/
static void draw_horizontal_join_shape(ScrArea *sa, char dir, unsigned int pos)
{
+ const float width = screen_geom_area_width(sa) - 1;
+ const float height = screen_geom_area_height(sa) - 1;
vec2f points[10];
short i;
float w, h;
- float width = sa->v3->vec.x - sa->v1->vec.x;
- float height = sa->v3->vec.y - sa->v1->vec.y;
if (height < width) {
h = height / 8;
@@ -124,11 +125,11 @@ static void draw_horizontal_join_shape(ScrArea *sa, char dir, unsigned int pos)
*/
static void draw_vertical_join_shape(ScrArea *sa, char dir, unsigned int pos)
{
+ const float width = screen_geom_area_width(sa) - 1;
+ const float height = screen_geom_area_height(sa) - 1;
vec2f points[10];
short i;
float w, h;
- float width = sa->v3->vec.x - sa->v1->vec.x;
- float height = sa->v3->vec.y - sa->v1->vec.y;
if (height < width) {
h = height / 4;
@@ -353,7 +354,7 @@ static void drawscredge_corner(ScrArea *sa, int sizex, int sizey)
*/
static void scrarea_draw_shape_dark(ScrArea *sa, char dir, unsigned int pos)
{
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
immUniformColor4ub(0, 0, 0, 50);
draw_join_shape(sa, dir, pos);
@@ -364,7 +365,7 @@ static void scrarea_draw_shape_dark(ScrArea *sa, char dir, unsigned int pos)
*/
static void scrarea_draw_shape_light(ScrArea *sa, char UNUSED(dir), unsigned int pos)
{
- glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
+ GPU_blend_set_func(GPU_DST_COLOR, GPU_SRC_ALPHA);
/* value 181 was hardly computed: 181~105 */
immUniformColor4ub(255, 255, 255, 50);
/* draw_join_shape(sa, dir); */
@@ -444,7 +445,7 @@ void ED_screen_draw_edges(wmWindow *win)
/* Note: first loop only draws if U.pixelsize > 1, skip otherwise */
if (U.pixelsize > 1.0f) {
/* FIXME: doesn't our glLineWidth already scale by U.pixelsize? */
- glLineWidth((2.0f * U.pixelsize) - 1);
+ GPU_line_width((2.0f * U.pixelsize) - 1);
immUniformThemeColor(TH_EDITOR_OUTLINE);
for (sa = screen->areabase.first; sa; sa = sa->next) {
@@ -452,7 +453,7 @@ void ED_screen_draw_edges(wmWindow *win)
}
}
- glLineWidth(1);
+ GPU_line_width(1);
immUniformThemeColor(TH_EDITOR_OUTLINE);
for (sa = screen->areabase.first; sa; sa = sa->next) {
@@ -479,7 +480,7 @@ void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2)
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- glLineWidth(1);
+ GPU_line_width(1);
/* blended join arrow */
int dir = area_getorientation(sa1, sa2);
@@ -504,12 +505,12 @@ void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2)
break;
}
- glEnable(GL_BLEND);
+ GPU_blend(true);
scrarea_draw_shape_dark(sa2, dir, pos);
scrarea_draw_shape_light(sa1, dira, pos);
- glDisable(GL_BLEND);
+ GPU_blend(false);
}
immUnbindProgram();
@@ -521,7 +522,7 @@ void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac)
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* splitpoint */
- glEnable(GL_BLEND);
+ GPU_blend(true);
immUniformColor4ub(255, 255, 255, 100);
immBegin(GWN_PRIM_LINES, 2);
@@ -562,7 +563,7 @@ void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac)
immEnd();
}
- glDisable(GL_BLEND);
+ GPU_blend(false);
immUnbindProgram();
}
@@ -645,8 +646,8 @@ void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, uns
GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, true, false, err_out);
GPU_offscreen_bind(offscreen, true);
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ GPU_clear_color(0.0, 0.0, 0.0, 0.0);
+ GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT);
screen_preview_draw(screen, size_x, size_y);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 8ebdb5f32b8..6bc8a6c10cf 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -4,7 +4,7 @@
* 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.
+ * 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
@@ -74,98 +74,6 @@
#include "screen_intern.h" /* own module include */
-/* ******************* screen vert, edge, area managing *********************** */
-
-static ScrVert *screen_addvert_ex(ScrAreaMap *area_map, short x, short y)
-{
- ScrVert *sv = MEM_callocN(sizeof(ScrVert), "addscrvert");
- sv->vec.x = x;
- sv->vec.y = y;
-
- BLI_addtail(&area_map->vertbase, sv);
- return sv;
-}
-static ScrVert *screen_addvert(bScreen *sc, short x, short y)
-{
- return screen_addvert_ex(AREAMAP_FROM_SCREEN(sc), x, y);
-}
-
-static ScrEdge *screen_addedge_ex(ScrAreaMap *area_map, ScrVert *v1, ScrVert *v2)
-{
- ScrEdge *se = MEM_callocN(sizeof(ScrEdge), "addscredge");
-
- BKE_screen_sort_scrvert(&v1, &v2);
- se->v1 = v1;
- se->v2 = v2;
-
- BLI_addtail(&area_map->edgebase, se);
- return se;
-}
-static ScrEdge *screen_addedge(bScreen *sc, ScrVert *v1, ScrVert *v2)
-{
- return screen_addedge_ex(AREAMAP_FROM_SCREEN(sc), v1, v2);
-}
-
-bool scredge_is_horizontal(ScrEdge *se)
-{
- return (se->v1->vec.y == se->v2->vec.y);
-}
-
-/* need win size to make sure not to include edges along screen edge */
-ScrEdge *screen_area_map_find_active_scredge(
- const ScrAreaMap *area_map,
- const int winsize_x, const int winsize_y,
- const int mx, const int my)
-{
- int safety = U.widget_unit / 10;
-
- CLAMP_MIN(safety, 2);
-
- for (ScrEdge *se = area_map->edgebase.first; se; se = se->next) {
- if (scredge_is_horizontal(se)) {
- if (se->v1->vec.y > 0 && se->v1->vec.y < winsize_y - 1) {
- short min, max;
- min = MIN2(se->v1->vec.x, se->v2->vec.x);
- max = MAX2(se->v1->vec.x, se->v2->vec.x);
-
- if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max)
- return se;
- }
- }
- else {
- if (se->v1->vec.x > 0 && se->v1->vec.x < winsize_x - 1) {
- short min, max;
- min = MIN2(se->v1->vec.y, se->v2->vec.y);
- max = MAX2(se->v1->vec.y, se->v2->vec.y);
-
- if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max)
- return se;
- }
- }
- }
-
- return NULL;
-}
-
-/* need win size to make sure not to include edges along screen edge */
-ScrEdge *screen_find_active_scredge(
- const wmWindow *win, const bScreen *screen,
- const int mx, const int my)
-{
- /* Use layout size (screen excluding global areas) for screen-layout area edges */
- const int screen_x = WM_window_screen_pixels_x(win), screen_y = WM_window_screen_pixels_y(win);
- ScrEdge *se = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(screen), screen_x, screen_y, mx, my);
-
- if (!se) {
- /* Use entire window size (screen including global areas) for global area edges */
- const int win_x = WM_window_pixels_x(win), win_y = WM_window_pixels_y(win);
- se = screen_area_map_find_active_scredge(&win->global_areas, win_x, win_y, mx, my);
- }
- return se;
-}
-
-
-
/* adds no space data */
static ScrArea *screen_addarea_ex(
ScrAreaMap *area_map,
@@ -195,81 +103,45 @@ static ScrArea *screen_addarea(
static void screen_delarea(bContext *C, bScreen *sc, ScrArea *sa)
{
-
+
ED_area_exit(C, sa);
-
+
BKE_screen_area_free(sa);
-
+
BLI_remlink(&sc->areabase, sa);
MEM_freeN(sa);
}
-/* return 0: no split possible */
-/* else return (integer) screencoordinate split point */
-static short testsplitpoint(ScrArea *sa, char dir, float fac)
-{
- short x, y;
- const short area_min_x = AREAMINX;
- const short area_min_y = ED_area_headersize();
-
- // area big enough?
- if (dir == 'v' && (sa->v4->vec.x - sa->v1->vec.x <= 2 * area_min_x)) return 0;
- if (dir == 'h' && (sa->v2->vec.y - sa->v1->vec.y <= 2 * area_min_y)) return 0;
-
- // to be sure
- CLAMP(fac, 0.0f, 1.0f);
-
- if (dir == 'h') {
- y = sa->v1->vec.y + fac * (sa->v2->vec.y - sa->v1->vec.y);
-
- if (y - sa->v1->vec.y < area_min_y)
- y = sa->v1->vec.y + area_min_y;
- else if (sa->v2->vec.y - y < area_min_y)
- y = sa->v2->vec.y - area_min_y;
- else y -= (y % AREAGRID);
-
- return y;
- }
- else {
- x = sa->v1->vec.x + fac * (sa->v4->vec.x - sa->v1->vec.x);
-
- if (x - sa->v1->vec.x < area_min_x)
- x = sa->v1->vec.x + area_min_x;
- else if (sa->v4->vec.x - x < area_min_x)
- x = sa->v4->vec.x - area_min_x;
- else x -= (x % AREAGRID);
-
- return x;
- }
-}
-
-ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
+ScrArea *area_split(const wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
{
ScrArea *newa = NULL;
ScrVert *sv1, *sv2;
short split;
-
+ rcti window_rect;
+
if (sa == NULL) return NULL;
-
- split = testsplitpoint(sa, dir, fac);
+
+ WM_window_rect_calc(win, &window_rect);
+
+ split = screen_geom_find_area_split_point(sa, &window_rect, dir, fac);
if (split == 0) return NULL;
-
+
/* note regarding (fac > 0.5f) checks below.
* normally it shouldn't matter which is used since the copy should match the original
* however with viewport rendering and python console this isn't the case. - campbell */
if (dir == 'h') {
/* new vertices */
- sv1 = screen_addvert(sc, sa->v1->vec.x, split);
- sv2 = screen_addvert(sc, sa->v4->vec.x, split);
-
+ sv1 = screen_geom_vertex_add(sc, sa->v1->vec.x, split);
+ sv2 = screen_geom_vertex_add(sc, sa->v4->vec.x, split);
+
/* new edges */
- screen_addedge(sc, sa->v1, sv1);
- screen_addedge(sc, sv1, sa->v2);
- screen_addedge(sc, sa->v3, sv2);
- screen_addedge(sc, sv2, sa->v4);
- screen_addedge(sc, sv1, sv2);
-
+ screen_geom_edge_add(sc, sa->v1, sv1);
+ screen_geom_edge_add(sc, sv1, sa->v2);
+ screen_geom_edge_add(sc, sa->v3, sv2);
+ screen_geom_edge_add(sc, sv2, sa->v4);
+ screen_geom_edge_add(sc, sv1, sv2);
+
if (fac > 0.5f) {
/* new areas: top */
newa = screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->spacetype);
@@ -288,20 +160,20 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
}
ED_area_data_copy(newa, sa, true);
-
+
}
else {
/* new vertices */
- sv1 = screen_addvert(sc, split, sa->v1->vec.y);
- sv2 = screen_addvert(sc, split, sa->v2->vec.y);
-
+ sv1 = screen_geom_vertex_add(sc, split, sa->v1->vec.y);
+ sv2 = screen_geom_vertex_add(sc, split, sa->v2->vec.y);
+
/* new edges */
- screen_addedge(sc, sa->v1, sv1);
- screen_addedge(sc, sv1, sa->v4);
- screen_addedge(sc, sa->v2, sv2);
- screen_addedge(sc, sv2, sa->v3);
- screen_addedge(sc, sv1, sv2);
-
+ screen_geom_edge_add(sc, sa->v1, sv1);
+ screen_geom_edge_add(sc, sv1, sa->v4);
+ screen_geom_edge_add(sc, sa->v2, sv2);
+ screen_geom_edge_add(sc, sv2, sa->v3);
+ screen_geom_edge_add(sc, sv1, sv2);
+
if (fac > 0.5f) {
/* new areas: right */
newa = screen_addarea(sc, sv1, sv2, sa->v3, sa->v4, sa->spacetype);
@@ -321,41 +193,41 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
ED_area_data_copy(newa, sa, true);
}
-
+
/* remove double vertices en edges */
if (merge)
BKE_screen_remove_double_scrverts(sc);
BKE_screen_remove_double_scredges(sc);
BKE_screen_remove_unused_scredges(sc);
-
+
return newa;
}
/**
* Empty screen, with 1 dummy area without spacedata. Uses window size.
*/
-bScreen *screen_add(const char *name, const int winsize_x, const int winsize_y)
+bScreen *screen_add(Main *bmain, const char *name, const rcti *rect)
{
bScreen *sc;
ScrVert *sv1, *sv2, *sv3, *sv4;
-
- sc = BKE_libblock_alloc(G.main, ID_SCR, name, 0);
+
+ sc = BKE_libblock_alloc(bmain, ID_SCR, name, 0);
sc->do_refresh = true;
sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN;
- sv1 = screen_addvert(sc, 0, 0);
- sv2 = screen_addvert(sc, 0, winsize_y - 1);
- sv3 = screen_addvert(sc, winsize_x - 1, winsize_y - 1);
- sv4 = screen_addvert(sc, winsize_x - 1, 0);
-
- screen_addedge(sc, sv1, sv2);
- screen_addedge(sc, sv2, sv3);
- screen_addedge(sc, sv3, sv4);
- screen_addedge(sc, sv4, sv1);
-
+ sv1 = screen_geom_vertex_add(sc, rect->xmin, rect->ymin);
+ sv2 = screen_geom_vertex_add(sc, rect->xmin, rect->ymax - 1);
+ sv3 = screen_geom_vertex_add(sc, rect->xmax - 1, rect->ymax - 1);
+ sv4 = screen_geom_vertex_add(sc, rect->xmax - 1, rect->ymin);
+
+ screen_geom_edge_add(sc, sv1, sv2);
+ screen_geom_edge_add(sc, sv2, sv3);
+ screen_geom_edge_add(sc, sv3, sv4);
+ screen_geom_edge_add(sc, sv4, sv1);
+
/* dummy type, no spacedata */
screen_addarea(sc, sv1, sv2, sv3, sv4, SPACE_EMPTY);
-
+
return sc;
}
@@ -364,26 +236,26 @@ void screen_data_copy(bScreen *to, bScreen *from)
ScrVert *s1, *s2;
ScrEdge *se;
ScrArea *sa, *saf;
-
+
/* free contents of 'to', is from blenkernel screen.c */
BKE_screen_free(to);
-
+
BLI_duplicatelist(&to->vertbase, &from->vertbase);
BLI_duplicatelist(&to->edgebase, &from->edgebase);
BLI_duplicatelist(&to->areabase, &from->areabase);
BLI_listbase_clear(&to->regionbase);
-
+
s2 = to->vertbase.first;
for (s1 = from->vertbase.first; s1; s1 = s1->next, s2 = s2->next) {
s1->newv = s2;
}
-
+
for (se = to->edgebase.first; se; se = se->next) {
se->v1 = se->v1->newv;
se->v2 = se->v2->newv;
BKE_screen_sort_scrvert(&(se->v1), &(se->v2));
}
-
+
saf = from->areabase.first;
for (sa = to->areabase.first; sa; sa = sa->next, saf = saf->next) {
sa->v1 = sa->v1->newv;
@@ -395,10 +267,10 @@ void screen_data_copy(bScreen *to, bScreen *from)
BLI_listbase_clear(&sa->regionbase);
BLI_listbase_clear(&sa->actionzones);
BLI_listbase_clear(&sa->handlers);
-
+
ED_area_data_copy(sa, saf, true);
}
-
+
/* put at zero (needed?) */
for (s1 = from->vertbase.first; s1; s1 = s1->next)
s1->newv = NULL;
@@ -433,7 +305,7 @@ int area_getorientation(ScrArea *sa, ScrArea *sb)
sbv2 = sb->v2;
sbv3 = sb->v3;
sbv4 = sb->v4;
-
+
if (sav1 == sbv4 && sav2 == sbv3) { /* sa to right of sb = W */
return 0;
}
@@ -446,7 +318,7 @@ int area_getorientation(ScrArea *sa, ScrArea *sb)
else if (sav1 == sbv2 && sav4 == sbv3) { /* sa on top of sb = S*/
return 3;
}
-
+
return -1;
}
@@ -456,39 +328,39 @@ int area_getorientation(ScrArea *sa, ScrArea *sb)
int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2)
{
int dir;
-
+
dir = area_getorientation(sa1, sa2);
/*printf("dir is : %i\n", dir);*/
-
+
if (dir == -1) {
return 0;
}
-
+
if (dir == 0) {
sa1->v1 = sa2->v1;
sa1->v2 = sa2->v2;
- screen_addedge(scr, sa1->v2, sa1->v3);
- screen_addedge(scr, sa1->v1, sa1->v4);
+ screen_geom_edge_add(scr, sa1->v2, sa1->v3);
+ screen_geom_edge_add(scr, sa1->v1, sa1->v4);
}
else if (dir == 1) {
sa1->v2 = sa2->v2;
sa1->v3 = sa2->v3;
- screen_addedge(scr, sa1->v1, sa1->v2);
- screen_addedge(scr, sa1->v3, sa1->v4);
+ screen_geom_edge_add(scr, sa1->v1, sa1->v2);
+ screen_geom_edge_add(scr, sa1->v3, sa1->v4);
}
else if (dir == 2) {
sa1->v3 = sa2->v3;
sa1->v4 = sa2->v4;
- screen_addedge(scr, sa1->v2, sa1->v3);
- screen_addedge(scr, sa1->v1, sa1->v4);
+ screen_geom_edge_add(scr, sa1->v2, sa1->v3);
+ screen_geom_edge_add(scr, sa1->v1, sa1->v4);
}
else if (dir == 3) {
sa1->v1 = sa2->v1;
sa1->v4 = sa2->v4;
- screen_addedge(scr, sa1->v1, sa1->v2);
- screen_addedge(scr, sa1->v3, sa1->v4);
+ screen_geom_edge_add(scr, sa1->v1, sa1->v2);
+ screen_geom_edge_add(scr, sa1->v3, sa1->v4);
}
-
+
screen_delarea(C, scr, sa2);
BKE_screen_remove_double_scrverts(scr);
/* Update preview thumbnail */
@@ -497,241 +369,6 @@ int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2)
return 1;
}
-void select_connected_scredge(const wmWindow *win, ScrEdge *edge)
-{
- bScreen *sc = WM_window_get_active_screen(win);
- ScrEdge *se;
- int oneselected;
- char dir;
-
- /* select connected, only in the right direction */
- /* 'dir' is the direction of EDGE */
-
- if (edge->v1->vec.x == edge->v2->vec.x) dir = 'v';
- else dir = 'h';
-
- ED_screen_verts_iter(win, sc, sv) {
- sv->flag = 0;
- }
-
- edge->v1->flag = 1;
- edge->v2->flag = 1;
-
- oneselected = 1;
- while (oneselected) {
- se = sc->edgebase.first;
- oneselected = 0;
- while (se) {
- if (se->v1->flag + se->v2->flag == 1) {
- if (dir == 'h') {
- if (se->v1->vec.y == se->v2->vec.y) {
- se->v1->flag = se->v2->flag = 1;
- oneselected = 1;
- }
- }
- if (dir == 'v') {
- if (se->v1->vec.x == se->v2->vec.x) {
- se->v1->flag = se->v2->flag = 1;
- oneselected = 1;
- }
- }
- }
- se = se->next;
- }
- }
-}
-
-/**
- * Test if screen vertices should be scaled and do if needed.
- */
-static void screen_vertices_scale(
- const wmWindow *win, bScreen *sc,
- int window_size_x, int window_size_y,
- int screen_size_x, int screen_size_y)
-{
- /* clamp Y size of header sized areas when expanding windows
- * avoids annoying empty space around file menu */
-#define USE_HEADER_SIZE_CLAMP
-
- const int headery_init = ED_area_headersize();
- ScrVert *sv = NULL;
- ScrArea *sa;
- int screen_size_x_prev, screen_size_y_prev;
- float facx, facy, tempf, min[2], max[2];
-
- /* calculate size */
- min[0] = min[1] = 20000.0f;
- max[0] = max[1] = 0.0f;
-
- for (sv = sc->vertbase.first; sv; sv = sv->next) {
- const float fv[2] = {(float)sv->vec.x, (float)sv->vec.y};
- minmax_v2v2_v2(min, max, fv);
- }
-
- /* always make 0.0 left under */
- for (sv = sc->vertbase.first; sv; sv = sv->next) {
- sv->vec.x -= min[0];
- sv->vec.y -= min[1];
- }
-
- screen_size_x_prev = (max[0] - min[0]) + 1;
- screen_size_y_prev = (max[1] - min[1]) + 1;
-
-
-#ifdef USE_HEADER_SIZE_CLAMP
-#define TEMP_BOTTOM 1
-#define TEMP_TOP 2
-
- /* if the window's Y axis grows, clamp header sized areas */
- if (screen_size_y_prev < screen_size_y) { /* growing? */
- const int headery_margin_max = headery_init + 4;
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
- sa->temp = 0;
-
- if (ar && !(ar->flag & RGN_FLAG_HIDDEN)) {
- if (sa->v2->vec.y == screen_size_y_prev) {
- if ((sa->v2->vec.y - sa->v1->vec.y) < headery_margin_max) {
- sa->temp = TEMP_TOP;
- }
- }
- else if (sa->v1->vec.y == 0) {
- if ((sa->v2->vec.y - sa->v1->vec.y) < headery_margin_max) {
- sa->temp = TEMP_BOTTOM;
- }
- }
- }
- }
- }
-#endif
-
-
- if (screen_size_x_prev != screen_size_x || screen_size_y_prev != screen_size_y) {
- facx = ((float)screen_size_x - 1) / ((float)screen_size_x_prev - 1);
- facy = ((float)screen_size_y) / ((float)screen_size_y_prev);
-
- /* make sure it fits! */
- for (sv = sc->vertbase.first; sv; sv = sv->next) {
- /* FIXME, this re-sizing logic is no good when re-sizing the window + redrawing [#24428]
- * need some way to store these as floats internally and re-apply from there. */
- tempf = ((float)sv->vec.x) * facx;
- sv->vec.x = (short)(tempf + 0.5f);
- //sv->vec.x += AREAGRID - 1;
- //sv->vec.x -= (sv->vec.x % AREAGRID);
-
- CLAMP(sv->vec.x, 0, screen_size_x - 1);
-
- tempf = ((float)sv->vec.y) * facy;
- sv->vec.y = (short)(tempf + 0.5f);
- //sv->vec.y += AREAGRID - 1;
- //sv->vec.y -= (sv->vec.y % AREAGRID);
-
- CLAMP(sv->vec.y, 0, screen_size_y);
- }
- }
-
-
-#ifdef USE_HEADER_SIZE_CLAMP
- if (screen_size_y_prev < screen_size_y) { /* growing? */
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- ScrEdge *se = NULL;
-
- if (sa->temp == 0)
- continue;
-
- if (sa->v1 == sa->v2)
- continue;
-
- /* adjust headery if verts are along the edge of window */
- if (sa->temp == TEMP_TOP) {
- /* lower edge */
- const int yval = sa->v2->vec.y - headery_init;
- se = BKE_screen_find_edge(sc, sa->v4, sa->v1);
- if (se != NULL) {
- select_connected_scredge(win, se);
- }
- for (sv = sc->vertbase.first; sv; sv = sv->next) {
- if (sv != sa->v2 && sv != sa->v3) {
- if (sv->flag) {
- sv->vec.y = yval;
- }
- }
- }
- }
- else {
- /* upper edge */
- const int yval = sa->v1->vec.y + headery_init;
- se = BKE_screen_find_edge(sc, sa->v2, sa->v3);
- if (se != NULL) {
- select_connected_scredge(win, se);
- }
- for (sv = sc->vertbase.first; sv; sv = sv->next) {
- if (sv != sa->v1 && sv != sa->v4) {
- if (sv->flag) {
- sv->vec.y = yval;
- }
- }
- }
- }
- }
- }
-
-#undef USE_HEADER_SIZE_CLAMP
-#undef TEMP_BOTTOM
-#undef TEMP_TOP
-#endif
-
-
- /* test for collapsed areas. This could happen in some blender version... */
- /* ton: removed option now, it needs Context... */
-
- /* make each window at least ED_area_headersize() high */
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- int headery = headery_init;
-
- /* adjust headery if verts are along the edge of window */
- if (sa->v1->vec.y > 0)
- headery += U.pixelsize;
- if (sa->v2->vec.y < screen_size_y)
- headery += U.pixelsize;
-
- if (sa->v2->vec.y - sa->v1->vec.y + 1 < headery) {
- /* lower edge */
- ScrEdge *se = BKE_screen_find_edge(sc, sa->v4, sa->v1);
- if (se && sa->v1 != sa->v2) {
- int yval;
-
- select_connected_scredge(win, se);
-
- /* all selected vertices get the right offset */
- yval = sa->v2->vec.y - headery + 1;
- for (sv = sc->vertbase.first; sv; sv = sv->next) {
- /* if is a collapsed area */
- if (sv != sa->v2 && sv != sa->v3) {
- if (sv->flag) {
- sv->vec.y = yval;
- }
- }
- }
- }
- }
- }
-
- /* Global areas have a fixed size that only changes with the DPI. Here we ensure that exactly this size is set.
- * TODO Assumes global area to be top-aligned. Should be made more generic */
- for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) {
- if (area->global->flag & GLOBAL_AREA_IS_HIDDEN) {
- continue;
- }
- /* width */
- area->v1->vec.x = area->v2->vec.x = 0;
- area->v3->vec.x = area->v4->vec.x = window_size_x - 1;
- /* height */
- area->v2->vec.y = area->v3->vec.y = window_size_y - 1;
- area->v1->vec.y = area->v4->vec.y = area->v2->vec.y - ED_area_global_size_y(area);
- }
-}
-
/* ****************** EXPORTED API TO OTHER MODULES *************************** */
@@ -787,7 +424,7 @@ static void screen_refresh_headersizes(void)
{
const ListBase *lb = BKE_spacetypes_list();
SpaceType *st;
-
+
for (st = lb->first; st; st = st->next) {
ARegionType *art = BKE_regiontype_from_id(st, RGN_TYPE_HEADER);
if (art) art->prefsizey = ED_area_headersize();
@@ -802,23 +439,23 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
/* exception for bg mode, we only need the screen context */
if (!G.background) {
- const int window_size_x = WM_window_pixels_x(win);
- const int window_size_y = WM_window_pixels_y(win);
- const int screen_size_x = WM_window_screen_pixels_x(win);
- const int screen_size_y = WM_window_screen_pixels_y(win);
+ rcti window_rect, screen_rect;
/* header size depends on DPI, let's verify */
WM_window_set_dpi(win);
screen_refresh_headersizes();
- screen_vertices_scale(win, screen, window_size_x, window_size_y, screen_size_x, screen_size_y);
+ WM_window_rect_calc(win, &window_rect);
+ WM_window_screen_rect_calc(win, &screen_rect); /* Get screen bounds __after__ updating window DPI! */
+
+ screen_geom_vertices_scale(win, screen);
ED_screen_areas_iter(win, screen, area) {
/* set spacetype and region callbacks, calls init() */
/* sets subwindows for regions, adds handlers */
ED_area_initialize(wm, win, area);
}
-
+
/* wake up animtimer */
if (screen->animtimer)
WM_event_timer_sleep(wm, win, screen->animtimer, false);
@@ -835,19 +472,22 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
}
/* file read, set all screens, ... */
-void ED_screens_initialize(wmWindowManager *wm)
+void ED_screens_initialize(Main *bmain, wmWindowManager *wm)
{
wmWindow *win;
-
+
for (win = wm->windows.first; win; win = win->next) {
if (WM_window_get_active_workspace(win) == NULL) {
- WM_window_set_active_workspace(win, G.main->workspaces.first);
+ WM_window_set_active_workspace(win, bmain->workspaces.first);
}
if (BLI_listbase_is_empty(&win->global_areas.areabase)) {
ED_screen_global_areas_create(win);
}
ED_screen_refresh(wm, win);
+ if (win->eventstate) {
+ ED_screen_set_active_region(NULL, win, &win->eventstate->x);
+ }
}
}
@@ -875,12 +515,12 @@ void ED_region_exit(bContext *C, ARegion *ar)
WM_event_remove_handlers(C, &ar->handlers);
WM_event_modal_handler_region_replace(win, ar, NULL);
WM_draw_region_free(ar);
-
+
if (ar->headerstr) {
MEM_freeN(ar->headerstr);
ar->headerstr = NULL;
}
-
+
if (ar->regiontimer) {
WM_event_remove_timer(wm, win, ar->regiontimer);
ar->regiontimer = NULL;
@@ -916,31 +556,30 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *prevwin = CTX_wm_window(C);
- ScrArea *sa;
- ARegion *ar;
CTX_wm_window_set(C, window);
-
+
if (screen->animtimer)
WM_event_remove_timer(wm, window, screen->animtimer);
screen->animtimer = NULL;
screen->scrubbing = false;
screen->active_region = NULL;
-
- for (ar = screen->regionbase.first; ar; ar = ar->next) {
+
+ for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) {
ED_region_exit(C, ar);
}
- for (sa = screen->areabase.first; sa; sa = sa->next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
ED_area_exit(C, sa);
}
- for (sa = window->global_areas.areabase.first; sa; sa = sa->next) {
+ /* Don't use ED_screen_areas_iter here, it skips hidden areas. */
+ for (ScrArea *sa = window->global_areas.areabase.first; sa; sa = sa->next) {
ED_area_exit(C, sa);
}
/* mark it available for use for other windows */
screen->winid = 0;
-
+
if (!WM_window_is_temp_screen(prevwin)) {
/* use previous window if possible */
CTX_wm_window_set(C, prevwin);
@@ -949,7 +588,7 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
/* none otherwise */
CTX_wm_window_set(C, NULL);
}
-
+
}
/* *********************************** */
@@ -960,11 +599,11 @@ static void screen_cursor_set(wmWindow *win, const int xy[2])
const bScreen *screen = WM_window_get_active_screen(win);
AZone *az = NULL;
ScrArea *sa;
-
+
for (sa = screen->areabase.first; sa; sa = sa->next)
- if ((az = is_in_area_actionzone(sa, xy)))
+ if ((az = ED_area_actionzone_find_xy(sa, xy)))
break;
-
+
if (sa) {
if (az->type == AZONE_AREA)
WM_cursor_set(win, CURSOR_EDIT);
@@ -976,10 +615,10 @@ static void screen_cursor_set(wmWindow *win, const int xy[2])
}
}
else {
- ScrEdge *actedge = screen_find_active_scredge(win, screen, xy[0], xy[1]);
+ ScrEdge *actedge = screen_geom_find_active_scredge(win, screen, xy[0], xy[1]);
if (actedge) {
- if (scredge_is_horizontal(actedge))
+ if (screen_geom_edge_is_horizontal(actedge))
WM_cursor_set(win, CURSOR_Y_MOVE);
else
WM_cursor_set(win, CURSOR_X_MOVE);
@@ -992,9 +631,8 @@ static void screen_cursor_set(wmWindow *win, const int xy[2])
/* called in wm_event_system.c. sets state vars in screen, cursors */
/* event type is mouse move */
-void ED_screen_set_active_region(bContext *C, const int xy[2])
+void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
{
- wmWindow *win = CTX_wm_window(C);
bScreen *scr = WM_window_get_active_screen(win);
if (scr) {
@@ -1005,7 +643,7 @@ void ED_screen_set_active_region(bContext *C, const int xy[2])
ED_screen_areas_iter(win, scr, area_iter) {
if (xy[0] > area_iter->totrct.xmin && xy[0] < area_iter->totrct.xmax) {
if (xy[1] > area_iter->totrct.ymin && xy[1] < area_iter->totrct.ymax) {
- if (is_in_area_actionzone(area_iter, xy) == NULL) {
+ if (ED_area_actionzone_refresh_xy(area_iter, xy) == NULL) {
sa = area_iter;
break;
}
@@ -1023,29 +661,29 @@ void ED_screen_set_active_region(bContext *C, const int xy[2])
}
else
scr->active_region = NULL;
-
+
/* check for redraw headers */
if (old_ar != scr->active_region) {
ED_screen_areas_iter(win, scr, area_iter) {
bool do_draw = false;
-
+
for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
if (ar == old_ar || ar == scr->active_region) {
do_draw = true;
}
}
-
+
if (do_draw) {
for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_HEADER) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw_no_rebuild(ar);
}
}
}
}
}
-
+
/* cursors, for time being set always on edges, otherwise aregion doesnt switch */
if (scr->active_region == NULL) {
screen_cursor_set(win, xy);
@@ -1058,7 +696,9 @@ void ED_screen_set_active_region(bContext *C, const int xy[2])
/* this used to be a notifier, but needs to be done immediate
* because it can undo setting the right button as active due
* to delayed notifier handling */
- UI_screen_free_active_but(C, scr);
+ if (C) {
+ UI_screen_free_active_but(C, scr);
+ }
}
else
region_cursor_set(win, false);
@@ -1073,12 +713,12 @@ int ED_screen_area_active(const bContext *C)
ScrArea *sa = CTX_wm_area(C);
if (win && sc && sa) {
- AZone *az = is_in_area_actionzone(sa, &win->eventstate->x);
+ AZone *az = ED_area_actionzone_find_xy(sa, &win->eventstate->x);
ARegion *ar;
-
+
if (az && az->type == AZONE_REGION)
return 1;
-
+
for (ar = sa->regionbase.first; ar; ar = ar->next)
if (ar == sc->active_region)
return 1;
@@ -1094,52 +734,69 @@ static ScrArea *screen_area_create_with_geometry(
ScrAreaMap *area_map, const rcti *rect,
short spacetype)
{
- ScrVert *bottom_left = screen_addvert_ex(area_map, rect->xmin, rect->ymin);
- ScrVert *top_left = screen_addvert_ex(area_map, rect->xmin, rect->ymax);
- ScrVert *top_right = screen_addvert_ex(area_map, rect->xmax, rect->ymax);
- ScrVert *bottom_right = screen_addvert_ex(area_map, rect->xmax, rect->ymin);
+ ScrVert *bottom_left = screen_geom_vertex_add_ex(area_map, rect->xmin, rect->ymin);
+ ScrVert *top_left = screen_geom_vertex_add_ex(area_map, rect->xmin, rect->ymax);
+ ScrVert *top_right = screen_geom_vertex_add_ex(area_map, rect->xmax, rect->ymax);
+ ScrVert *bottom_right = screen_geom_vertex_add_ex(area_map, rect->xmax, rect->ymin);
- screen_addedge_ex(area_map, bottom_left, top_left);
- screen_addedge_ex(area_map, top_left, top_right);
- screen_addedge_ex(area_map, top_right, bottom_right);
- screen_addedge_ex(area_map, bottom_right, bottom_left);
+ screen_geom_edge_add_ex(area_map, bottom_left, top_left);
+ screen_geom_edge_add_ex(area_map, top_left, top_right);
+ screen_geom_edge_add_ex(area_map, top_right, bottom_right);
+ screen_geom_edge_add_ex(area_map, bottom_right, bottom_left);
return screen_addarea_ex(area_map, bottom_left, top_left, top_right, bottom_right, spacetype);
}
-void ED_screen_global_topbar_area_create(wmWindow *win, const bScreen *screen)
+static void screen_global_area_create(
+ wmWindow *win, eSpace_Type space_type, GlobalAreaAlign align, const rcti *rect,
+ const short height_cur, const short height_min, const short height_max)
{
- if (screen->temp == 0) {
- const short size_y = 2.25 * HEADERY;
- SpaceType *st;
- SpaceLink *sl;
- ScrArea *sa;
- rcti rect;
-
- BLI_rcti_init(&rect, 0, WM_window_pixels_x(win) - 1, 0, WM_window_pixels_y(win) - 1);
- rect.ymin = rect.ymax - size_y;
-
- sa = screen_area_create_with_geometry(&win->global_areas, &rect, SPACE_TOPBAR);
- st = BKE_spacetype_from_id(SPACE_TOPBAR);
- sl = st->new(sa, WM_window_get_active_scene(win));
- sa->regionbase = sl->regionbase;
-
- /* Data specific to global areas. */
- sa->global = MEM_callocN(sizeof(*sa->global), __func__);
- sa->global->cur_fixed_height = size_y;
- sa->global->size_max = size_y;
- sa->global->size_min = HEADERY;
-
- BLI_addhead(&sa->spacedata, sl);
- BLI_listbase_clear(&sl->regionbase);
- }
- /* Do not create more area types here! Function is called on file load (wm_window_ghostwindows_ensure). TODO */
+ ScrArea *area = screen_area_create_with_geometry(&win->global_areas, rect, space_type);
+ SpaceType *stype = BKE_spacetype_from_id(space_type);
+ SpaceLink *slink = stype->new(area, WM_window_get_active_scene(win));
+
+ area->regionbase = slink->regionbase;
+
+ /* Data specific to global areas. */
+ area->global = MEM_callocN(sizeof(*area->global), __func__);
+ area->global->cur_fixed_height = height_cur;
+ area->global->size_max = height_max;
+ area->global->size_min = height_min;
+ area->global->align = align;
+
+ BLI_addhead(&area->spacedata, slink);
+ BLI_listbase_clear(&slink->regionbase);
+}
+
+static void screen_global_topbar_area_create(wmWindow *win)
+{
+ const short size_y = 2.25 * HEADERY;
+ rcti rect;
+
+ BLI_rcti_init(&rect, 0, WM_window_pixels_x(win) - 1, 0, WM_window_pixels_y(win) - 1);
+ rect.ymin = rect.ymax - size_y;
+
+ screen_global_area_create(win, SPACE_TOPBAR, GLOBAL_AREA_ALIGN_TOP, &rect, size_y, HEADERY, size_y);
+}
+
+static void screen_global_statusbar_area_create(wmWindow *win)
+{
+ const short size_y = 0.8f * HEADERY;
+ rcti rect;
+
+ BLI_rcti_init(&rect, 0, WM_window_pixels_x(win) - 1, 0, WM_window_pixels_y(win) - 1);
+ rect.ymax = rect.ymin + size_y;
+
+ screen_global_area_create(win, SPACE_STATUSBAR, GLOBAL_AREA_ALIGN_BOTTOM, &rect, size_y, 0, size_y);
}
void ED_screen_global_areas_create(wmWindow *win)
{
- const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
- ED_screen_global_topbar_area_create(win, screen);
+ bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
+ if (screen->temp == 0) {
+ screen_global_topbar_area_create(win);
+ screen_global_statusbar_area_create(win);
+ }
}
@@ -1260,13 +917,13 @@ static void screen_set_3dview_camera(Scene *scene, ViewLayer *view_layer, ScrAre
if (!v3d->camera) {
ARegion *ar;
ListBase *regionbase;
-
+
/* regionbase is in different place depending if space is active */
if (v3d == sa->spacedata.first)
regionbase = &sa->regionbase;
else
regionbase = &v3d->regionbase;
-
+
for (ar = regionbase->first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = ar->regiondata;
@@ -1299,7 +956,7 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
if (!sa || sa->full == NULL) {
newsa = ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED);
}
-
+
if (!newsa) {
newsa = sa;
}
@@ -1356,10 +1013,10 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa)
SpaceLink *sl = sa->spacedata.first;
bScreen *screen = CTX_wm_screen(C);
short state = (screen ? screen->state : SCREENMAXIMIZED);
-
+
/* if fullscreen area has a temporary space (such as a file browser or fullscreen render
* overlaid on top of an existing setup) then return to the previous space */
-
+
if (sl->next) {
if (sa->flag & AREA_FLAG_TEMP_TYPE) {
ED_screen_full_prevspace(C, sa);
@@ -1382,6 +1039,7 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa)
*/
ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const short state)
{
+ Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
WorkSpace *workspace = WM_window_get_active_workspace(win);
bScreen *sc, *oldscreen;
@@ -1400,8 +1058,9 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
}
}
- /* prevent hanging header prints */
- ED_area_headerprint(sa, NULL);
+ /* prevent hanging status prints */
+ ED_area_status_text(sa, NULL);
+ ED_workspace_status_text(C, NULL);
}
if (sa && sa->full) {
@@ -1472,7 +1131,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
oldscreen->state = state;
BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "nonnormal");
- layout_new = ED_workspace_layout_add(workspace, win, newname);
+ layout_new = ED_workspace_layout_add(bmain, workspace, win, newname);
sc = BKE_workspace_layout_screen_get(layout_new);
sc->state = state;
@@ -1485,7 +1144,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
/* use random area when we have no active one, e.g. when the
* mouse is outside of the window and we open a file browser */
- if (!sa) {
+ if (!sa || sa->global) {
sa = oldscreen->areabase.first;
}
@@ -1527,15 +1186,15 @@ void ED_refresh_viewport_fps(bContext *C)
{
wmTimer *animtimer = CTX_wm_screen(C)->animtimer;
Scene *scene = CTX_data_scene(C);
-
+
/* is anim playback running? */
if (animtimer && (U.uiflag & USER_SHOW_FPS)) {
ScreenFrameRateInfo *fpsi = scene->fps_info;
-
+
/* if there isn't any info, init it first */
if (fpsi == NULL)
fpsi = scene->fps_info = MEM_callocN(sizeof(ScreenFrameRateInfo), "refresh_viewport_fps fps_info");
-
+
/* update the values */
fpsi->redrawtime = fpsi->lredrawtime;
fpsi->lredrawtime = animtimer->ltime;
@@ -1548,7 +1207,7 @@ void ED_refresh_viewport_fps(bContext *C)
}
}
-/* redraws: uses defines from stime->redraws
+/* redraws: uses defines from stime->redraws
* enable: 1 - forward on, -1 - backwards on, 0 - off
*/
void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync, int enable)
@@ -1558,17 +1217,17 @@ void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync,
wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
bScreen *stopscreen = ED_screen_animation_playing(wm);
-
+
if (stopscreen) {
WM_event_remove_timer(wm, win, stopscreen->animtimer);
stopscreen->animtimer = NULL;
}
-
+
if (enable) {
ScreenAnimData *sad = MEM_callocN(sizeof(ScreenAnimData), "ScreenAnimData");
-
+
screen->animtimer = WM_event_add_timer(wm, win, TIMER0, (1.0 / FPS));
-
+
sad->ar = CTX_wm_region(C);
/* if startframe is larger than current frame, we put currentframe on startframe.
* note: first frame then is not drawn! (ton) */
@@ -1603,7 +1262,7 @@ void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync,
sad->from_anim_edit = (ELEM(spacetype, SPACE_IPO, SPACE_ACTION, SPACE_NLA));
screen->animtimer->customdata = sad;
-
+
}
/* notifier catched by top header, for button */
@@ -1616,7 +1275,7 @@ static ARegion *time_top_left_3dwindow(bScreen *screen)
ARegion *aret = NULL;
ScrArea *sa;
int min = 10000;
-
+
for (sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->spacetype == SPACE_VIEW3D) {
ARegion *ar;
@@ -1639,7 +1298,7 @@ void ED_screen_animation_timer_update(bScreen *screen, int redraws, int refresh)
if (screen && screen->animtimer) {
wmTimer *wt = screen->animtimer;
ScreenAnimData *sad = wt->customdata;
-
+
sad->redraws = redraws;
sad->refresh = refresh;
sad->ar = NULL;
@@ -1662,9 +1321,10 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
BKE_screen_view3d_scene_sync(sc, scene);
}
+ DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
}
#endif
-
+
ED_clip_update_frame(bmain, scene->r.cfra);
/* this function applies the changes too */
@@ -1673,7 +1333,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
/* composite */
if (scene->use_nodes && scene->nodetree)
ntreeCompositTagAnimated(scene->nodetree);
-
+
/* update animated texture nodes */
{
Tex *tex;
@@ -1683,7 +1343,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
}
}
}
-
+
}
/*
diff --git a/source/blender/editors/screen/screen_geometry.c b/source/blender/editors/screen/screen_geometry.c
new file mode 100644
index 00000000000..5d87479e371
--- /dev/null
+++ b/source/blender/editors/screen/screen_geometry.c
@@ -0,0 +1,462 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/screen/screen_geometry.c
+ * \ingroup edscr
+ * \brief Functions for screen vertices and edges
+ *
+ * Screen geometry refers to the vertices (ScrVert) and edges (ScrEdge) through
+ * which the flexible screen-layout system of Blender is established.
+ */
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_rect.h"
+
+#include "BKE_screen.h"
+
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "ED_screen.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "WM_api.h"
+
+#include "screen_intern.h"
+
+
+int screen_geom_area_height(const ScrArea *area)
+{
+ return area->v2->vec.y - area->v1->vec.y + 1;
+}
+int screen_geom_area_width(const ScrArea *area)
+{
+ return area->v4->vec.x - area->v1->vec.x + 1;
+}
+
+ScrVert *screen_geom_vertex_add_ex(ScrAreaMap *area_map, short x, short y)
+{
+ ScrVert *sv = MEM_callocN(sizeof(ScrVert), "addscrvert");
+ sv->vec.x = x;
+ sv->vec.y = y;
+
+ BLI_addtail(&area_map->vertbase, sv);
+ return sv;
+}
+ScrVert *screen_geom_vertex_add(bScreen *sc, short x, short y)
+{
+ return screen_geom_vertex_add_ex(AREAMAP_FROM_SCREEN(sc), x, y);
+}
+
+ScrEdge *screen_geom_edge_add_ex(ScrAreaMap *area_map, ScrVert *v1, ScrVert *v2)
+{
+ ScrEdge *se = MEM_callocN(sizeof(ScrEdge), "addscredge");
+
+ BKE_screen_sort_scrvert(&v1, &v2);
+ se->v1 = v1;
+ se->v2 = v2;
+
+ BLI_addtail(&area_map->edgebase, se);
+ return se;
+}
+ScrEdge *screen_geom_edge_add(bScreen *sc, ScrVert *v1, ScrVert *v2)
+{
+ return screen_geom_edge_add_ex(AREAMAP_FROM_SCREEN(sc), v1, v2);
+}
+
+bool screen_geom_edge_is_horizontal(ScrEdge *se)
+{
+ return (se->v1->vec.y == se->v2->vec.y);
+}
+
+/**
+ * \param bounds_rect: Either window or screen bounds. Used to exclude edges along window/screen edges.
+ */
+ScrEdge *screen_geom_area_map_find_active_scredge(
+ const ScrAreaMap *area_map,
+ const rcti *bounds_rect,
+ const int mx, const int my)
+{
+ int safety = U.widget_unit / 10;
+
+ CLAMP_MIN(safety, 2);
+
+ for (ScrEdge *se = area_map->edgebase.first; se; se = se->next) {
+ if (screen_geom_edge_is_horizontal(se)) {
+ if ((se->v1->vec.y > bounds_rect->ymin) && (se->v1->vec.y < (bounds_rect->ymax - 1))) {
+ short min, max;
+ min = MIN2(se->v1->vec.x, se->v2->vec.x);
+ max = MAX2(se->v1->vec.x, se->v2->vec.x);
+
+ if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max)
+ return se;
+ }
+ }
+ else {
+ if ((se->v1->vec.x > bounds_rect->xmin) && (se->v1->vec.x < (bounds_rect->xmax - 1))) {
+ short min, max;
+ min = MIN2(se->v1->vec.y, se->v2->vec.y);
+ max = MAX2(se->v1->vec.y, se->v2->vec.y);
+
+ if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max)
+ return se;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/* need win size to make sure not to include edges along screen edge */
+ScrEdge *screen_geom_find_active_scredge(
+ const wmWindow *win, const bScreen *screen,
+ const int mx, const int my)
+{
+ /* Use layout size (screen excluding global areas) for screen-layout area edges */
+ rcti screen_rect;
+ ScrEdge *se;
+
+ WM_window_screen_rect_calc(win, &screen_rect);
+ se = screen_geom_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(screen), &screen_rect, mx, my);
+
+ if (!se) {
+ /* Use entire window size (screen including global areas) for global area edges */
+ rcti win_rect;
+ WM_window_rect_calc(win, &win_rect);
+ se = screen_geom_area_map_find_active_scredge(&win->global_areas, &win_rect, mx, my);
+ }
+ return se;
+}
+
+/**
+ * \brief Main screen-layout calculation function.
+ *
+ * * Scale areas nicely on window size and DPI changes.
+ * * Ensure areas have a minimum height.
+ * * Correctly set global areas to their fixed height.
+ */
+void screen_geom_vertices_scale(const wmWindow *win, bScreen *sc)
+{
+ /* clamp Y size of header sized areas when expanding windows
+ * avoids annoying empty space around file menu */
+#define USE_HEADER_SIZE_CLAMP
+
+ rcti window_rect, screen_rect;
+
+ WM_window_rect_calc(win, &window_rect);
+ WM_window_screen_rect_calc(win, &screen_rect);
+
+ const int headery_init = ED_area_headersize();
+ const int screen_size_x = BLI_rcti_size_x(&screen_rect);
+ const int screen_size_y = BLI_rcti_size_y(&screen_rect);
+ ScrVert *sv = NULL;
+ ScrArea *sa;
+ int screen_size_x_prev, screen_size_y_prev;
+ float min[2], max[2];
+
+ /* calculate size */
+ min[0] = min[1] = 20000.0f;
+ max[0] = max[1] = 0.0f;
+
+ for (sv = sc->vertbase.first; sv; sv = sv->next) {
+ const float fv[2] = {(float)sv->vec.x, (float)sv->vec.y};
+ minmax_v2v2_v2(min, max, fv);
+ }
+
+ screen_size_x_prev = (max[0] - min[0]) + 1;
+ screen_size_y_prev = (max[1] - min[1]) + 1;
+
+
+#ifdef USE_HEADER_SIZE_CLAMP
+#define TEMP_BOTTOM 1
+#define TEMP_TOP 2
+
+ /* if the window's Y axis grows, clamp header sized areas */
+ if (screen_size_y_prev < screen_size_y) { /* growing? */
+ const int headery_margin_max = headery_init + 5;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
+ sa->temp = 0;
+
+ if (ar && !(ar->flag & RGN_FLAG_HIDDEN)) {
+ if (sa->v2->vec.y == max[1]) {
+ if (screen_geom_area_height(sa) < headery_margin_max) {
+ sa->temp = TEMP_TOP;
+ }
+ }
+ else if (sa->v1->vec.y == min[1]) {
+ if (screen_geom_area_height(sa) < headery_margin_max) {
+ sa->temp = TEMP_BOTTOM;
+ }
+ }
+ }
+ }
+ }
+#endif
+
+
+ if (screen_size_x_prev != screen_size_x || screen_size_y_prev != screen_size_y) {
+ const float facx = ((float)screen_size_x - 1) / ((float)screen_size_x_prev - 1);
+ const float facy = ((float)screen_size_y - 1) / ((float)screen_size_y_prev - 1);
+
+ /* make sure it fits! */
+ for (sv = sc->vertbase.first; sv; sv = sv->next) {
+ sv->vec.x = screen_rect.xmin + round_fl_to_short((sv->vec.x - min[0]) * facx);
+ CLAMP(sv->vec.x, screen_rect.xmin, screen_rect.xmax - 1);
+
+ sv->vec.y = screen_rect.ymin + round_fl_to_short((sv->vec.y - min[1]) * facy);
+ CLAMP(sv->vec.y, screen_rect.ymin, screen_rect.ymax - 1);
+ }
+ }
+
+
+#ifdef USE_HEADER_SIZE_CLAMP
+ if (screen_size_y_prev < screen_size_y) { /* growing? */
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ ScrEdge *se = NULL;
+
+ if (sa->temp == 0)
+ continue;
+
+ if (sa->v1 == sa->v2)
+ continue;
+
+ /* adjust headery if verts are along the edge of window */
+ if (sa->temp == TEMP_TOP) {
+ /* lower edge */
+ const int yval = sa->v2->vec.y - headery_init;
+ se = BKE_screen_find_edge(sc, sa->v4, sa->v1);
+ if (se != NULL) {
+ screen_geom_select_connected_edge(win, se);
+ }
+ for (sv = sc->vertbase.first; sv; sv = sv->next) {
+ if (sv != sa->v2 && sv != sa->v3) {
+ if (sv->flag) {
+ sv->vec.y = yval;
+ }
+ }
+ }
+ }
+ else {
+ /* upper edge */
+ const int yval = sa->v1->vec.y + headery_init;
+ se = BKE_screen_find_edge(sc, sa->v2, sa->v3);
+ if (se != NULL) {
+ screen_geom_select_connected_edge(win, se);
+ }
+ for (sv = sc->vertbase.first; sv; sv = sv->next) {
+ if (sv != sa->v1 && sv != sa->v4) {
+ if (sv->flag) {
+ sv->vec.y = yval;
+ }
+ }
+ }
+ }
+ }
+ }
+
+#undef USE_HEADER_SIZE_CLAMP
+#undef TEMP_BOTTOM
+#undef TEMP_TOP
+#endif
+
+
+ /* test for collapsed areas. This could happen in some blender version... */
+ /* ton: removed option now, it needs Context... */
+
+ /* make each window at least ED_area_headersize() high */
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ int headery = headery_init;
+
+ /* adjust headery if verts are along the edge of window */
+ if (sa->v1->vec.y > window_rect.ymin)
+ headery += U.pixelsize;
+ if (sa->v2->vec.y < (window_rect.ymax - 1))
+ headery += U.pixelsize;
+
+ if (screen_geom_area_height(sa) < headery) {
+ /* lower edge */
+ ScrEdge *se = BKE_screen_find_edge(sc, sa->v4, sa->v1);
+ if (se && sa->v1 != sa->v2) {
+ const int yval = sa->v2->vec.y - headery + 1;
+
+ screen_geom_select_connected_edge(win, se);
+
+ /* all selected vertices get the right offset */
+ for (sv = sc->vertbase.first; sv; sv = sv->next) {
+ /* if is a collapsed area */
+ if (sv != sa->v2 && sv != sa->v3) {
+ if (sv->flag) {
+ sv->vec.y = yval;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Global areas have a fixed size that only changes with the DPI. Here we ensure that exactly this size is set. */
+ for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) {
+ if (area->global->flag & GLOBAL_AREA_IS_HIDDEN) {
+ continue;
+ }
+
+ int height = ED_area_global_size_y(area) - 1;
+
+ if (area->v1->vec.y > window_rect.ymin) {
+ height += U.pixelsize;
+ }
+ if (area->v2->vec.y < (window_rect.ymax - 1)) {
+ height += U.pixelsize;
+ }
+
+ /* width */
+ area->v1->vec.x = area->v2->vec.x = window_rect.xmin;
+ area->v3->vec.x = area->v4->vec.x = window_rect.xmax - 1;
+ /* height */
+ area->v1->vec.y = area->v4->vec.y = window_rect.ymin;
+ area->v2->vec.y = area->v3->vec.y = window_rect.ymax - 1;
+
+ switch (area->global->align) {
+ case GLOBAL_AREA_ALIGN_TOP:
+ area->v1->vec.y = area->v4->vec.y = area->v2->vec.y - height;
+ break;
+ case GLOBAL_AREA_ALIGN_BOTTOM:
+ area->v2->vec.y = area->v3->vec.y = area->v1->vec.y + height;
+ break;
+ }
+ }
+}
+
+/**
+ * \return 0 if no split is possible, otherwise the screen-coordinate at which to split.
+ */
+short screen_geom_find_area_split_point(const ScrArea *sa, const rcti *window_rect, char dir, float fac)
+{
+ short x, y;
+ const int cur_area_width = screen_geom_area_width(sa);
+ const int cur_area_height = screen_geom_area_height(sa);
+ const short area_min_x = AREAMINX;
+ const short area_min_y = ED_area_headersize();
+ int area_min;
+
+ // area big enough?
+ if ((dir == 'v') && (cur_area_width <= 2 * area_min_x)) {
+ return 0;
+ }
+ if ((dir == 'h') && (cur_area_height <= 2 * area_min_y)) {
+ return 0;
+ }
+
+ // to be sure
+ CLAMP(fac, 0.0f, 1.0f);
+
+ if (dir == 'h') {
+ y = sa->v1->vec.y + round_fl_to_short(fac * cur_area_height);
+
+ area_min = area_min_y;
+
+ if (sa->v1->vec.y > window_rect->ymin) {
+ area_min += U.pixelsize;
+ }
+ if (sa->v2->vec.y < (window_rect->ymax - 1)) {
+ area_min += U.pixelsize;
+ }
+
+ if (y - sa->v1->vec.y < area_min) {
+ y = sa->v1->vec.y + area_min;
+ }
+ else if (sa->v2->vec.y - y < area_min) {
+ y = sa->v2->vec.y - area_min;
+ }
+
+ return y;
+ }
+ else {
+ x = sa->v1->vec.x + round_fl_to_short(fac * cur_area_width);
+
+ area_min = area_min_x;
+
+ if (sa->v1->vec.x > window_rect->xmin) {
+ area_min += U.pixelsize;
+ }
+ if (sa->v4->vec.x < (window_rect->xmax - 1)) {
+ area_min += U.pixelsize;
+ }
+
+ if (x - sa->v1->vec.x < area_min) {
+ x = sa->v1->vec.x + area_min;
+ }
+ else if (sa->v4->vec.x - x < area_min) {
+ x = sa->v4->vec.x - area_min;
+ }
+
+ return x;
+ }
+}
+
+/**
+ * Select all edges that are directly or indirectly connected to \a edge.
+ */
+void screen_geom_select_connected_edge(const wmWindow *win, ScrEdge *edge)
+{
+ bScreen *sc = WM_window_get_active_screen(win);
+ bool oneselected = true;
+ char dir;
+
+ /* select connected, only in the right direction */
+ /* 'dir' is the direction of EDGE */
+
+ if (edge->v1->vec.x == edge->v2->vec.x) {
+ dir = 'v';
+ }
+ else {
+ dir = 'h';
+ }
+
+ ED_screen_verts_iter(win, sc, sv) {
+ sv->flag = 0;
+ }
+
+ edge->v1->flag = 1;
+ edge->v2->flag = 1;
+
+ while (oneselected) {
+ oneselected = false;
+ for (ScrEdge *se = sc->edgebase.first; se; se = se->next) {
+ if (se->v1->flag + se->v2->flag == 1) {
+ if (dir == 'h') {
+ if (se->v1->vec.y == se->v2->vec.y) {
+ se->v1->flag = se->v2->flag = 1;
+ oneselected = true;
+ }
+ }
+ if (dir == 'v') {
+ if (se->v1->vec.x == se->v2->vec.x) {
+ se->v1->flag = se->v2->flag = 1;
+ oneselected = true;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index 045e5ee6b48..cd71c07a3c0 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -4,7 +4,7 @@
* 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.
+ * 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
@@ -18,7 +18,7 @@
* The Original Code is Copyright (C) 2008 Blender Foundation.
* All rights reserved.
*
- *
+ *
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
@@ -48,26 +48,37 @@ void screen_area_update_region_sizes(wmWindowManager *wm, wmWindow *win,
void region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade);
/* screen_edit.c */
-bScreen *screen_add(const char *name, const int winsize_x, const int winsize_y);
+bScreen *screen_add(struct Main *bmain, const char *name, const rcti *rect);
void screen_data_copy(bScreen *to, bScreen *from);
void screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new);
void screen_change_update(struct bContext *C, wmWindow *win, bScreen *sc);
bScreen *screen_change_prepare(bScreen *screen_old, bScreen *screen_new, struct Main *bmain, struct bContext *C, wmWindow *win);
-ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge);
+ScrArea *area_split(const wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac, int merge);
int screen_area_join(struct bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2);
int area_getorientation(ScrArea *sa, ScrArea *sb);
-void select_connected_scredge(const wmWindow *win, ScrEdge *edge);
-bool scredge_is_horizontal(ScrEdge *se);
-ScrEdge *screen_area_map_find_active_scredge(
+struct AZone *ED_area_actionzone_find_xy(ScrArea *sa, const int xy[2]);
+struct AZone *ED_area_actionzone_refresh_xy(ScrArea *sa, const int xy[2]);
+
+/* screen_geometry.c */
+int screen_geom_area_height(const ScrArea *area);
+int screen_geom_area_width(const ScrArea *area);
+ScrVert *screen_geom_vertex_add_ex(ScrAreaMap *area_map, short x, short y);
+ScrVert *screen_geom_vertex_add(bScreen *sc, short x, short y);
+ScrEdge *screen_geom_edge_add_ex(ScrAreaMap *area_map, ScrVert *v1, ScrVert *v2);
+ScrEdge *screen_geom_edge_add(bScreen *sc, ScrVert *v1, ScrVert *v2);
+bool screen_geom_edge_is_horizontal(ScrEdge *se);
+ScrEdge *screen_geom_area_map_find_active_scredge(
const struct ScrAreaMap *area_map,
- const int winsize_x, const int winsize_y,
+ const rcti *bounds_rect,
const int mx, const int my);
-ScrEdge *screen_find_active_scredge(
+ScrEdge *screen_geom_find_active_scredge(
const wmWindow *win, const bScreen *screen,
const int mx, const int my);
+void screen_geom_vertices_scale(const wmWindow *win, bScreen *sc);
+short screen_geom_find_area_split_point(const ScrArea *sa, const rcti *window_rect, char dir, float fac);
+void screen_geom_select_connected_edge(const wmWindow *win, ScrEdge *edge);
-struct AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]);
/* screen_context.c */
int ed_screen_context(
@@ -77,7 +88,6 @@ extern const char *screen_context_dir[]; /* doc access */
/* screendump.c */
void SCREEN_OT_screenshot(struct wmOperatorType *ot);
-void SCREEN_OT_screencast(struct wmOperatorType *ot);
/* screen_ops.c */
void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 6f422a39584..2776bd98a43 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -4,7 +4,7 @@
* 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.
+ * 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
@@ -39,6 +39,7 @@
#include "BLT_translation.h"
+#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_lattice_types.h"
#include "DNA_object_types.h"
@@ -53,6 +54,7 @@
#include "BKE_context.h"
#include "BKE_customdata.h"
+#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_icons.h"
#include "BKE_main.h"
@@ -70,6 +72,7 @@
#include "DEG_depsgraph.h"
+#include "ED_anim_api.h"
#include "ED_armature.h"
#include "ED_clip.h"
#include "ED_image.h"
@@ -143,6 +146,14 @@ int ED_operator_screen_mainwinactive(bContext *C)
return 1;
}
+int ED_operator_scene(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ if (scene)
+ return 1;
+ return 0;
+}
+
int ED_operator_scene_editable(bContext *C)
{
Scene *scene = CTX_data_scene(C);
@@ -160,11 +171,11 @@ int ED_operator_objectmode(bContext *C)
return 0;
if (CTX_data_edit_object(C))
return 0;
-
+
/* add a check for ob->mode too? */
if (obact && (obact->mode != OB_MODE_OBJECT))
return 0;
-
+
return 1;
}
@@ -241,20 +252,20 @@ int ED_operator_buttons_active(bContext *C)
int ED_operator_node_active(bContext *C)
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
if (snode && snode->edittree)
return 1;
-
+
return 0;
}
int ED_operator_node_editable(bContext *C)
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
if (snode && snode->edittree && !ID_IS_LINKED(snode->edittree))
return 1;
-
+
return 0;
}
@@ -440,15 +451,15 @@ int ED_operator_uvmap(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = NULL;
-
+
if (obedit && obedit->type == OB_MESH) {
em = BKE_editmesh_from_object(obedit);
}
-
+
if (em && (em->bm->totface)) {
return true;
}
-
+
return false;
}
@@ -595,23 +606,23 @@ static ARegion *screen_find_region_type(bContext *C, int type)
/** \name Action Zone Operator
* \{ */
-/* operator state vars used:
+/* operator state vars used:
* none
- *
+ *
* functions:
- *
+ *
* apply() set actionzone event
- *
+ *
* exit() free customdata
- *
+ *
* callbacks:
- *
+ *
* exec() never used
- *
- * invoke() check if in zone
+ *
+ * invoke() check if in zone
* add customdata, put mouseco and area in it
* add modal handler
- *
+ *
* modal() accept modal events while doing it
* call apply() with gesture info, active window, nonactive window
* call exit() and remove handler when LMB confirm
@@ -628,11 +639,11 @@ static int actionzone_area_poll(bContext *C)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = CTX_wm_area(C);
-
+
if (sa && win && win->eventstate) {
const int *xy = &win->eventstate->x;
AZone *az;
-
+
for (az = sa->actionzones.first; az; az = az->next)
if (BLI_rcti_isect_pt_v(&az->rect, xy))
return 1;
@@ -658,117 +669,141 @@ static void fullscreen_click_rcti_init(rcti *rect, const short x1, const short y
BLI_rcti_init(rect, x, x + icon_size, y, y + icon_size);
}
-AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2])
+static AZone *area_actionzone_refresh_xy(ScrArea *sa, const int xy[2], const bool test_only)
{
AZone *az = NULL;
-
+
for (az = sa->actionzones.first; az; az = az->next) {
if (BLI_rcti_isect_pt_v(&az->rect, xy)) {
if (az->type == AZONE_AREA) {
/* no triangle intersect but a hotspot circle based on corner */
- int radius = (xy[0] - az->x1) * (xy[0] - az->x1) + (xy[1] - az->y1) * (xy[1] - az->y1);
-
- if (radius <= AZONESPOT * AZONESPOT)
+ int radius_sq = SQUARE(xy[0] - az->x1) + SQUARE(xy[1] - az->y1);
+ if (radius_sq <= SQUARE(AZONESPOT)) {
break;
+ }
}
else if (az->type == AZONE_REGION) {
break;
}
else if (az->type == AZONE_FULLSCREEN) {
- int mouse_radius, spot_radius, fadein_radius, fadeout_radius;
rcti click_rect;
-
fullscreen_click_rcti_init(&click_rect, az->x1, az->y1, az->x2, az->y2);
+ const bool click_isect = BLI_rcti_isect_pt_v(&click_rect, xy);
- if (BLI_rcti_isect_pt_v(&click_rect, xy)) {
- az->alpha = 1.0f;
+ if (test_only) {
+ if (click_isect) {
+ break;
+ }
}
else {
- mouse_radius = (xy[0] - az->x2) * (xy[0] - az->x2) + (xy[1] - az->y2) * (xy[1] - az->y2);
- spot_radius = AZONESPOT * AZONESPOT;
- fadein_radius = AZONEFADEIN * AZONEFADEIN;
- fadeout_radius = AZONEFADEOUT * AZONEFADEOUT;
-
- if (mouse_radius < spot_radius) {
+ if (click_isect) {
az->alpha = 1.0f;
}
- else if (mouse_radius < fadein_radius) {
- az->alpha = 1.0f;
- }
- else if (mouse_radius < fadeout_radius) {
- az->alpha = 1.0f - ((float)(mouse_radius - fadein_radius)) / ((float)(fadeout_radius - fadein_radius));
- }
else {
- az->alpha = 0.0f;
+ const int mouse_sq = SQUARE(xy[0] - az->x2) + SQUARE(xy[1] - az->y2);
+ const int spot_sq = SQUARE(AZONESPOT);
+ const int fadein_sq = SQUARE(AZONEFADEIN);
+ const int fadeout_sq = SQUARE(AZONEFADEOUT);
+
+ if (mouse_sq < spot_sq) {
+ az->alpha = 1.0f;
+ }
+ else if (mouse_sq < fadein_sq) {
+ az->alpha = 1.0f;
+ }
+ else if (mouse_sq < fadeout_sq) {
+ az->alpha = 1.0f - ((float)(mouse_sq - fadein_sq)) / ((float)(fadeout_sq - fadein_sq));
+ }
+ else {
+ az->alpha = 0.0f;
+ }
+
+ /* fade in/out but no click */
+ az = NULL;
}
- /* fade in/out but no click */
- az = NULL;
+ /* XXX force redraw to show/hide the action zone */
+ ED_area_tag_redraw(sa);
+ break;
}
-
- /* XXX force redraw to show/hide the action zone */
- ED_area_tag_redraw(sa);
- break;
}
else if (az->type == AZONE_REGION_SCROLL) {
ARegion *ar = az->ar;
View2D *v2d = &ar->v2d;
const short isect_value = UI_view2d_mouse_in_scrollers(ar, v2d, xy[0], xy[1]);
- bool redraw = false;
-
- if (isect_value == 'h') {
- if (az->direction == AZ_SCROLL_HOR) {
- az->alpha = 1.0f;
- v2d->alpha_hor = 255;
- v2d->size_hor = V2D_SCROLL_HEIGHT;
- redraw = true;
- }
- }
- else if (isect_value == 'v') {
- if (az->direction == AZ_SCROLL_VERT) {
- az->alpha = 1.0f;
- v2d->alpha_vert = 255;
- v2d->size_vert = V2D_SCROLL_WIDTH;
- redraw = true;
+ if (test_only) {
+ if (isect_value != 0) {
+ break;
}
}
else {
- const int local_xy[2] = {xy[0] - ar->winrct.xmin, xy[1] - ar->winrct.ymin};
- float dist_fac = 0.0f, alpha = 0.0f;
-
- if (az->direction == AZ_SCROLL_HOR) {
- dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / AZONEFADEIN;
- CLAMP(dist_fac, 0.0f, 1.0f);
- alpha = 1.0f - dist_fac;
+ bool redraw = false;
- v2d->alpha_hor = alpha * 255;
- v2d->size_hor = round_fl_to_int(V2D_SCROLL_HEIGHT -
- ((V2D_SCROLL_HEIGHT - V2D_SCROLL_HEIGHT_MIN) * dist_fac));
+ if (isect_value == 'h') {
+ if (az->direction == AZ_SCROLL_HOR) {
+ az->alpha = 1.0f;
+ v2d->alpha_hor = 255;
+ v2d->size_hor = V2D_SCROLL_HEIGHT;
+ redraw = true;
+ }
}
- else if (az->direction == AZ_SCROLL_VERT) {
- dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / AZONEFADEIN;
- CLAMP(dist_fac, 0.0f, 1.0f);
- alpha = 1.0f - dist_fac;
-
- v2d->alpha_vert = alpha * 255;
- v2d->size_vert = round_fl_to_int(V2D_SCROLL_WIDTH -
- ((V2D_SCROLL_WIDTH - V2D_SCROLL_WIDTH_MIN) * dist_fac));
+ else if (isect_value == 'v') {
+ if (az->direction == AZ_SCROLL_VERT) {
+ az->alpha = 1.0f;
+ v2d->alpha_vert = 255;
+ v2d->size_vert = V2D_SCROLL_WIDTH;
+ redraw = true;
+ }
+ }
+ else {
+ const int local_xy[2] = {xy[0] - ar->winrct.xmin, xy[1] - ar->winrct.ymin};
+ float dist_fac = 0.0f, alpha = 0.0f;
+
+ if (az->direction == AZ_SCROLL_HOR) {
+ dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / AZONEFADEIN;
+ CLAMP(dist_fac, 0.0f, 1.0f);
+ alpha = 1.0f - dist_fac;
+
+ v2d->alpha_hor = alpha * 255;
+ v2d->size_hor = round_fl_to_int(
+ V2D_SCROLL_HEIGHT -
+ ((V2D_SCROLL_HEIGHT - V2D_SCROLL_HEIGHT_MIN) * dist_fac));
+ }
+ else if (az->direction == AZ_SCROLL_VERT) {
+ dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / AZONEFADEIN;
+ CLAMP(dist_fac, 0.0f, 1.0f);
+ alpha = 1.0f - dist_fac;
+
+ v2d->alpha_vert = alpha * 255;
+ v2d->size_vert = round_fl_to_int(
+ V2D_SCROLL_WIDTH -
+ ((V2D_SCROLL_WIDTH - V2D_SCROLL_WIDTH_MIN) * dist_fac));
+ }
+ az->alpha = alpha;
+ redraw = true;
}
- az->alpha = alpha;
- redraw = true;
- }
- if (redraw) {
- ED_area_tag_redraw(sa);
+ if (redraw) {
+ ED_area_tag_redraw_no_rebuild(sa);
+ }
+ /* Don't return! */
}
- /* Don't return! */
}
}
}
-
+
return az;
}
+AZone *ED_area_actionzone_find_xy(ScrArea *sa, const int xy[2])
+{
+ return area_actionzone_refresh_xy(sa, xy, true);
+}
+
+AZone *ED_area_actionzone_refresh_xy(ScrArea *sa, const int xy[2])
+{
+ return area_actionzone_refresh_xy(sa, xy, false);
+}
static void actionzone_exit(wmOperator *op)
{
@@ -783,9 +818,9 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
wmEvent event;
wmWindow *win = CTX_wm_window(C);
sActionzoneData *sad = op->customdata;
-
+
sad->modifier = RNA_int_get(op->ptr, "modifier");
-
+
wm_event_init_from_window(win, &event);
if (type == AZONE_AREA)
@@ -799,39 +834,36 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
event.customdata = op->customdata;
event.customdatafree = true;
op->customdata = NULL;
-
+
wm_event_add(win, &event);
}
static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
- AZone *az = is_in_area_actionzone(sa, &event->x);
+ AZone *az = ED_area_actionzone_find_xy(sa, &event->x);
sActionzoneData *sad;
-
- /* quick escape */
- if (az == NULL)
+
+ /* quick escape - Scroll azones only hide/unhide the scroll-bars, they have their own handling. */
+ if (az == NULL || ELEM(az->type, AZONE_REGION_SCROLL))
return OPERATOR_PASS_THROUGH;
-
+
/* ok we do the actionzone */
sad = op->customdata = MEM_callocN(sizeof(sActionzoneData), "sActionzoneData");
sad->sa1 = sa;
sad->az = az;
sad->x = event->x; sad->y = event->y;
-
+
/* region azone directly reacts on mouse clicks */
if (ELEM(sad->az->type, AZONE_REGION, AZONE_FULLSCREEN)) {
actionzone_apply(C, op, sad->az->type);
actionzone_exit(op);
return OPERATOR_FINISHED;
}
- else if (ELEM(sad->az->type, AZONE_REGION_SCROLL)) {
- return OPERATOR_PASS_THROUGH;
- }
else {
/* add modal handler */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
}
@@ -839,11 +871,8 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- wmWindow *win = CTX_wm_window(C);
bScreen *sc = CTX_wm_screen(C);
sActionzoneData *sad = op->customdata;
- const int screen_size_x = WM_window_screen_pixels_x(win);
- const int screen_size_y = WM_window_screen_pixels_y(win);
switch (event->type) {
case MOUSEMOVE:
@@ -862,13 +891,17 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
sad->gesture_dir = 's';
else
sad->gesture_dir = 'w';
-
+
if (sad->az->type == AZONE_AREA) {
+ const wmWindow *win = CTX_wm_window(C);
+ rcti screen_rect;
+
+ WM_window_screen_rect_calc(win, &screen_rect);
/* once we drag outside the actionzone, register a gesture
* check we're not on an edge so join finds the other area */
- is_gesture = ((is_in_area_actionzone(sad->sa1, &event->x) != sad->az) &&
- (screen_area_map_find_active_scredge(
- AREAMAP_FROM_SCREEN(sc), screen_size_x, screen_size_y, event->x, event->y) == NULL));
+ is_gesture = ((ED_area_actionzone_find_xy(sad->sa1, &event->x) != sad->az) &&
+ (screen_geom_area_map_find_active_scredge(
+ AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y) == NULL));
}
else {
const int delta_min = 1;
@@ -882,7 +915,7 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* apply sends event */
actionzone_apply(C, op, sad->az->type);
actionzone_exit(op);
-
+
return OPERATOR_FINISHED;
}
break;
@@ -893,9 +926,9 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
case LEFTMOUSE:
actionzone_exit(op);
return OPERATOR_CANCELLED;
-
+
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -910,15 +943,15 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot)
ot->name = "Handle Area Action Zones";
ot->description = "Handle area action zones for mouse actions/gestures";
ot->idname = "SCREEN_OT_actionzone";
-
+
ot->invoke = actionzone_invoke;
ot->modal = actionzone_modal;
ot->poll = actionzone_area_poll;
ot->cancel = actionzone_cancel;
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
+
RNA_def_int(ot->srna, "modifier", 0, 0, 2, "Modifier", "Modifier state", 0, 2);
}
@@ -956,15 +989,15 @@ static int area_swap_init(wmOperator *op, const wmEvent *event)
{
sAreaSwapData *sd = NULL;
sActionzoneData *sad = event->customdata;
-
+
if (sad == NULL || sad->sa1 == NULL)
return 0;
-
+
sd = MEM_callocN(sizeof(sAreaSwapData), "sAreaSwapData");
sd->sa1 = sad->sa1;
sd->sa2 = sad->sa2;
op->customdata = sd;
-
+
return 1;
}
@@ -984,22 +1017,22 @@ static void area_swap_cancel(bContext *C, wmOperator *op)
static int area_swap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
-
+
if (!area_swap_init(op, event))
return OPERATOR_PASS_THROUGH;
-
+
/* add modal handler */
WM_cursor_modal_set(CTX_wm_window(C), BC_SWAPAREA_CURSOR);
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
-
+
}
static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sActionzoneData *sad = op->customdata;
-
+
switch (event->type) {
case MOUSEMOVE:
/* second area, for join */
@@ -1016,15 +1049,15 @@ static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
ED_area_tag_redraw(sad->sa2);
ED_area_swapspace(C, sad->sa1, sad->sa2);
-
+
area_swap_exit(C, op);
-
+
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
break;
-
+
case ESCKEY:
area_swap_cancel(C, op);
return OPERATOR_CANCELLED;
@@ -1037,12 +1070,12 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
ot->name = "Swap Areas";
ot->description = "Swap selected areas screen positions";
ot->idname = "SCREEN_OT_area_swap";
-
+
ot->invoke = area_swap_invoke;
ot->modal = area_swap_modal;
ot->poll = ED_operator_areaactive;
ot->cancel = area_swap_cancel;
-
+
ot->flag = OPTYPE_BLOCKING;
}
@@ -1057,6 +1090,7 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
/* operator callback */
static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ Main *bmain = CTX_data_main(C);
wmWindow *newwin, *win = CTX_wm_window(C);
Scene *scene;
WorkSpace *workspace = WM_window_get_active_workspace(win);
@@ -1065,18 +1099,18 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bScreen *newsc;
ScrArea *sa;
rcti rect;
-
+
win = CTX_wm_window(C);
scene = CTX_data_scene(C);
sa = CTX_wm_area(C);
-
+
/* XXX hrmf! */
if (event->type == EVT_ACTIONZONE_AREA) {
sActionzoneData *sad = event->customdata;
-
+
if (sad == NULL)
return OPERATOR_PASS_THROUGH;
-
+
sa = sad->sa1;
}
@@ -1098,7 +1132,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
WM_window_set_active_workspace(newwin, workspace);
/* allocs new screen and adds to newly created window, using window size */
- layout_new = ED_workspace_layout_add(workspace, newwin, BKE_workspace_layout_name_get(layout_old));
+ layout_new = ED_workspace_layout_add(bmain, workspace, newwin, BKE_workspace_layout_name_get(layout_old));
newsc = BKE_workspace_layout_screen_get(layout_new);
WM_window_set_active_layout(newwin, workspace, layout_new);
ED_screen_global_areas_create(newwin);
@@ -1115,7 +1149,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
finally:
if (event->type == EVT_ACTIONZONE_AREA)
actionzone_exit(op);
-
+
if (newwin) {
return OPERATOR_FINISHED;
}
@@ -1129,7 +1163,7 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot)
ot->name = "Duplicate Area into New Window";
ot->description = "Duplicate selected area into new window";
ot->idname = "SCREEN_OT_area_dupli";
-
+
ot->invoke = area_dupli_invoke;
ot->poll = ED_operator_areaactive;
}
@@ -1140,29 +1174,29 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot)
/** \name Move Area Edge Operator
* \{ */
-/* operator state vars used:
+/* operator state vars used:
* x, y mouse coord near edge
* delta movement of edge
- *
+ *
* functions:
- *
+ *
* init() set default property values, find edge based on mouse coords, test
* if the edge can be moved, select edges, calculate min and max movement
- *
+ *
* apply() apply delta on selection
- *
+ *
* exit() cleanup, send notifier
- *
+ *
* cancel() cancel moving
- *
+ *
* callbacks:
- *
+ *
* exec() execute without any user interaction, based on properties
* call init(), apply(), exit()
- *
+ *
* invoke() gets called on mouse click near edge
* call init(), add handler
- *
+ *
* modal() accept modal events while doing it
* call apply() with delta motion
* call exit() and remove handler
@@ -1174,6 +1208,8 @@ typedef struct sAreaMoveData {
enum AreaMoveSnapType {
/* Snapping disabled */
SNAP_NONE = 0,
+ /* Snap to an invisible grid with a unit defined in AREAGRID */
+ SNAP_AREAGRID,
/* Snap to mid-point and adjacent edges. */
SNAP_MIDPOINT_AND_ADJACENT,
/* Snap to either bigger or smaller, nothing in-between (used for
@@ -1184,13 +1220,13 @@ typedef struct sAreaMoveData {
} sAreaMoveData;
/* helper call to move area-edge, sets limits
- * need window size in order to get correct limits */
+ * need window bounds in order to get correct limits */
static void area_move_set_limits(
wmWindow *win, bScreen *sc, int dir,
- const int winsize_x, const int winsize_y,
int *bigger, int *smaller,
bool *use_bigger_smaller_snap)
{
+ rcti window_rect;
int areaminy = ED_area_headersize();
int areamin;
@@ -1200,8 +1236,11 @@ static void area_move_set_limits(
if (use_bigger_smaller_snap != NULL) {
*use_bigger_smaller_snap = false;
for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) {
- const int size_min = round_fl_to_int(area->global->size_min * UI_DPI_FAC);
- const int size_max = round_fl_to_int(area->global->size_max * UI_DPI_FAC);
+ int size_min = ED_area_global_min_size_y(area) - 1;
+ int size_max = ED_area_global_max_size_y(area) - 1;
+
+ size_min = MAX2(size_min, 0);
+ BLI_assert(size_min < size_max);
/* logic here is only tested for lower edge :) */
/* left edge */
@@ -1235,18 +1274,20 @@ static void area_move_set_limits(
}
}
+ WM_window_rect_calc(win, &window_rect);
+
for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
if (dir == 'h') {
int y1;
areamin = areaminy;
-
- if (sa->v1->vec.y > 0)
+
+ if (sa->v1->vec.y > window_rect.ymin)
areamin += U.pixelsize;
- if (sa->v2->vec.y < winsize_y - 1)
+ if (sa->v2->vec.y < (window_rect.ymax - 1))
areamin += U.pixelsize;
-
- y1 = sa->v2->vec.y - sa->v1->vec.y + 1 - areamin;
-
+
+ y1 = screen_geom_area_height(sa) - areamin;
+
/* if top or down edge selected, test height */
if (sa->v1->editflag && sa->v4->editflag)
*bigger = min_ii(*bigger, y1);
@@ -1256,14 +1297,14 @@ static void area_move_set_limits(
else {
int x1;
areamin = AREAMINX;
-
- if (sa->v1->vec.x > 0)
+
+ if (sa->v1->vec.x > window_rect.xmin)
areamin += U.pixelsize;
- if (sa->v4->vec.x < winsize_x - 1)
+ if (sa->v4->vec.x < (window_rect.xmax - 1))
areamin += U.pixelsize;
-
- x1 = sa->v4->vec.x - sa->v1->vec.x + 1 - areamin;
-
+
+ x1 = screen_geom_area_width(sa) - areamin;
+
/* if left or right edge selected, test width */
if (sa->v1->editflag && sa->v2->editflag)
*bigger = min_ii(*bigger, x1);
@@ -1281,37 +1322,33 @@ static int area_move_init(bContext *C, wmOperator *op)
wmWindow *win = CTX_wm_window(C);
ScrEdge *actedge;
sAreaMoveData *md;
- const int screen_size_x = WM_window_screen_pixels_x(win);
- const int screen_size_y = WM_window_screen_pixels_y(win);
int x, y;
-
+
/* required properties */
x = RNA_int_get(op->ptr, "x");
y = RNA_int_get(op->ptr, "y");
-
+
/* setup */
- actedge = screen_find_active_scredge(win, sc, x, y);
+ actedge = screen_geom_find_active_scredge(win, sc, x, y);
if (actedge == NULL) return 0;
-
+
md = MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData");
op->customdata = md;
-
- md->dir = scredge_is_horizontal(actedge) ? 'h' : 'v';
+
+ md->dir = screen_geom_edge_is_horizontal(actedge) ? 'h' : 'v';
if (md->dir == 'h') md->origval = actedge->v1->vec.y;
else md->origval = actedge->v1->vec.x;
-
- select_connected_scredge(win, actedge);
+
+ screen_geom_select_connected_edge(win, actedge);
/* now all vertices with 'flag == 1' are the ones that can be moved. Move this to editflag */
ED_screen_verts_iter(win, sc, v1) {
v1->editflag = v1->flag;
}
bool use_bigger_smaller_snap = false;
- area_move_set_limits(win, sc, md->dir, screen_size_x, screen_size_y,
- &md->bigger, &md->smaller,
- &use_bigger_smaller_snap);
+ area_move_set_limits(win, sc, md->dir, &md->bigger, &md->smaller, &use_bigger_smaller_snap);
- md->snap_type = use_bigger_smaller_snap ? SNAP_BIGGER_SMALLER_ONLY : SNAP_NONE;
+ md->snap_type = use_bigger_smaller_snap ? SNAP_BIGGER_SMALLER_ONLY : SNAP_AREAGRID;
return 1;
}
@@ -1322,30 +1359,44 @@ static int area_snap_calc_location(
const int bigger, const int smaller)
{
BLI_assert(snap_type != SNAP_NONE);
- if (snap_type == SNAP_BIGGER_SMALLER_ONLY) {
- return ((origval + delta) >= bigger) ? bigger : smaller;
- }
-
int final_loc = -1;
const int m_loc = origval + delta;
- const int axis = (dir == 'v') ? 0 : 1;
- int snap_dist;
- int dist;
- {
- /* Test the snap to middle. */
- int middle = origval + (bigger - smaller) / 2;
- middle -= (middle % AREAGRID);
- snap_dist = abs(m_loc - middle);
- final_loc = middle;
- }
+ switch (snap_type) {
+ case SNAP_AREAGRID:
+ final_loc = m_loc;
+ if (delta != bigger && delta != -smaller) {
+ final_loc -= (m_loc % AREAGRID);
+ CLAMP(final_loc, origval - smaller, origval + bigger);
+ }
+ break;
- for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) {
- if (v1->editflag) {
- const int v_loc = (&v1->vec.x)[!axis];
+ case SNAP_BIGGER_SMALLER_ONLY:
+ final_loc = (m_loc >= bigger) ? bigger : smaller;
+ break;
- for (const ScrVert *v2 = sc->vertbase.first; v2; v2 = v2->next) {
- if (!v2->editflag) {
+ case SNAP_MIDPOINT_AND_ADJACENT:
+ {
+ const int axis = (dir == 'v') ? 0 : 1;
+ int snap_dist;
+ int dist;
+ {
+ /* Test the snap to middle. */
+ int middle = origval + (bigger - smaller) / 2;
+ snap_dist = abs(m_loc - middle);
+ final_loc = middle;
+ }
+
+ for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) {
+ if (!v1->editflag) {
+ continue;
+ }
+ const int v_loc = (&v1->vec.x)[!axis];
+
+ for (const ScrVert *v2 = sc->vertbase.first; v2; v2 = v2->next) {
+ if (v2->editflag) {
+ continue;
+ }
if (v_loc == (&v2->vec.x)[!axis]) {
const int v_loc2 = (&v2->vec.x)[axis];
/* Do not snap to the vertices at the ends. */
@@ -1359,9 +1410,15 @@ static int area_snap_calc_location(
}
}
}
+ break;
}
+ case SNAP_NONE:
+ break;
}
+ BLI_assert(ELEM(snap_type, SNAP_BIGGER_SMALLER_ONLY) ||
+ IN_RANGE_INCL(final_loc, origval - smaller, origval + bigger));
+
return final_loc;
}
@@ -1374,16 +1431,15 @@ static void area_move_apply_do(
{
wmWindow *win = CTX_wm_window(C);
bScreen *sc = CTX_wm_screen(C);
+ short final_loc = -1;
bool doredraw = false;
- CLAMP(delta, -smaller, bigger);
- short final_loc = -1;
+ if (snap_type != SNAP_BIGGER_SMALLER_ONLY) {
+ CLAMP(delta, -smaller, bigger);
+ }
if (snap_type == SNAP_NONE) {
final_loc = origval + delta;
- if (delta != bigger && delta != -smaller) {
- final_loc -= (final_loc % AREAGRID);
- }
}
else {
final_loc = area_snap_calc_location(sc, snap_type, delta, origval, dir, bigger, smaller);
@@ -1411,7 +1467,7 @@ static void area_move_apply_do(
ED_screen_areas_iter(win, sc, sa) {
if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) {
if (ED_area_is_global(sa)) {
- sa->global->cur_fixed_height = round_fl_to_int((sa->v2->vec.y - sa->v1->vec.y) / UI_DPI_FAC);
+ sa->global->cur_fixed_height = round_fl_to_int(screen_geom_area_height(sa) / UI_DPI_FAC);
sc->do_refresh = true;
redraw_all = true;
}
@@ -1443,7 +1499,7 @@ static void area_move_exit(bContext *C, wmOperator *op)
if (op->customdata)
MEM_freeN(op->customdata);
op->customdata = NULL;
-
+
/* this makes sure aligned edges will result in aligned grabbing */
BKE_screen_remove_double_scrverts(CTX_wm_screen(C));
BKE_screen_remove_double_scredges(CTX_wm_screen(C));
@@ -1453,10 +1509,10 @@ static int area_move_exec(bContext *C, wmOperator *op)
{
if (!area_move_init(C, op))
return OPERATOR_CANCELLED;
-
+
area_move_apply(C, op);
area_move_exit(C, op);
-
+
return OPERATOR_FINISHED;
}
@@ -1465,19 +1521,19 @@ static int area_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set(op->ptr, "x", event->x);
RNA_int_set(op->ptr, "y", event->y);
-
- if (!area_move_init(C, op))
+
+ if (!area_move_init(C, op))
return OPERATOR_PASS_THROUGH;
-
+
/* add temp handler */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
static void area_move_cancel(bContext *C, wmOperator *op)
{
-
+
RNA_int_set(op->ptr, "delta", 0);
area_move_apply(C, op);
area_move_exit(C, op);
@@ -1488,17 +1544,17 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sAreaMoveData *md = op->customdata;
int delta, x, y;
-
+
/* execute the events */
switch (event->type) {
case MOUSEMOVE:
{
x = RNA_int_get(op->ptr, "x");
y = RNA_int_get(op->ptr, "y");
-
+
delta = (md->dir == 'v') ? event->x - x : event->y - y;
RNA_int_set(op->ptr, "delta", delta);
-
+
area_move_apply(C, op);
break;
}
@@ -1508,26 +1564,27 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
case KM_MODAL_APPLY:
area_move_exit(C, op);
return OPERATOR_FINISHED;
-
+
case KM_MODAL_CANCEL:
area_move_cancel(C, op);
return OPERATOR_CANCELLED;
case KM_MODAL_SNAP_ON:
- if (md->snap_type == SNAP_NONE) {
+ if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) {
md->snap_type = SNAP_MIDPOINT_AND_ADJACENT;
}
break;
+
case KM_MODAL_SNAP_OFF:
- if (md->snap_type == SNAP_MIDPOINT_AND_ADJACENT) {
- md->snap_type = SNAP_NONE;
+ if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) {
+ md->snap_type = SNAP_AREAGRID;
}
break;
}
break;
}
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -1537,16 +1594,16 @@ static void SCREEN_OT_area_move(wmOperatorType *ot)
ot->name = "Move Area Edges";
ot->description = "Move selected area edges";
ot->idname = "SCREEN_OT_area_move";
-
+
ot->exec = area_move_exec;
ot->invoke = area_move_invoke;
ot->cancel = area_move_cancel;
ot->modal = area_move_modal;
ot->poll = ED_operator_screen_mainwinactive; /* when mouse is over area-edge */
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
+
/* rna */
RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
@@ -1605,7 +1662,7 @@ typedef struct sAreaSplitData {
ScrEdge *nedge; /* new edge */
ScrArea *sarea; /* start area */
ScrArea *narea; /* new area */
-
+
} sAreaSplitData;
static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdata)
@@ -1625,11 +1682,11 @@ static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdat
static int area_split_menu_init(bContext *C, wmOperator *op)
{
sAreaSplitData *sd;
-
+
/* custom data */
sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split");
op->customdata = sd;
-
+
sd->sarea = CTX_wm_area(C);
return 1;
@@ -1640,27 +1697,33 @@ static int area_split_init(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
sAreaSplitData *sd;
- int areaminy = ED_area_headersize() + 1;
+ int areaminy = ED_area_headersize();
int dir;
-
+
/* required context */
if (sa == NULL) return 0;
-
+
/* required properties */
dir = RNA_enum_get(op->ptr, "direction");
-
+
/* minimal size */
if (dir == 'v' && sa->winx < 2 * AREAMINX) return 0;
if (dir == 'h' && sa->winy < 2 * areaminy) return 0;
-
+
/* custom data */
sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split");
op->customdata = sd;
-
+
sd->sarea = sa;
- sd->origsize = dir == 'v' ? sa->winx : sa->winy;
- sd->origmin = dir == 'v' ? sa->totrct.xmin : sa->totrct.ymin;
-
+ if (dir == 'v') {
+ sd->origmin = sa->v1->vec.x;
+ sd->origsize = sa->v4->vec.x - sd->origmin;
+ }
+ else {
+ sd->origmin = sa->v1->vec.y;
+ sd->origsize = sa->v2->vec.y - sd->origmin;
+ }
+
return 1;
}
@@ -1676,7 +1739,7 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb)
ScrVert *sbv2 = sb->v2;
ScrVert *sbv3 = sb->v3;
ScrVert *sbv4 = sb->v4;
-
+
if (sav1 == sbv4 && sav2 == sbv3) { /* sa to right of sb = W */
return BKE_screen_find_edge(screen, sav1, sav2);
}
@@ -1689,7 +1752,7 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb)
else if (sav1 == sbv2 && sav4 == sbv3) { /* sa on top of sb = S*/
return BKE_screen_find_edge(screen, sav1, sav4);
}
-
+
return NULL;
}
@@ -1697,28 +1760,28 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb)
/* do the split, return success */
static int area_split_apply(bContext *C, wmOperator *op)
{
+ const wmWindow *win = CTX_wm_window(C);
bScreen *sc = CTX_wm_screen(C);
sAreaSplitData *sd = (sAreaSplitData *)op->customdata;
float fac;
int dir;
-
+
fac = RNA_float_get(op->ptr, "factor");
dir = RNA_enum_get(op->ptr, "direction");
-
- sd->narea = area_split(sc, sd->sarea, dir, fac, 0); /* 0 = no merge */
-
+
+ sd->narea = area_split(win, sc, sd->sarea, dir, fac, 0); /* 0 = no merge */
+
if (sd->narea) {
- ScrVert *sv;
-
sd->nedge = area_findsharededge(sc, sd->sarea, sd->narea);
-
+
/* select newly created edge, prepare for moving edge */
- for (sv = sc->vertbase.first; sv; sv = sv->next)
+ ED_screen_verts_iter(win, sc, sv) {
sv->editflag = 0;
-
+ }
+
sd->nedge->v1->editflag = 1;
sd->nedge->v2->editflag = 1;
-
+
if (dir == 'h') sd->origval = sd->nedge->v1->vec.y;
else sd->origval = sd->nedge->v1->vec.x;
@@ -1731,7 +1794,7 @@ static int area_split_apply(bContext *C, wmOperator *op)
return 1;
}
-
+
return 0;
}
@@ -1748,10 +1811,10 @@ static void area_split_exit(bContext *C, wmOperator *op)
MEM_freeN(op->customdata);
op->customdata = NULL;
}
-
+
WM_cursor_modal_restore(CTX_wm_window(C));
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
+
/* this makes sure aligned edges will result in aligned grabbing */
BKE_screen_remove_double_scrverts(CTX_wm_screen(C));
BKE_screen_remove_double_scredges(CTX_wm_screen(C));
@@ -1770,29 +1833,27 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmWindow *win = CTX_wm_window(C);
bScreen *sc = CTX_wm_screen(C);
sAreaSplitData *sd;
- const int screen_size_x = WM_window_screen_pixels_x(win);
- const int screen_size_y = WM_window_screen_pixels_y(win);
int dir;
-
+
/* no full window splitting allowed */
if (sc->state != SCREENNORMAL)
return OPERATOR_CANCELLED;
-
+
if (event->type == EVT_ACTIONZONE_AREA) {
sActionzoneData *sad = event->customdata;
-
+
if (sad == NULL || sad->modifier > 0) {
return OPERATOR_PASS_THROUGH;
}
-
+
/* verify *sad itself */
if (sad->sa1 == NULL || sad->az == NULL)
return OPERATOR_PASS_THROUGH;
-
+
/* is this our *sad? if areas not equal it should be passed on */
if (CTX_wm_area(C) != sad->sa1 || sad->sa1 != sad->sa2)
return OPERATOR_PASS_THROUGH;
-
+
/* prepare operator state vars */
if (sad->gesture_dir == 'n' || sad->gesture_dir == 's') {
dir = 'h';
@@ -1803,52 +1864,55 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
RNA_float_set(op->ptr, "factor", ((float)(event->y - sad->sa1->v1->vec.y)) / (float)sad->sa1->winy);
}
RNA_enum_set(op->ptr, "direction", dir);
-
+
/* general init, also non-UI case, adds customdata, sets area and defaults */
if (!area_split_init(C, op))
return OPERATOR_PASS_THROUGH;
-
+
}
else {
ScrEdge *actedge;
+ rcti screen_rect;
int x, y;
-
+
/* retrieve initial mouse coord, so we can find the active edge */
if (RNA_struct_property_is_set(op->ptr, "mouse_x"))
x = RNA_int_get(op->ptr, "mouse_x");
else
x = event->x;
-
+
if (RNA_struct_property_is_set(op->ptr, "mouse_y"))
y = RNA_int_get(op->ptr, "mouse_y");
else
y = event->x;
-
- actedge = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), screen_size_x, screen_size_y, x, y);
+
+ WM_window_screen_rect_calc(win, &screen_rect);
+
+ actedge = screen_geom_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), &screen_rect, x, y);
if (actedge == NULL)
return OPERATOR_CANCELLED;
-
- dir = scredge_is_horizontal(actedge) ? 'v' : 'h';
-
+
+ dir = screen_geom_edge_is_horizontal(actedge) ? 'v' : 'h';
+
RNA_enum_set(op->ptr, "direction", dir);
-
+
/* special case, adds customdata, sets defaults */
if (!area_split_menu_init(C, op))
return OPERATOR_CANCELLED;
-
+
}
-
+
sd = (sAreaSplitData *)op->customdata;
-
+
if (event->type == EVT_ACTIONZONE_AREA) {
-
+
/* do the split */
if (area_split_apply(C, op)) {
- area_move_set_limits(win, sc, dir, screen_size_x, screen_size_y, &sd->bigger, &sd->smaller, NULL);
-
+ area_move_set_limits(win, sc, dir, &sd->bigger, &sd->smaller, NULL);
+
/* add temp handler for edge move or cancel */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
}
@@ -1860,22 +1924,22 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
area_split_preview_update_cursor(C, op);
return OPERATOR_RUNNING_MODAL;
-
+
}
-
+
return OPERATOR_PASS_THROUGH;
}
/* function to be called outside UI context, or for redo */
static int area_split_exec(bContext *C, wmOperator *op)
{
-
+
if (!area_split_init(C, op))
return OPERATOR_CANCELLED;
-
+
area_split_apply(C, op);
area_split_exit(C, op);
-
+
return OPERATOR_FINISHED;
}
@@ -1883,7 +1947,7 @@ static int area_split_exec(bContext *C, wmOperator *op)
static void area_split_cancel(bContext *C, wmOperator *op)
{
sAreaSplitData *sd = (sAreaSplitData *)op->customdata;
-
+
if (sd->previewmode) {
/* pass */
}
@@ -1924,7 +1988,7 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
break;
-
+
case MIDDLEMOUSE:
case TABKEY:
if (sd->previewmode == 0) {
@@ -1940,9 +2004,9 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
}
-
+
break;
-
+
case RIGHTMOUSE: /* cancel operation */
case ESCKEY:
area_split_cancel(C, op);
@@ -1978,12 +2042,12 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (sd->sarea) {
ScrArea *sa = sd->sarea;
if (dir == 'v') {
- sd->origsize = sa->winx;
- sd->origmin = sa->totrct.xmin;
+ sd->origmin = sa->v1->vec.x;
+ sd->origsize = sa->v4->vec.x - sd->origmin;
}
else {
- sd->origsize = sa->winy;
- sd->origmin = sa->totrct.ymin;
+ sd->origmin = sa->v1->vec.y;
+ sd->origsize = sa->v2->vec.y - sd->origmin;
}
if (sd->do_snap) {
@@ -2021,17 +2085,17 @@ static void SCREEN_OT_area_split(wmOperatorType *ot)
ot->name = "Split Area";
ot->description = "Split selected area into new windows";
ot->idname = "SCREEN_OT_area_split";
-
+
ot->exec = area_split_exec;
ot->invoke = area_split_invoke;
ot->modal = area_split_modal;
ot->cancel = area_split_cancel;
-
+
ot->poll = screen_active_editable;
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
+
/* rna */
RNA_def_enum(ot->srna, "direction", prop_direction_items, 'h', "Direction", "");
RNA_def_float(ot->srna, "factor", 0.5f, 0.0, 1.0, "Factor", "", 0.0, 1.0);
@@ -2053,7 +2117,7 @@ typedef struct RegionMoveData {
int origx, origy;
int maxsize;
AZEdge edge;
-
+
} RegionMoveData;
@@ -2061,20 +2125,20 @@ static int area_max_regionsize(ScrArea *sa, ARegion *scalear, AZEdge edge)
{
ARegion *ar;
int dist;
-
+
if (edge == AE_RIGHT_TO_TOPLEFT || edge == AE_LEFT_TO_TOPRIGHT) {
dist = BLI_rcti_size_x(&sa->totrct);
}
else { /* AE_BOTTOM_TO_TOPLEFT, AE_TOP_TO_BOTTOMRIGHT */
dist = BLI_rcti_size_y(&sa->totrct);
}
-
- /* subtractwidth of regions on opposite side
+
+ /* subtractwidth of regions on opposite side
* prevents dragging regions into other opposite regions */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar == scalear)
continue;
-
+
if (scalear->alignment == RGN_ALIGN_TOP && ar->alignment == RGN_ALIGN_BOTTOM)
dist -= ar->winy;
else if (scalear->alignment == RGN_ALIGN_BOTTOM && ar->alignment == RGN_ALIGN_TOP)
@@ -2083,7 +2147,7 @@ static int area_max_regionsize(ScrArea *sa, ARegion *scalear, AZEdge edge)
dist -= ar->winx;
else if (scalear->alignment == RGN_ALIGN_RIGHT && ar->alignment == RGN_ALIGN_LEFT)
dist -= ar->winx;
-
+
/* case of regions in regions, like operator properties panel */
/* these can sit on top of other regions such as headers, so account for this */
else if (edge == AE_BOTTOM_TO_TOPLEFT && scalear->alignment & RGN_ALIGN_TOP &&
@@ -2105,20 +2169,20 @@ static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event
{
sActionzoneData *sad = event->customdata;
AZone *az;
-
+
if (event->type != EVT_ACTIONZONE_REGION) {
BKE_report(op->reports, RPT_ERROR, "Can only scale region size from an action zone");
return OPERATOR_CANCELLED;
}
-
+
az = sad->az;
-
+
if (az->ar) {
RegionMoveData *rmd = MEM_callocN(sizeof(RegionMoveData), "RegionMoveData");
int maxsize;
-
+
op->customdata = rmd;
-
+
rmd->az = az;
rmd->ar = az->ar;
rmd->sa = sad->sa1;
@@ -2126,13 +2190,13 @@ static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event
rmd->origx = event->x;
rmd->origy = event->y;
rmd->maxsize = area_max_regionsize(rmd->sa, rmd->ar, rmd->edge);
-
+
/* if not set we do now, otherwise it uses type */
if (rmd->ar->sizex == 0)
rmd->ar->sizex = rmd->ar->winx;
if (rmd->ar->sizey == 0)
rmd->ar->sizey = rmd->ar->winy;
-
+
/* now copy to regionmovedata */
if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) {
rmd->origval = rmd->ar->sizex;
@@ -2140,21 +2204,21 @@ static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event
else {
rmd->origval = rmd->ar->sizey;
}
-
+
/* limit headers to standard height for now */
if (rmd->ar->regiontype == RGN_TYPE_HEADER)
maxsize = ED_area_headersize();
else
maxsize = 1000;
-
+
CLAMP(rmd->maxsize, 0, maxsize);
-
+
/* add temp handler */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
-
+
return OPERATOR_FINISHED;
}
@@ -2210,20 +2274,20 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionMoveData *rmd = op->customdata;
int delta;
-
+
/* execute the events */
switch (event->type) {
case MOUSEMOVE:
{
const float aspect = BLI_rctf_size_x(&rmd->ar->v2d.cur) / (BLI_rcti_size_x(&rmd->ar->v2d.mask) + 1);
- const int snap_size_threshold = (U.widget_unit * 3) / aspect;
+ const int snap_size_threshold = (U.widget_unit * 2) / aspect;
if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) {
delta = event->x - rmd->origx;
if (rmd->edge == AE_LEFT_TO_TOPRIGHT) delta = -delta;
-
+
/* region sizes now get multiplied */
delta /= UI_DPI_FAC;
-
+
rmd->ar->sizex = rmd->origval + delta;
if (rmd->ar->type->snap_size) {
@@ -2246,7 +2310,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
int maxsize = region_scale_get_maxsize(rmd);
delta = event->y - rmd->origy;
if (rmd->edge == AE_BOTTOM_TO_TOPLEFT) delta = -delta;
-
+
/* region sizes now get multiplied */
delta /= UI_DPI_FAC;
@@ -2268,19 +2332,19 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (!(rmd->ar->flag & RGN_FLAG_HIDDEN))
region_scale_toggle_hidden(C, rmd);
}
- else if (maxsize > 0 && (rmd->ar->sizey > maxsize))
+ else if (maxsize > 0 && (rmd->ar->sizey > maxsize))
rmd->ar->sizey = maxsize;
else if (rmd->ar->flag & RGN_FLAG_HIDDEN)
region_scale_toggle_hidden(C, rmd);
}
ED_area_tag_redraw(rmd->sa);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
+
break;
}
case LEFTMOUSE:
if (event->val == KM_RELEASE) {
-
+
if (ABS(event->x - rmd->origx) < 2 && ABS(event->y - rmd->origy) < 2) {
if (rmd->ar->flag & RGN_FLAG_HIDDEN) {
region_scale_toggle_hidden(C, rmd);
@@ -2294,15 +2358,15 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
MEM_freeN(op->customdata);
op->customdata = NULL;
-
+
return OPERATOR_FINISHED;
}
break;
-
+
case ESCKEY:
break;
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -2318,13 +2382,13 @@ static void SCREEN_OT_region_scale(wmOperatorType *ot)
ot->name = "Scale Region Size";
ot->description = "Scale selected area";
ot->idname = "SCREEN_OT_region_scale";
-
+
ot->invoke = region_scale_invoke;
ot->modal = region_scale_modal;
ot->cancel = region_scale_cancel;
-
+
ot->poll = ED_operator_areaactive;
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
}
@@ -2382,19 +2446,19 @@ static int frame_offset_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
int delta;
-
+
delta = RNA_int_get(op->ptr, "delta");
CFRA += delta;
FRAMENUMBER_MIN_CLAMP(CFRA);
SUBFRA = 0.f;
-
+
areas_do_frame_follow(C, false);
BKE_sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -2403,13 +2467,13 @@ static void SCREEN_OT_frame_offset(wmOperatorType *ot)
ot->name = "Frame Offset";
ot->idname = "SCREEN_OT_frame_offset";
ot->description = "Move current frame forward/backward by a given number";
-
+
ot->exec = frame_offset_exec;
-
+
ot->poll = ED_operator_screenactive_norender;
ot->flag = OPTYPE_UNDO_GROUPED;
- ot->undo_group = "FRAME_CHANGE";
-
+ ot->undo_group = "Frame Change";
+
/* rna */
RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
}
@@ -2433,9 +2497,9 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
*/
if (animtimer) {
ScreenAnimData *sad = animtimer->customdata;
-
+
sad->flag |= ANIMPLAY_FLAG_USE_NEXT_FRAME;
-
+
if (RNA_boolean_get(op->ptr, "end"))
sad->nextfra = PEFRA;
else
@@ -2446,14 +2510,14 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
CFRA = PEFRA;
else
CFRA = PSFRA;
-
+
areas_do_frame_follow(C, true);
BKE_sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
-
+
return OPERATOR_FINISHED;
}
@@ -2462,13 +2526,13 @@ static void SCREEN_OT_frame_jump(wmOperatorType *ot)
ot->name = "Jump to Endpoint";
ot->description = "Jump to first/last frame in frame range";
ot->idname = "SCREEN_OT_frame_jump";
-
+
ot->exec = frame_jump_exec;
-
+
ot->poll = ED_operator_screenactive_norender;
ot->flag = OPTYPE_UNDO_GROUPED;
- ot->undo_group = "FRAME_CHANGE";
-
+ ot->undo_group = "Frame Change";
+
/* rna */
RNA_def_boolean(ot->srna, "end", 0, "Last Frame", "Jump to the last frame of the frame range");
}
@@ -2491,7 +2555,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
float cfra;
const bool next = RNA_boolean_get(op->ptr, "next");
bool done = false;
-
+
/* sanity checks */
if (scene == NULL)
return OPERATOR_CANCELLED;
@@ -2500,13 +2564,13 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
/* init binarytree-list for getting keyframes */
BLI_dlrbTree_init(&keys);
-
+
/* seed up dummy dopesheet context with flags to perform necessary filtering */
if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) {
/* only selected channels are included */
ads.filterflag |= ADS_FILTER_ONLYSEL;
}
-
+
/* populate tree with keyframe nodes */
scene_to_keylist(&ads, scene, &keys, NULL);
gpencil_to_keylist(&ads, scene->gpd, &keys);
@@ -2515,7 +2579,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
ob_to_keylist(&ads, ob, &keys, NULL);
gpencil_to_keylist(&ads, ob->gpd, &keys);
}
-
+
{
Mask *mask = CTX_data_edit_mask(C);
if (mask) {
@@ -2526,13 +2590,13 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
/* build linked-list for searching */
BLI_dlrbTree_linkedlist_sync(&keys);
-
+
/* find matching keyframe in the right direction */
if (next)
ak = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfra);
else
ak = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfra);
-
+
while ((ak != NULL) && (done == false)) {
if (CFRA != (int)ak->cfra) {
/* this changes the frame, so set the frame and we're done */
@@ -2549,7 +2613,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* free temp stuff */
BLI_dlrbTree_free(&keys);
@@ -2575,13 +2639,13 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
ot->name = "Jump to Keyframe";
ot->description = "Jump to previous/next keyframe";
ot->idname = "SCREEN_OT_keyframe_jump";
-
+
ot->exec = keyframe_jump_exec;
-
+
ot->poll = ED_operator_screenactive_norender;
ot->flag = OPTYPE_UNDO_GROUPED;
- ot->undo_group = "FRAME_CHANGE";
-
+ ot->undo_group = "Frame Change";
+
/* properties */
RNA_def_boolean(ot->srna, "next", true, "Next Keyframe", "");
}
@@ -2647,7 +2711,7 @@ static void SCREEN_OT_marker_jump(wmOperatorType *ot)
ot->poll = ED_operator_screenactive_norender;
ot->flag = OPTYPE_UNDO_GROUPED;
- ot->undo_group = "FRAME_CHANGE";
+ ot->undo_group = "Frame Change";
/* properties */
RNA_def_boolean(ot->srna, "next", true, "Next Marker", "");
@@ -2677,7 +2741,7 @@ static void SCREEN_OT_screen_set(wmOperatorType *ot)
ot->name = "Set Screen";
ot->description = "Cycle through available screens";
ot->idname = "SCREEN_OT_screen_set";
-
+
ot->exec = screen_set_exec;
ot->poll = ED_operator_screenactive;
@@ -2697,17 +2761,17 @@ static int screen_maximize_area_exec(bContext *C, wmOperator *op)
bScreen *screen = CTX_wm_screen(C);
ScrArea *sa = NULL;
const bool hide_panels = RNA_boolean_get(op->ptr, "use_hide_panels");
-
+
/* search current screen for 'fullscreen' areas */
/* prevents restoring info header, when mouse is over it */
for (sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->full) break;
}
-
+
if (sa == NULL) {
sa = CTX_wm_area(C);
}
-
+
if (hide_panels) {
if (!ELEM(screen->state, SCREENNORMAL, SCREENFULL)) {
return OPERATOR_CANCELLED;
@@ -2729,7 +2793,8 @@ static int screen_maximize_area_poll(bContext *C)
const bScreen *screen = CTX_wm_screen(C);
const ScrArea *area = CTX_wm_area(C);
return ED_operator_areaactive(C) &&
- ((screen->state != SCREENNORMAL) || (area->spacetype != SPACE_TOPBAR));
+ /* Don't allow maximizing global areas but allow minimizing from them. */
+ ((screen->state != SCREENNORMAL) || !ED_area_is_global(area));
}
static void SCREEN_OT_screen_full_area(wmOperatorType *ot)
@@ -2739,7 +2804,7 @@ static void SCREEN_OT_screen_full_area(wmOperatorType *ot)
ot->name = "Toggle Maximize Area";
ot->description = "Toggle display selected area as fullscreen/maximized";
ot->idname = "SCREEN_OT_screen_full_area";
-
+
ot->exec = screen_maximize_area_exec;
ot->poll = screen_maximize_area_poll;
ot->flag = 0;
@@ -2754,28 +2819,28 @@ static void SCREEN_OT_screen_full_area(wmOperatorType *ot)
/** \name Screen Join-Area Operator
* \{ */
-/* operator state vars used:
+/* operator state vars used:
* x1, y1 mouse coord in first area, which will disappear
* x2, y2 mouse coord in 2nd area, which will become joined
- *
+ *
* functions:
- *
- * init() find edge based on state vars
- * test if the edge divides two areas,
+ *
+ * init() find edge based on state vars
+ * test if the edge divides two areas,
* store active and nonactive area,
- *
+ *
* apply() do the actual join
- *
+ *
* exit() cleanup, send notifier
- *
+ *
* callbacks:
- *
- * exec() calls init, apply, exit
- *
+ *
+ * exec() calls init, apply, exit
+ *
* invoke() sets mouse coords in x,y
* call init()
* add modal handler
- *
+ *
* modal() accept modal events while doing it
* call apply() with active window and nonactive window
* call exit() and remove handler when LMB confirm
@@ -2809,18 +2874,18 @@ static int area_join_init(bContext *C, wmOperator *op)
int x1, y1;
int x2, y2;
int shared = 0;
-
+
/* required properties, make negative to get return 0 if not set by caller */
x1 = RNA_int_get(op->ptr, "min_x");
y1 = RNA_int_get(op->ptr, "min_y");
x2 = RNA_int_get(op->ptr, "max_x");
y2 = RNA_int_get(op->ptr, "max_y");
-
+
sa1 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, x1, y1);
sa2 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, x2, y2);
if (sa1 == NULL || sa2 == NULL || sa1 == sa2)
return 0;
-
+
/* do areas share an edge? */
if (sa1->v1 == sa2->v1 || sa1->v1 == sa2->v2 || sa1->v1 == sa2->v3 || sa1->v1 == sa2->v4) shared++;
if (sa1->v2 == sa2->v1 || sa1->v2 == sa2->v2 || sa1->v2 == sa2->v3 || sa1->v2 == sa2->v4) shared++;
@@ -2830,7 +2895,7 @@ static int area_join_init(bContext *C, wmOperator *op)
printf("areas don't share edge\n");
return 0;
}
-
+
jd = (sAreaJoinData *)MEM_callocN(sizeof(sAreaJoinData), "op_area_join");
jd->sa1 = sa1;
@@ -2848,7 +2913,7 @@ static int area_join_apply(bContext *C, wmOperator *op)
{
sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
if (!jd) return 0;
-
+
if (!screen_area_join(C, CTX_wm_screen(C), jd->sa1, jd->sa2)) {
return 0;
}
@@ -2856,7 +2921,7 @@ static int area_join_apply(bContext *C, wmOperator *op)
CTX_wm_area_set(C, NULL);
CTX_wm_region_set(C, NULL);
}
-
+
return 1;
}
@@ -2872,7 +2937,7 @@ static void area_join_exit(bContext *C, wmOperator *op)
MEM_freeN(jd);
op->customdata = NULL;
}
-
+
/* this makes sure aligned edges will result in aligned grabbing */
BKE_screen_remove_double_scredges(CTX_wm_screen(C));
BKE_screen_remove_unused_scredges(CTX_wm_screen(C));
@@ -2881,55 +2946,55 @@ static void area_join_exit(bContext *C, wmOperator *op)
static int area_join_exec(bContext *C, wmOperator *op)
{
- if (!area_join_init(C, op))
+ if (!area_join_init(C, op))
return OPERATOR_CANCELLED;
-
+
area_join_apply(C, op);
area_join_exit(C, op);
-
+
return OPERATOR_FINISHED;
}
/* interaction callback */
static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
-
+
if (event->type == EVT_ACTIONZONE_AREA) {
sActionzoneData *sad = event->customdata;
-
+
if (sad == NULL || sad->modifier > 0) {
return OPERATOR_PASS_THROUGH;
}
-
+
/* verify *sad itself */
if (sad->sa1 == NULL || sad->sa2 == NULL)
return OPERATOR_PASS_THROUGH;
-
+
/* is this our *sad? if areas equal it should be passed on */
if (sad->sa1 == sad->sa2)
return OPERATOR_PASS_THROUGH;
-
+
/* prepare operator state vars */
RNA_int_set(op->ptr, "min_x", sad->x);
RNA_int_set(op->ptr, "min_y", sad->y);
RNA_int_set(op->ptr, "max_x", event->x);
RNA_int_set(op->ptr, "max_y", event->y);
}
-
-
- if (!area_join_init(C, op))
+
+
+ if (!area_join_init(C, op))
return OPERATOR_PASS_THROUGH;
-
+
/* add temp handler */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
static void area_join_cancel(bContext *C, wmOperator *op)
{
WM_event_add_notifier(C, NC_WINDOW, NULL);
-
+
area_join_exit(C, op);
}
@@ -2938,15 +3003,15 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
bScreen *sc = CTX_wm_screen(C);
sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
-
+
/* execute the events */
switch (event->type) {
-
- case MOUSEMOVE:
+
+ case MOUSEMOVE:
{
ScrArea *sa = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y);
int dir;
-
+
if (sa) {
if (jd->sa1 != sa) {
dir = area_getorientation(jd->sa1, sa);
@@ -2954,7 +3019,7 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
jd->sa2 = sa;
}
else {
- /* we are not bordering on the previously selected area
+ /* we are not bordering on the previously selected area
* we check if area has common border with the one marked for removal
* in this case we can swap areas.
*/
@@ -2970,7 +3035,7 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
WM_event_add_notifier(C, NC_WINDOW, NULL);
}
else {
- /* we are back in the area previously selected for keeping
+ /* we are back in the area previously selected for keeping
* we swap the areas if possible to allow user to choose */
if (jd->sa2 != NULL) {
jd->sa1 = jd->sa2;
@@ -3002,13 +3067,13 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
break;
-
+
case RIGHTMOUSE:
case ESCKEY:
area_join_cancel(C, op);
return OPERATOR_CANCELLED;
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -3019,17 +3084,17 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
ot->name = "Join Area";
ot->description = "Join selected areas into new window";
ot->idname = "SCREEN_OT_area_join";
-
+
/* api callbacks */
ot->exec = area_join_exec;
ot->invoke = area_join_invoke;
ot->modal = area_join_modal;
ot->poll = screen_active_editable;
ot->cancel = area_join_cancel;
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
+
/* rna */
RNA_def_int(ot->srna, "min_x", -100, INT_MIN, INT_MAX, "X 1", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "min_y", -100, INT_MIN, INT_MAX, "Y 1", "", INT_MIN, INT_MAX);
@@ -3045,23 +3110,22 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- wmWindow *win = CTX_wm_window(C);
- bScreen *sc = CTX_wm_screen(C);
+ const wmWindow *win = CTX_wm_window(C);
+ const bScreen *sc = CTX_wm_screen(C);
uiPopupMenu *pup;
uiLayout *layout;
PointerRNA ptr;
ScrEdge *actedge;
- const int screen_size_x = WM_window_screen_pixels_x(win);
- const int screen_size_y = WM_window_screen_pixels_y(win);
+ rcti screen_rect;
+
+ WM_window_screen_rect_calc(win, &screen_rect);
+ actedge = screen_geom_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y);
- actedge = screen_area_map_find_active_scredge(
- AREAMAP_FROM_SCREEN(sc), screen_size_x, screen_size_y, event->x, event->y);
-
if (actedge == NULL) return OPERATOR_CANCELLED;
-
+
pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
layout = UI_popup_menu_layout(pup);
-
+
uiItemFullO(layout, "SCREEN_OT_area_split", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr);
/* store initial mouse cursor position */
RNA_int_set(&ptr, "mouse_x", event->x);
@@ -3073,9 +3137,9 @@ static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent
RNA_int_set(&ptr, "min_y", event->y + 4);
RNA_int_set(&ptr, "max_x", event->x - 4);
RNA_int_set(&ptr, "max_y", event->y - 4);
-
+
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -3085,10 +3149,10 @@ static void SCREEN_OT_area_options(wmOperatorType *ot)
ot->name = "Area Options";
ot->description = "Operations for splitting and merging";
ot->idname = "SCREEN_OT_area_options";
-
+
/* api callbacks */
ot->invoke = screen_area_options_invoke;
-
+
ot->poll = ED_operator_screen_mainwinactive;
/* flags */
@@ -3107,7 +3171,7 @@ static int spacedata_cleanup_exec(bContext *C, wmOperator *op)
bScreen *screen;
ScrArea *sa;
int tot = 0;
-
+
for (screen = bmain->screen.first; screen; screen = screen->id.next) {
for (sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->spacedata.first != sa->spacedata.last) {
@@ -3121,7 +3185,7 @@ static int spacedata_cleanup_exec(bContext *C, wmOperator *op)
}
}
BKE_reportf(op->reports, RPT_INFO, "Removed amount of editors: %d", tot);
-
+
return OPERATOR_FINISHED;
}
@@ -3131,11 +3195,11 @@ static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot)
ot->name = "Clean-up Space-data";
ot->description = "Remove unused settings for invisible editors";
ot->idname = "SCREEN_OT_spacedata_cleanup";
-
+
/* api callbacks */
ot->exec = spacedata_cleanup_exec;
ot->poll = WM_operator_winactive;
-
+
}
/** \} */
@@ -3163,7 +3227,7 @@ static int repeat_last_exec(bContext *C, wmOperator *UNUSED(op))
WM_operator_free_all_after(wm, lastop);
WM_operator_repeat(C, lastop);
}
-
+
return OPERATOR_CANCELLED;
}
@@ -3173,12 +3237,12 @@ static void SCREEN_OT_repeat_last(wmOperatorType *ot)
ot->name = "Repeat Last";
ot->description = "Repeat last action";
ot->idname = "SCREEN_OT_repeat_last";
-
+
/* api callbacks */
ot->exec = repeat_last_exec;
-
+
ot->poll = ED_operator_screenactive;
-
+
}
/** \} */
@@ -3194,37 +3258,37 @@ static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNU
uiPopupMenu *pup;
uiLayout *layout;
int items, i;
-
+
items = BLI_listbase_count(&wm->operators);
if (items == 0)
return OPERATOR_CANCELLED;
-
+
pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
layout = UI_popup_menu_layout(pup);
-
+
for (i = items - 1, lastop = wm->operators.last; lastop; lastop = lastop->prev, i--)
if ((lastop->type->flag & OPTYPE_REGISTER) && WM_operator_repeat_check(C, lastop)) {
uiItemIntO(layout, RNA_struct_ui_name(lastop->type->srna), ICON_NONE, op->type->idname, "index", i);
}
-
+
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
static int repeat_history_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
-
+
op = BLI_findlink(&wm->operators, RNA_int_get(op->ptr, "index"));
if (op) {
/* let's put it as last operator in list */
BLI_remlink(&wm->operators, op);
BLI_addtail(&wm->operators, op);
-
+
WM_operator_repeat(C, op);
}
-
+
return OPERATOR_FINISHED;
}
@@ -3234,13 +3298,13 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot)
ot->name = "Repeat History";
ot->description = "Display menu for previous actions performed";
ot->idname = "SCREEN_OT_repeat_history";
-
+
/* api callbacks */
ot->invoke = repeat_history_invoke;
ot->exec = repeat_history_exec;
-
+
ot->poll = ED_operator_screenactive;
-
+
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000);
}
@@ -3253,10 +3317,10 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot)
static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
wmOperator *lastop = WM_operator_last_redo(C);
-
+
if (lastop)
WM_operator_redo_popup(C, lastop);
-
+
return OPERATOR_CANCELLED;
}
@@ -3266,10 +3330,10 @@ static void SCREEN_OT_redo_last(wmOperatorType *ot)
ot->name = "Redo Last";
ot->description = "Display menu for last action performed";
ot->idname = "SCREEN_OT_redo_last";
-
+
/* api callbacks */
ot->invoke = redo_last_invoke;
-
+
ot->poll = ED_operator_screenactive;
}
@@ -3312,7 +3376,7 @@ static void region_quadview_init_rv3d(ScrArea *sa, ARegion *ar,
static int region_quadview_exec(bContext *C, wmOperator *op)
{
ARegion *ar = CTX_wm_region(C);
-
+
/* some rules... */
if (ar->regiontype != RGN_TYPE_WINDOW) {
BKE_report(op->reports, RPT_ERROR, "Only window region can be 4-splitted");
@@ -3321,10 +3385,10 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
/* Exit quad-view */
ScrArea *sa = CTX_wm_area(C);
ARegion *arn;
-
+
/* keep current region */
ar->alignment = 0;
-
+
if (sa->spacetype == SPACE_VIEW3D) {
ARegion *ar_iter;
RegionView3D *rv3d = ar->regiondata;
@@ -3354,7 +3418,7 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
}
}
}
-
+
for (ar = sa->regionbase.first; ar; ar = arn) {
arn = ar->next;
if (ar->alignment == RGN_ALIGN_QSPLIT) {
@@ -3375,14 +3439,14 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
ScrArea *sa = CTX_wm_area(C);
ARegion *newar;
int count;
-
+
ar->alignment = RGN_ALIGN_QSPLIT;
-
+
for (count = 0; count < 3; count++) {
newar = BKE_area_region_copy(sa->type, ar);
BLI_addtail(&sa->regionbase, newar);
}
-
+
/* lock views and set them */
if (sa->spacetype == SPACE_VIEW3D) {
View3D *v3d = sa->spacedata.first;
@@ -3412,8 +3476,8 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
ED_area_tag_redraw(sa);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
}
-
-
+
+
return OPERATOR_FINISHED;
}
@@ -3423,7 +3487,7 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot)
ot->name = "Toggle Quad View";
ot->description = "Split selected area into camera, front, right & top views";
ot->idname = "SCREEN_OT_region_quadview";
-
+
/* api callbacks */
ot->exec = region_quadview_exec;
ot->poll = ED_operator_region_view3d_active;
@@ -3440,10 +3504,10 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot)
static int region_flip_exec(bContext *C, wmOperator *UNUSED(op))
{
ARegion *ar = CTX_wm_region(C);
-
+
if (!ar)
return OPERATOR_CANCELLED;
-
+
if (ar->alignment == RGN_ALIGN_TOP)
ar->alignment = RGN_ALIGN_BOTTOM;
else if (ar->alignment == RGN_ALIGN_BOTTOM)
@@ -3455,7 +3519,7 @@ static int region_flip_exec(bContext *C, wmOperator *UNUSED(op))
ED_area_tag_redraw(CTX_wm_area(C));
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -3478,7 +3542,7 @@ static void SCREEN_OT_region_flip(wmOperatorType *ot)
ot->name = "Flip Region";
ot->idname = "SCREEN_OT_region_flip";
ot->description = "Toggle the region's alignment (left/right or top/bottom)";
-
+
/* api callbacks */
ot->exec = region_flip_exec;
ot->poll = region_flip_poll;
@@ -3545,7 +3609,7 @@ static void SCREEN_OT_header_toggle_menus(wmOperatorType *ot)
ot->name = "Expand/Collapse Header Menus";
ot->idname = "SCREEN_OT_header_toggle_menus";
ot->description = "Expand or collapse the header pulldown menus";
-
+
/* api callbacks */
ot->exec = header_toggle_menus_exec;
ot->poll = ED_operator_areaactive;
@@ -3564,6 +3628,8 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN
ARegion *ar = CTX_wm_region(C);
const char *but_flip_str = (ar->alignment == RGN_ALIGN_TOP) ? IFACE_("Flip to Bottom") : IFACE_("Flip to Top");
+ uiItemO(layout, IFACE_("Toggle Header"), ICON_NONE, "SCREEN_OT_header");
+
/* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
@@ -3582,7 +3648,7 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN
}
}
-static int header_toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
+static int header_context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -3597,15 +3663,15 @@ static int header_toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
return OPERATOR_INTERFACE;
}
-static void SCREEN_OT_header_toolbox(wmOperatorType *ot)
+static void SCREEN_OT_header_context_menu(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Header Toolbox";
- ot->description = "Display header region toolbox";
- ot->idname = "SCREEN_OT_header_toolbox";
-
+ ot->name = "Header Context Menu";
+ ot->description = "Display header region context menu";
+ ot->idname = "SCREEN_OT_header_context_menu";
+
/* api callbacks */
- ot->invoke = header_toolbox_invoke;
+ ot->invoke = header_context_menu_invoke;
}
/** \} */
@@ -3624,14 +3690,14 @@ static int match_area_with_refresh(int spacetype, int refresh)
return 1;
break;
}
-
+
return 0;
}
static int match_region_with_redraws(int spacetype, int regiontype, int redraws, bool from_anim_edit)
{
if (regiontype == RGN_TYPE_WINDOW) {
-
+
switch (spacetype) {
case SPACE_VIEW3D:
if ((redraws & TIME_ALL_3D_WIN) || from_anim_edit)
@@ -3669,7 +3735,7 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws,
if ((redraws & TIME_CLIPS) || from_anim_edit)
return 1;
break;
-
+
}
}
else if (regiontype == RGN_TYPE_CHANNELS) {
@@ -3734,12 +3800,12 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
ScrArea *sa;
int sync;
float time;
-
+
/* sync, don't sync, or follow scene setting */
if (sad->flag & ANIMPLAY_FLAG_SYNC) sync = 1;
else if (sad->flag & ANIMPLAY_FLAG_NO_SYNC) sync = 0;
else sync = (scene->flag & SCE_FRAME_DROP);
-
+
if ((scene->audio.flag & AUDIO_SYNC) &&
(sad->flag & ANIMPLAY_FLAG_REVERSE) == false &&
isfinite(time = BKE_sound_sync_scene(scene)))
@@ -3785,12 +3851,12 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
scene->r.cfra++;
}
}
-
+
sad->last_duration = wt->duration;
/* reset 'jumped' flag before checking if we need to jump... */
sad->flag &= ~ANIMPLAY_FLAG_JUMPED;
-
+
if (sad->flag & ANIMPLAY_FLAG_REVERSE) {
/* jump back to end? */
if (PRVRANGEON) {
@@ -3828,14 +3894,14 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
sad->flag &= ~ANIMPLAY_FLAG_USE_NEXT_FRAME;
sad->flag |= ANIMPLAY_FLAG_JUMPED;
}
-
+
if (sad->flag & ANIMPLAY_FLAG_JUMPED) {
BKE_sound_seek_scene(bmain, scene);
#ifdef PROFILE_AUDIO_SYNCH
old_frame = CFRA;
#endif
}
-
+
/* since we follow drawflags, we can't send notifier but tag regions ourselves */
ED_update_for_newframe(bmain, depsgraph);
@@ -3874,24 +3940,24 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
}
}
}
-
+
if (match_area_with_refresh(sa->spacetype, sad->refresh))
ED_area_tag_refresh(sa);
}
}
-
- /* update frame rate info too
- * NOTE: this may not be accurate enough, since we might need this after modifiers/etc.
+
+ /* update frame rate info too
+ * NOTE: this may not be accurate enough, since we might need this after modifiers/etc.
* have been calculated instead of just before updates have been done?
*/
ED_refresh_viewport_fps(C);
-
+
/* recalculate the timestep for the timer now that we've finished calculating this,
* since the frames-per-second value may have been changed
*/
/* TODO: this may make evaluation a bit slower if the value doesn't change... any way to avoid this? */
wt->timestep = (1.0 / FPS);
-
+
return OPERATOR_FINISHED;
}
return OPERATOR_PASS_THROUGH;
@@ -3903,12 +3969,12 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot)
ot->name = "Animation Step";
ot->description = "Step through animation by position";
ot->idname = "SCREEN_OT_animation_step";
-
+
/* api callbacks */
ot->invoke = screen_animation_step;
-
+
ot->poll = ED_operator_screenactive_norender;
-
+
}
/** \} */
@@ -3962,16 +4028,16 @@ int ED_screen_animation_play(bContext *C, int sync, int mode)
}
else {
int refresh = SPACE_ACTION; /* these settings are currently only available from a menu in the TimeLine */
-
+
if (mode == 1) /* XXX only play audio forwards!? */
BKE_sound_play_scene(scene);
-
+
ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode);
-
+
if (screen->animtimer) {
wmTimer *wt = screen->animtimer;
ScreenAnimData *sad = wt->customdata;
-
+
sad->ar = CTX_wm_region(C);
}
}
@@ -3983,10 +4049,10 @@ static int screen_animation_play_exec(bContext *C, wmOperator *op)
{
int mode = (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1;
int sync = -1;
-
+
if (RNA_struct_property_is_set(op->ptr, "sync"))
sync = (RNA_boolean_get(op->ptr, "sync"));
-
+
return ED_screen_animation_play(C, sync, mode);
}
@@ -3998,12 +4064,12 @@ static void SCREEN_OT_animation_play(wmOperatorType *ot)
ot->name = "Play Animation";
ot->description = "Play animation";
ot->idname = "SCREEN_OT_animation_play";
-
+
/* api callbacks */
ot->exec = screen_animation_play_exec;
-
+
ot->poll = ED_operator_screenactive_norender;
-
+
prop = RNA_def_boolean(ot->srna, "reverse", 0, "Play in Reverse", "Animation is played backwards");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "sync", 0, "Sync", "Drop frames to maintain framerate");
@@ -4046,10 +4112,10 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot)
ot->name = "Cancel Animation";
ot->description = "Cancel animation, returning to the original frame";
ot->idname = "SCREEN_OT_animation_cancel";
-
+
/* api callbacks */
ot->exec = screen_animation_cancel_exec;
-
+
ot->poll = ED_operator_screenactive;
RNA_def_boolean(ot->srna, "restore_frame", true, "Restore Frame", "Restore the frame when animation was initialized");
@@ -4061,36 +4127,36 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot)
/** \name Border Select Operator (Template)
* \{ */
-/* operator state vars used: (added by default WM callbacks)
- * xmin, ymin
- * xmax, ymax
- *
+/* operator state vars used: (added by default WM callbacks)
+ * xmin, ymin
+ * xmax, ymax
+ *
* customdata: the wmGesture pointer
- *
+ *
* callbacks:
- *
+ *
* exec() has to be filled in by user
- *
+ *
* invoke() default WM function
* adds modal handler
- *
- * modal() default WM function
+ *
+ * modal() default WM function
* accept modal events while doing it, calls exec(), handles ESC and border drawing
- *
+ *
* poll() has to be filled in by user for context
*/
#if 0
static int border_select_exec(bContext *C, wmOperator *op)
{
int event_type = RNA_int_get(op->ptr, "event_type");
-
+
if (event_type == LEFTMOUSE)
printf("border select do select\n");
else if (event_type == RIGHTMOUSE)
printf("border select deselect\n");
- else
+ else
printf("border select do something\n");
-
+
return 1;
}
@@ -4099,15 +4165,15 @@ static void SCREEN_OT_border_select(wmOperatorType *ot)
/* identifiers */
ot->name = "Border Select";
ot->idname = "SCREEN_OT_border_select";
-
+
/* api callbacks */
ot->exec = border_select_exec;
ot->invoke = WM_gesture_border_invoke;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = ED_operator_areaactive;
-
+
/* rna */
RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
WM_operator_properties_border(ot);
@@ -4127,7 +4193,7 @@ static int fullscreen_back_exec(bContext *C, wmOperator *op)
{
bScreen *screen = CTX_wm_screen(C);
ScrArea *sa = NULL;
-
+
/* search current screen for 'fullscreen' areas */
for (sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->full) break;
@@ -4148,7 +4214,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
ot->name = "Back to Previous Screen";
ot->description = "Revert back to the original screen layout, before fullscreen area overlay";
ot->idname = "SCREEN_OT_back_to_previous";
-
+
/* api callbacks */
ot->exec = fullscreen_back_exec;
ot->poll = ED_operator_screenactive;
@@ -4163,8 +4229,8 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
static int userpref_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int sizex = 800 * UI_DPI_FAC;
- int sizey = 480 * UI_DPI_FAC;
-
+ int sizey = 500 * UI_DPI_FAC;
+
/* changes context! */
if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_USERPREFS) != NULL) {
return OPERATOR_FINISHED;
@@ -4182,7 +4248,7 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot)
ot->name = "Show User Preferences";
ot->description = "Show user preferences";
ot->idname = "SCREEN_OT_userpref_show";
-
+
/* api callbacks */
ot->invoke = userpref_show_invoke;
ot->poll = ED_operator_screenactive;
@@ -4191,17 +4257,86 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Show Drivers Editor Operator
+ * \{ */
+
+static int drivers_editor_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index = -1;
+ uiBut *but = NULL;
+
+ int sizex = 900 * UI_DPI_FAC;
+ int sizey = 580 * UI_DPI_FAC;
+
+ /* Get active property to show driver for
+ * - Need to grab it first, or else this info disappears
+ * after we've created the window
+ */
+ but = UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ /* changes context! */
+ if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_DRIVERS) != NULL) {
+ /* activate driver F-Curve for the property under the cursor */
+ if (but) {
+ FCurve *fcu;
+ bool driven, special;
+
+ fcu = rna_get_fcurve_context_ui(C,
+ &ptr, prop, index,
+ NULL, NULL, &driven, &special);
+ if (fcu) {
+ /* Isolate this F-Curve... */
+ bAnimContext ac;
+ if (ANIM_animdata_get_context(C, &ac)) {
+ int filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS;
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+ ANIM_set_active_channel(&ac, ac.data, ac.datatype, filter, fcu, ANIMTYPE_FCURVE);
+ }
+ else {
+ /* Just blindly isolate... This isn't the best, and shouldn't happen, but may be enough... */
+ fcu->flag |= (FCURVE_ACTIVE | FCURVE_SELECTED);
+ }
+ }
+ }
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
+ return OPERATOR_CANCELLED;
+ }
+}
+
+
+static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Show Drivers Editor";
+ ot->description = "Show drivers editor in a separate window";
+ ot->idname = "SCREEN_OT_drivers_editor_show";
+
+ /* api callbacks */
+ ot->invoke = drivers_editor_show_invoke;
+ ot->poll = ED_operator_screenactive;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name New Screen Operator
* \{ */
static int screen_new_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
wmWindow *win = CTX_wm_window(C);
WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
WorkSpaceLayout *layout_old = BKE_workspace_active_layout_get(win->workspace_hook);
WorkSpaceLayout *layout_new;
- layout_new = ED_workspace_layout_duplicate(workspace, layout_old, win);
+ layout_new = ED_workspace_layout_duplicate(bmain, workspace, layout_old, win);
WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTBROWSE, layout_new);
return OPERATOR_FINISHED;
@@ -4213,7 +4348,7 @@ static void SCREEN_OT_new(wmOperatorType *ot)
ot->name = "New Screen";
ot->description = "Add a new screen";
ot->idname = "SCREEN_OT_new";
-
+
/* api callbacks */
ot->exec = screen_new_exec;
ot->poll = WM_operator_winactive;
@@ -4242,7 +4377,7 @@ static void SCREEN_OT_delete(wmOperatorType *ot)
ot->name = "Delete Screen";
ot->description = "Delete active screen";
ot->idname = "SCREEN_OT_delete";
-
+
/* api callbacks */
ot->exec = screen_delete_exec;
}
@@ -4280,7 +4415,7 @@ float ED_region_blend_alpha(ARegion *ar)
alpha = (float)ar->regiontimer->duration / TIMEOUT;
/* makes sure the blend out works 100% - without area redraws */
if (rgi->hidden) alpha = 0.9f - TIMESTEP - alpha;
-
+
CLAMP(alpha, 0.0f, 1.0f);
return alpha;
}
@@ -4291,12 +4426,12 @@ float ED_region_blend_alpha(ARegion *ar)
static void region_blend_end(bContext *C, ARegion *ar, const bool is_running)
{
RegionAlphaInfo *rgi = ar->regiontimer->customdata;
-
+
/* always send redraw */
ED_region_tag_redraw(ar);
if (rgi->child_ar)
ED_region_tag_redraw(rgi->child_ar);
-
+
/* if running timer was hiding, the flag toggle went wrong */
if (is_running) {
if (rgi->hidden)
@@ -4320,14 +4455,14 @@ void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
RegionAlphaInfo *rgi;
-
+
/* end running timer */
if (ar->regiontimer) {
region_blend_end(C, ar, true);
}
rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo");
-
+
rgi->hidden = ar->flag & RGN_FLAG_HIDDEN;
rgi->sa = sa;
rgi->ar = ar;
@@ -4356,18 +4491,18 @@ static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven
{
RegionAlphaInfo *rgi;
wmTimer *timer = event->customdata;
-
+
/* event type is TIMERREGION, but we better check */
if (event->type != TIMERREGION || timer == NULL)
return OPERATOR_PASS_THROUGH;
-
+
rgi = timer->customdata;
-
+
/* always send redraws */
ED_region_tag_redraw(rgi->ar);
if (rgi->child_ar)
ED_region_tag_redraw(rgi->child_ar);
-
+
/* end timer? */
if (rgi->ar->regiontimer->duration > (double)TIMEOUT) {
region_blend_end(C, rgi->ar, false);
@@ -4383,13 +4518,13 @@ static void SCREEN_OT_region_blend(wmOperatorType *ot)
ot->name = "Region Alpha";
ot->idname = "SCREEN_OT_region_blend";
ot->description = "Blend in and out overlapping region";
-
+
/* api callbacks */
ot->invoke = region_blend_invoke;
-
+
/* flags */
ot->flag = OPTYPE_INTERNAL;
-
+
/* properties */
}
@@ -4452,11 +4587,10 @@ static int space_context_cycle_invoke(bContext *C, wmOperator *op, const wmEvent
PointerRNA ptr;
PropertyRNA *prop;
context_cycle_prop_get(CTX_wm_screen(C), CTX_wm_area(C), &ptr, &prop);
-
const int old_context = RNA_property_enum_get(&ptr, prop);
const int new_context = RNA_property_enum_step(
- C, &ptr, prop, old_context,
- direction == SPACE_CONTEXT_CYCLE_PREV ? -1 : 1);
+ C, &ptr, prop, old_context,
+ direction == SPACE_CONTEXT_CYCLE_PREV ? -1 : 1);
RNA_property_enum_set(&ptr, prop, new_context);
RNA_property_update(C, &ptr, prop);
@@ -4483,6 +4617,51 @@ static void SCREEN_OT_space_context_cycle(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Workspace Cycle Operator
+ * \{ */
+
+static int space_workspace_cycle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ wmWindow *win = CTX_wm_window(C);
+ if (WM_window_is_temp_screen(win)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ Main *bmain = CTX_data_main(C);
+ const int direction = RNA_enum_get(op->ptr, "direction");
+ WorkSpace *workspace_src = WM_window_get_active_workspace(win);
+ WorkSpace *workspace_dst = (direction == SPACE_CONTEXT_CYCLE_PREV) ? workspace_src->id.prev : workspace_src->id.next;
+ if (workspace_dst == NULL) {
+ workspace_dst = (direction == SPACE_CONTEXT_CYCLE_PREV) ? bmain->workspaces.last : bmain->workspaces.first;
+ }
+ if (workspace_src != workspace_dst) {
+ win->workspace_hook->temp_workspace_store = workspace_dst;
+ WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace_dst);
+ win->workspace_hook->temp_workspace_store = NULL;
+ }
+ return OPERATOR_FINISHED;
+}
+
+static void SCREEN_OT_workspace_cycle(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Cycle Workspace";
+ ot->description = "Cycle through workspaces";
+ ot->idname = "SCREEN_OT_workspace_cycle";
+
+ /* api callbacks */
+ ot->invoke = space_workspace_cycle_invoke;
+ ot->poll = ED_operator_screenactive;;
+
+ ot->flag = 0;
+
+ RNA_def_enum(ot->srna, "direction", space_context_cycle_direction, SPACE_CONTEXT_CYCLE_NEXT, "Direction",
+ "Direction to cycle through");
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Assigning Operator Types
* \{ */
@@ -4494,7 +4673,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_repeat_last);
WM_operatortype_append(SCREEN_OT_repeat_history);
WM_operatortype_append(SCREEN_OT_redo_last);
-
+
/* screen tools */
WM_operatortype_append(SCREEN_OT_area_move);
WM_operatortype_append(SCREEN_OT_area_split);
@@ -4507,23 +4686,24 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_region_flip);
WM_operatortype_append(SCREEN_OT_header);
WM_operatortype_append(SCREEN_OT_header_toggle_menus);
- WM_operatortype_append(SCREEN_OT_header_toolbox);
+ WM_operatortype_append(SCREEN_OT_header_context_menu);
WM_operatortype_append(SCREEN_OT_screen_set);
WM_operatortype_append(SCREEN_OT_screen_full_area);
WM_operatortype_append(SCREEN_OT_back_to_previous);
WM_operatortype_append(SCREEN_OT_spacedata_cleanup);
WM_operatortype_append(SCREEN_OT_screenshot);
- WM_operatortype_append(SCREEN_OT_screencast);
WM_operatortype_append(SCREEN_OT_userpref_show);
+ WM_operatortype_append(SCREEN_OT_drivers_editor_show);
WM_operatortype_append(SCREEN_OT_region_blend);
WM_operatortype_append(SCREEN_OT_space_context_cycle);
-
+ WM_operatortype_append(SCREEN_OT_workspace_cycle);
+
/*frame changes*/
WM_operatortype_append(SCREEN_OT_frame_offset);
WM_operatortype_append(SCREEN_OT_frame_jump);
WM_operatortype_append(SCREEN_OT_keyframe_jump);
WM_operatortype_append(SCREEN_OT_marker_jump);
-
+
WM_operatortype_append(SCREEN_OT_animation_step);
WM_operatortype_append(SCREEN_OT_animation_play);
WM_operatortype_append(SCREEN_OT_animation_cancel);
@@ -4540,7 +4720,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(ED_OT_undo_history);
WM_operatortype_append(ED_OT_flush_edits);
-
+
}
/** \} */
@@ -4558,20 +4738,20 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
{KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap off", ""},
{0, NULL, 0, NULL, NULL}};
wmKeyMap *keymap;
-
+
/* Standard Modal keymap ------------------------------------------------ */
keymap = WM_modalkeymap_add(keyconf, "Standard Modal Map", modal_items);
-
+
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, KM_MODAL_APPLY);
WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY);
WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY);
-
+
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_SNAP_ON);
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, KM_MODAL_SNAP_OFF);
-
+
WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move");
-
+
}
static int open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
@@ -4597,14 +4777,14 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
ListBase *lb;
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
/* Screen Editing ------------------------------------------------ */
keymap = WM_keymap_find(keyconf, "Screen Editing", 0, 0);
-
+
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "modifier", 0);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "modifier", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "modifier", 2);
-
+
/* screen tools */
WM_keymap_verify_item(keymap, "SCREEN_OT_area_split", EVT_ACTIONZONE_AREA, 0, 0, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_area_join", EVT_ACTIONZONE_AREA, 0, 0, 0);
@@ -4615,65 +4795,77 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "use_hide_panels", true);
/* area move after action zones */
WM_keymap_verify_item(keymap, "SCREEN_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0);
-
+
WM_keymap_verify_item(keymap, "SCREEN_OT_area_options", RIGHTMOUSE, KM_PRESS, 0, 0);
+#ifdef USE_WM_KEYMAP_27X
WM_keymap_add_item(keymap, "SCREEN_OT_header", F9KEY, KM_PRESS, KM_ALT, 0);
+#endif
/* Header Editing ------------------------------------------------ */
/* note: this is only used when the cursor is inside the header */
keymap = WM_keymap_find(keyconf, "Header", 0, 0);
- WM_keymap_add_item(keymap, "SCREEN_OT_header_toolbox", RIGHTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SCREEN_OT_header_context_menu", RIGHTMOUSE, KM_PRESS, 0, 0);
/* Screen General ------------------------------------------------ */
keymap = WM_keymap_find(keyconf, "Screen", 0, 0);
-
+
/* standard timers */
WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_region_blend", TIMERREGION, KM_ANY, KM_ANY, 0);
-
-
+
+#ifdef USE_WM_KEYMAP_27X
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
- WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", UPARROWKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", DOWNARROWKEY, KM_PRESS, KM_CTRL, 0);
+#endif
WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_SHIFT, 0);
- kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", F10KEY, KM_PRESS, KM_ALT, 0);
+ kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "use_hide_panels", true);
+#ifdef USE_WM_KEYMAP_27X
WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "SCREEN_OT_screencast", F3KEY, KM_PRESS, KM_ALT, 0);
+#endif
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_space_context_cycle", TABKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_NEXT);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_space_context_cycle", TABKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_PREV);
+ kmi = WM_keymap_add_item(keymap, "SCREEN_OT_workspace_cycle", TABKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_NEXT);
+ kmi = WM_keymap_add_item(keymap, "SCREEN_OT_workspace_cycle", TABKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_PREV);
+
/* tests */
WM_keymap_add_item(keymap, "SCREEN_OT_region_quadview", QKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
- WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0);
+#ifdef USE_WM_KEYMAP_27X
+ WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", RKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "SCRIPT_OT_reload", F8KEY, KM_PRESS, 0, 0);
-
+#endif
+
/* files */
WM_keymap_add_item(keymap, "FILE_OT_execute", RETKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_execute", PADENTER, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_cancel", ESCKEY, KM_PRESS, 0, 0);
-
+
/* undo */
#ifdef __APPLE__
WM_keymap_add_item(keymap, "ED_OT_undo", ZKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "ED_OT_redo", ZKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0);
+#ifdef USE_WM_KEYMAP_27X
WM_keymap_add_item(keymap, "ED_OT_undo_history", ZKEY, KM_PRESS, KM_ALT | KM_OSKEY, 0);
#endif
+#endif
WM_keymap_add_item(keymap, "ED_OT_undo", ZKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ED_OT_redo", ZKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
+#ifdef USE_WM_KEYMAP_27X
WM_keymap_add_item(keymap, "ED_OT_undo_history", ZKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
-
-
+#endif
+
/* render */
kmi = WM_keymap_add_item(keymap, "RENDER_OT_render", F12KEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_viewport", true);
@@ -4683,62 +4875,68 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "RENDER_OT_view_cancel", ESCKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "RENDER_OT_view_show", F11KEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "RENDER_OT_play_rendered_anim", F11KEY, KM_PRESS, KM_CTRL, 0);
-
+
+#ifdef USE_WM_KEYMAP_27X
/* user prefs */
#ifdef __APPLE__
WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", COMMAKEY, KM_PRESS, KM_OSKEY, 0);
#endif
WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", UKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
-
-
+#endif
+
+
/* Anim Playback ------------------------------------------------ */
keymap = WM_keymap_find(keyconf, "Frames", 0, 0);
-
+
/* frame offsets */
+#ifdef USE_WM_KEYMAP_27X
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", UPARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "delta", 10);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", DOWNARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "delta", -10);
+#endif
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", -1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
-
+
+#ifdef USE_WM_KEYMAP_27X
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELDOWNMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELUPMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", -1);
-
+
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "end", true);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "end", false);
+#endif
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", true);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", false);
-
+
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", UPARROWKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "next", true);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", DOWNARROWKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "next", false);
-
+
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIALAST, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "next", true);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIAFIRST, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "next", false);
-
+
/* play (forward and backwards) */
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0)->ptr, "reverse", true);
WM_keymap_add_item(keymap, "SCREEN_OT_animation_cancel", ESCKEY, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", MEDIAPLAY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_animation_cancel", MEDIASTOP, KM_PRESS, 0, 0);
-
+
/* Alternative keys for animation and sequencer playing */
#if 0 /* XXX: disabled for restoring later... bad implementation */
keymap = WM_keymap_find(keyconf, "Frames", 0, 0);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "cycle_speed", true);
-
+
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", LEFTARROWKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "reverse", true);
RNA_boolean_set(kmi->ptr, "cycle_speed", true);
-
+
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", DOWNARROWKEY, KM_PRESS, KM_ALT, 0);
#endif
diff --git a/source/blender/editors/screen/screen_user_menu.c b/source/blender/editors/screen/screen_user_menu.c
new file mode 100644
index 00000000000..c51227d7107
--- /dev/null
+++ b/source/blender/editors/screen/screen_user_menu.c
@@ -0,0 +1,196 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/screen/screen_user_menu.c
+ * \ingroup spview3d
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "BLT_translation.h"
+
+#include "BKE_blender_user_menu.h"
+#include "BKE_context.h"
+#include "BKE_screen.h"
+#include "BKE_idprop.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Menu Type
+ * \{ */
+
+bUserMenu *ED_screen_user_menu_find(bContext *C)
+{
+ SpaceLink *sl = CTX_wm_space_data(C);
+ const char *context = CTX_data_mode_string(C);
+ return BKE_blender_user_menu_find(&U.user_menus, sl->spacetype, context);
+}
+
+bUserMenu *ED_screen_user_menu_ensure(bContext *C)
+{
+ SpaceLink *sl = CTX_wm_space_data(C);
+ const char *context = CTX_data_mode_string(C);
+ return BKE_blender_user_menu_ensure(&U.user_menus, sl->spacetype, context);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Menu Item
+ * \{ */
+
+bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(
+ ListBase *lb,
+ const wmOperatorType *ot, IDProperty *prop, short opcontext)
+{
+ for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) {
+ if (umi->type == USER_MENU_TYPE_OPERATOR) {
+ bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
+ if (STREQ(ot->idname, umi_op->op_idname) &&
+ (opcontext == umi_op->opcontext) &&
+ (IDP_EqualsProperties(prop, umi_op->prop)))
+ {
+ return umi_op;
+ }
+ }
+ }
+ return NULL;
+}
+
+struct bUserMenuItem_Menu *ED_screen_user_menu_item_find_menu(
+ struct ListBase *lb,
+ const struct MenuType *mt)
+{
+ for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) {
+ if (umi->type == USER_MENU_TYPE_MENU) {
+ bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi;
+ if (STREQ(mt->idname, umi_mt->mt_idname)) {
+ return umi_mt;
+ }
+ }
+ }
+ return NULL;
+}
+
+void ED_screen_user_menu_item_add_operator(
+ ListBase *lb, const char *ui_name,
+ const wmOperatorType *ot, const IDProperty *prop, short opcontext)
+{
+ bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_OPERATOR);
+ umi_op->opcontext = opcontext;
+ if (!STREQ(ui_name, ot->name)) {
+ STRNCPY(umi_op->item.ui_name, ui_name);
+ }
+ STRNCPY(umi_op->op_idname, ot->idname);
+ umi_op->prop = prop ? IDP_CopyProperty(prop) : NULL;
+}
+
+void ED_screen_user_menu_item_add_menu(
+ ListBase *lb, const char *ui_name,
+ const MenuType *mt)
+{
+ bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_MENU);
+ if (!STREQ(ui_name, mt->label)) {
+ STRNCPY(umi_mt->item.ui_name, ui_name);
+ }
+ STRNCPY(umi_mt->mt_idname, mt->idname);
+}
+
+void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
+{
+ BLI_remlink(lb, umi);
+ BKE_blender_user_menu_item_free(umi);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Menu Definition
+ * \{ */
+
+static void screen_user_menu_draw(const bContext *C, Menu *menu)
+{
+ SpaceLink *sl = CTX_wm_space_data(C);
+ const char *context = CTX_data_mode_string(C);
+ bUserMenu *um_array[] = {
+ BKE_blender_user_menu_find(&U.user_menus, sl->spacetype, context),
+ (sl->spacetype != SPACE_TOPBAR) ? BKE_blender_user_menu_find(&U.user_menus, SPACE_TOPBAR, context) : NULL,
+ };
+ for (int um_index = 0; um_index < ARRAY_SIZE(um_array); um_index++) {
+ bUserMenu *um = um_array[um_index];
+ if (um == NULL) {
+ continue;
+ }
+ for (bUserMenuItem *umi = um->items.first; umi; umi = umi->next) {
+ const char *ui_name = umi->ui_name[0] ? umi->ui_name : NULL;
+ if (umi->type == USER_MENU_TYPE_OPERATOR) {
+ bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
+ IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL;
+ uiItemFullO(
+ menu->layout, umi_op->op_idname, ui_name,
+ ICON_NONE, prop, umi_op->opcontext, 0, NULL);
+ }
+ else if (umi->type == USER_MENU_TYPE_MENU) {
+ bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi;
+ uiItemM(menu->layout, umi_mt->mt_idname, ui_name,
+ ICON_NONE);
+ }
+ else if (umi->type == USER_MENU_TYPE_SEP) {
+ uiItemS(menu->layout);
+ }
+ }
+ }
+}
+
+void ED_screen_user_menu_register(void)
+{
+ MenuType *mt = MEM_callocN(sizeof(MenuType), __func__);
+ strcpy(mt->idname, "SCREEN_MT_user_menu");
+ strcpy(mt->label, "Quick Favorites");
+ strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ mt->draw = screen_user_menu_draw;
+ WM_menutype_add(mt);
+}
+
+/** \} */
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 2c1cbc3d21d..387cd7df998 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -36,7 +36,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_math.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -44,20 +43,15 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-#include "DNA_userdef_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_image.h"
#include "BKE_report.h"
-#include "BKE_writeavi.h"
#include "BIF_gl.h"
-#include "GPU_immediate.h"
-#include "GPU_immediate_util.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
@@ -66,9 +60,6 @@
#include "WM_types.h"
#include "WM_api.h"
-#include "PIL_time.h"
-
-
#include "screen_intern.h"
typedef struct ScreenshotData {
@@ -104,7 +95,7 @@ static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy)
*dumpsy = WM_window_pixels_y(win);
if (*dumpsx && *dumpsy) {
-
+
dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect");
glReadBuffer(GL_FRONT);
screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char *)dumprect);
@@ -122,13 +113,13 @@ static int screenshot_data_create(bContext *C, wmOperator *op)
/* do redraw so we don't show popups/menus */
WM_redraw_windows(C);
-
+
dumprect = screenshot(C, &dumpsx, &dumpsy);
if (dumprect) {
ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot");
ScrArea *sa = CTX_wm_area(C);
-
+
scd->dumpsx = dumpsx;
scd->dumpsy = dumpsy;
scd->dumprect = dumprect;
@@ -194,7 +185,7 @@ static int screenshot_exec(bContext *C, wmOperator *op)
char path[FILE_MAX];
RNA_string_get(op->ptr, "filepath", path);
- BLI_path_abs(path, G.main->name);
+ BLI_path_abs(path, BKE_main_blendfile_path_from_global());
/* operator ensures the extension */
ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0);
@@ -233,13 +224,13 @@ static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
/* extension is added by 'screenshot_check' after */
char filepath[FILE_MAX] = "//screen";
if (G.relbase_valid) {
- BLI_strncpy(filepath, G.main->name, sizeof(filepath));
- BLI_replace_extension(filepath, sizeof(filepath), ""); /* strip '.blend' */
+ BLI_strncpy(filepath, BKE_main_blendfile_path_from_global(), sizeof(filepath));
+ BLI_path_extension_replace(filepath, sizeof(filepath), ""); /* strip '.blend' */
}
RNA_string_set(op->ptr, "filepath", filepath);
-
+
WM_event_add_fileselect(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_CANCELLED;
@@ -291,274 +282,19 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
ot->name = "Save Screenshot"; /* weak: opname starting with 'save' makes filewindow give save-over */
ot->idname = "SCREEN_OT_screenshot";
ot->description = "Capture a picture of the active area or whole Blender window";
-
+
ot->invoke = screenshot_invoke;
ot->check = screenshot_check;
ot->exec = screenshot_exec;
ot->cancel = screenshot_cancel;
ot->ui = screenshot_draw;
ot->poll = screenshot_poll;
-
+
ot->flag = 0;
-
+
WM_operator_properties_filesel(
ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, FILE_SPECIAL, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
RNA_def_boolean(ot->srna, "full", 1, "Full Screen",
"Capture the whole window (otherwise only capture the active area)");
}
-
-/* *************** screenshot movie job ************************* */
-
-typedef struct ScreenshotJob {
- Main *bmain;
- Scene *scene;
- wmWindowManager *wm;
- unsigned int *dumprect;
- int x, y, dumpsx, dumpsy;
- const short *stop;
- const short *do_update;
- ReportList reports;
-
- bMovieHandle *movie_handle;
- void *movie_ctx;
-} ScreenshotJob;
-
-
-static void screenshot_freejob(void *sjv)
-{
- ScreenshotJob *sj = sjv;
-
- if (sj->dumprect)
- MEM_freeN(sj->dumprect);
-
- if (sj->movie_handle) {
- bMovieHandle *mh = sj->movie_handle;
- mh->end_movie(sj->movie_ctx);
- mh->context_free(sj->movie_ctx);
- }
-
- MEM_freeN(sj);
-}
-
-
-/* called before redraw notifiers, copies a new dumprect */
-static void screenshot_updatejob(void *sjv)
-{
- ScreenshotJob *sj = sjv;
- unsigned int *dumprect;
-
- if (sj->dumprect == NULL) {
- dumprect = MEM_mallocN(sizeof(int) * sj->dumpsx * sj->dumpsy, "dumprect");
- screenshot_read_pixels(sj->x, sj->y, sj->dumpsx, sj->dumpsy, (unsigned char *)dumprect);
-
- sj->dumprect = dumprect;
- }
-}
-
-
-/* only this runs inside thread */
-static void screenshot_startjob(void *sjv, short *stop, short *do_update, float *UNUSED(progress))
-{
- ScreenshotJob *sj = sjv;
- RenderData rd = sj->scene->r;
- bMovieHandle *mh = NULL;
-
- /* we need this as local variables for renderdata */
- rd.frs_sec = U.scrcastfps;
- rd.frs_sec_base = 1.0f;
-
- if (BKE_imtype_is_movie(rd.im_format.imtype)) {
- mh = BKE_movie_handle_get(sj->scene->r.im_format.imtype);
- if (mh == NULL) {
- printf("Movie format unsupported\n");
- return;
- }
- sj->movie_ctx = mh->context_create();
- sj->movie_handle = mh;
-
- if (!mh->start_movie(sj->movie_ctx, sj->scene, &rd, sj->dumpsx, sj->dumpsy, &sj->reports, false, "")) {
- printf("screencast job stopped\n");
- return;
- }
- }
-
- sj->stop = stop;
- sj->do_update = do_update;
-
- *do_update = true; /* wait for opengl rect */
-
- while (*stop == 0) {
-
- if (sj->dumprect) {
-
- if (mh) {
- if (mh->append_movie(sj->movie_ctx, &rd, rd.sfra, rd.cfra, (int *)sj->dumprect,
- sj->dumpsx, sj->dumpsy, "", &sj->reports))
- {
- BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", rd.cfra);
- printf("Appended frame %d\n", rd.cfra);
- }
- else {
- break;
- }
- }
- else {
- ImBuf *ibuf = IMB_allocImBuf(sj->dumpsx, sj->dumpsy, rd.im_format.planes, 0);
- char name[FILE_MAX];
- int ok;
-
- BKE_image_path_from_imformat(
- name, rd.pic, sj->bmain->name, rd.cfra,
- &rd.im_format, (rd.scemode & R_EXTENSION) != 0, true, NULL);
-
- ibuf->rect = sj->dumprect;
- ok = BKE_imbuf_write(ibuf, name, &rd.im_format);
-
- if (ok == 0) {
- printf("Write error: cannot save %s\n", name);
- BKE_reportf(&sj->reports, RPT_INFO, "Write error: cannot save %s", name);
- break;
- }
- else {
- printf("Saved file: %s\n", name);
- BKE_reportf(&sj->reports, RPT_INFO, "Saved file: %s", name);
- }
-
- /* imbuf knows which rects are not part of ibuf */
- IMB_freeImBuf(ibuf);
- }
-
- MEM_freeN(sj->dumprect);
- sj->dumprect = NULL;
-
- *do_update = true;
-
- rd.cfra++;
-
- }
- else
- PIL_sleep_ms(U.scrcastwait);
- }
-
- if (mh) {
- mh->end_movie(sj->movie_ctx);
- mh->context_free(sj->movie_ctx);
- sj->movie_handle = NULL;
- }
-
- BKE_report(&sj->reports, RPT_INFO, "Screencast job stopped");
-}
-
-/* Helper callback for drawing the cursor itself */
-static void screencast_draw_cursor(bContext *UNUSED(C), int x, int y, void *UNUSED(p_ptr))
-{
- glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
-
- Gwn_VertFormat *format = immVertexFormat();
- unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- immUniformColor4ub(0, 0, 0, 32);
- imm_draw_circle_fill_2d(pos, (float)x, (float)y, 20, 40);
-
- immUniformColor4ub(255, 255, 255, 128);
- imm_draw_circle_wire_2d(pos, (float)x, (float)y, 20, 40);
-
- immUnbindProgram();
-
- glDisable(GL_BLEND);
- glDisable(GL_LINE_SMOOTH);
-}
-
-/* Turn brush cursor in 3D view on/off */
-static void screencast_cursor_toggle(wmWindowManager *wm, short enable)
-{
- static void *cursor = NULL;
-
- if (cursor && !enable) {
- /* clear cursor */
- WM_paint_cursor_end(wm, cursor);
- cursor = NULL;
- }
- else if (enable) {
- /* enable cursor */
- cursor = WM_paint_cursor_activate(wm, NULL, screencast_draw_cursor, NULL);
- }
-}
-
-static void screenshot_endjob(void *sjv)
-{
- ScreenshotJob *sj = sjv;
-
- screencast_cursor_toggle(sj->wm, 0);
-}
-
-
-static int screencast_exec(bContext *C, wmOperator *op)
-{
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
- bScreen *screen = CTX_wm_screen(C);
- wmJob *wm_job;
- ScreenshotJob *sj;
-
- /* if called again, stop the running job */
- if (WM_jobs_test(wm, screen, WM_JOB_TYPE_SCREENCAST))
- WM_jobs_stop(wm, screen, screenshot_startjob);
-
- wm_job = WM_jobs_get(wm, win, screen, "Screencast", 0, WM_JOB_TYPE_SCREENCAST);
- sj = MEM_callocN(sizeof(ScreenshotJob), "screenshot job");
-
- /* setup sj */
- if (RNA_boolean_get(op->ptr, "full")) {
- sj->x = 0;
- sj->y = 0;
- sj->dumpsx = WM_window_pixels_x(win);
- sj->dumpsy = WM_window_pixels_y(win);
- }
- else {
- ScrArea *curarea = CTX_wm_area(C);
- sj->x = curarea->totrct.xmin;
- sj->y = curarea->totrct.ymin;
- sj->dumpsx = curarea->totrct.xmax - sj->x;
- sj->dumpsy = curarea->totrct.ymax - sj->y;
- }
- sj->bmain = CTX_data_main(C);
- sj->scene = CTX_data_scene(C);
- sj->wm = wm;
-
- BKE_reports_init(&sj->reports, RPT_PRINT);
-
- /* setup job */
- WM_jobs_customdata_set(wm_job, sj, screenshot_freejob);
- WM_jobs_timer(wm_job, 0.1, 0, NC_SCREEN | ND_SCREENCAST);
- WM_jobs_callbacks(wm_job, screenshot_startjob, NULL, screenshot_updatejob, screenshot_endjob);
-
- WM_jobs_start(sj->wm, wm_job);
-
- screencast_cursor_toggle(sj->wm, 1);
-
- WM_event_add_notifier(C, NC_SCREEN | ND_SCREENCAST, screen);
-
- return OPERATOR_FINISHED;
-}
-
-void SCREEN_OT_screencast(wmOperatorType *ot)
-{
- ot->name = "Make Screencast";
- ot->idname = "SCREEN_OT_screencast";
- ot->description = "Capture a video of the active area or whole Blender window";
-
- ot->invoke = WM_operator_confirm;
- ot->exec = screencast_exec;
- ot->poll = screenshot_poll; /* shared poll */
-
- ot->flag = 0;
-
- RNA_def_property(ot->srna, "filepath", PROP_STRING, PROP_FILEPATH);
- RNA_def_boolean(ot->srna, "full", 1, "Full Screen",
- "Capture the whole window (otherwise only capture the active area)");
-}
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 21dc4e0f923..800b1fbe51d 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -65,6 +65,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "WM_toolsystem.h"
#include "screen_intern.h"
@@ -109,7 +110,7 @@ static void workspace_change_update_view_layer(
WorkSpace *workspace_new, const WorkSpace *workspace_old,
Scene *scene)
{
- if (!BKE_workspace_view_layer_get(workspace_new, scene)) {
+ if (!BKE_workspace_view_layer_exists(workspace_new, scene)) {
BKE_workspace_view_layer_set(workspace_new, BKE_workspace_view_layer_get(workspace_old, scene), scene);
}
}
@@ -130,7 +131,7 @@ static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, v
}
static WorkSpaceLayout *workspace_change_get_new_layout(
- WorkSpace *workspace_new, wmWindow *win)
+ Main *bmain, WorkSpace *workspace_new, wmWindow *win)
{
/* ED_workspace_duplicate may have stored a layout to activate once the workspace gets activated. */
WorkSpaceLayout *layout_new;
@@ -154,7 +155,7 @@ static WorkSpaceLayout *workspace_change_get_new_layout(
NULL, false);
if (!layout_temp) {
/* fallback solution: duplicate layout */
- layout_temp = ED_workspace_layout_duplicate(workspace_new, layout_new, win);
+ layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_new, win);
}
layout_new = layout_temp;
}
@@ -176,7 +177,7 @@ bool ED_workspace_change(
{
Main *bmain = CTX_data_main(C);
WorkSpace *workspace_old = WM_window_get_active_workspace(win);
- WorkSpaceLayout *layout_new = workspace_change_get_new_layout(workspace_new, win);
+ WorkSpaceLayout *layout_new = workspace_change_get_new_layout(bmain, workspace_new, win);
bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new);
bScreen *screen_old = BKE_workspace_active_screen_get(win->workspace_hook);
@@ -198,11 +199,11 @@ bool ED_workspace_change(
screen_change_update(C, win, screen_new);
workspace_change_update(workspace_new, workspace_old, C, wm);
- BLI_assert(BKE_workspace_view_layer_get(workspace_new, CTX_data_scene(C)) != NULL);
+ BLI_assert(BKE_workspace_view_layer_exists(workspace_new, CTX_data_scene(C)) != NULL);
BLI_assert(CTX_wm_workspace(C) == workspace_new);
- WM_toolsystem_unlink(C, workspace_old);
- WM_toolsystem_link(C, workspace_new);
+ WM_toolsystem_unlink_all(C, workspace_old);
+ WM_toolsystem_reinit_all(C, win);
return true;
}
@@ -224,10 +225,10 @@ WorkSpace *ED_workspace_duplicate(
bmain, workspace_old->id.name + 2, scene,
BKE_workspace_view_layer_get(workspace_old, scene));
- workspace_new->tool = workspace_old->tool;
+ /* TODO(campbell): tools */
for (WorkSpaceLayout *layout_old = layouts_old->first; layout_old; layout_old = layout_old->next) {
- WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(workspace_new, layout_old, win);
+ WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win);
if (layout_active_old == layout_old) {
win->workspace_hook->temp_layout_store = layout_new;
@@ -331,6 +332,12 @@ static void WORKSPACE_OT_workspace_delete(wmOperatorType *ot)
ot->exec = workspace_delete_exec;
}
+static int workspace_append_activate_poll(bContext *C)
+{
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false);
+ return WM_operator_poll(C, ot);
+}
+
static int workspace_append(bContext *C, const char *directory, const char *idname)
{
wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false);
@@ -385,6 +392,7 @@ static void WORKSPACE_OT_append_activate(wmOperatorType *ot)
/* api callbacks */
ot->exec = workspace_append_activate_exec;
+ ot->poll = workspace_append_activate_poll;
RNA_def_string(ot->srna, "idname", NULL, MAX_ID_NAME - 2, "Identifier",
"Name of the workspace to append and activate");
diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c
index a6f991d4bbe..6d504c05dd1 100644
--- a/source/blender/editors/screen/workspace_layout_edit.c
+++ b/source/blender/editors/screen/workspace_layout_edit.c
@@ -46,20 +46,22 @@
* Empty screen, with 1 dummy area without spacedata. Uses window size.
*/
WorkSpaceLayout *ED_workspace_layout_add(
+ Main *bmain,
WorkSpace *workspace,
wmWindow *win,
const char *name)
{
- const int screen_size_x = WM_window_screen_pixels_x(win);
- const int screen_size_y = WM_window_screen_pixels_y(win);
+ bScreen *screen;
+ rcti screen_rect;
- bScreen *screen = screen_add(name, screen_size_x, screen_size_y);
- WorkSpaceLayout *layout = BKE_workspace_layout_add(workspace, screen, name);
+ WM_window_screen_rect_calc(win, &screen_rect);
+ screen = screen_add(bmain, name, &screen_rect);
- return layout;
+ return BKE_workspace_layout_add(bmain, workspace, screen, name);
}
WorkSpaceLayout *ED_workspace_layout_duplicate(
+ Main *bmain,
WorkSpace *workspace, const WorkSpaceLayout *layout_old,
wmWindow *win)
{
@@ -72,7 +74,7 @@ WorkSpaceLayout *ED_workspace_layout_duplicate(
return NULL; /* XXX handle this case! */
}
- layout_new = ED_workspace_layout_add(workspace, win, name);
+ layout_new = ED_workspace_layout_add(bmain, workspace, win, name);
screen_new = BKE_workspace_layout_screen_get(layout_new);
screen_data_copy(screen_new, screen_old);