ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
This commit is contained in:
@@ -16,51 +16,51 @@
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
../include
|
||||
../../blenfont
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blenloader
|
||||
../../blentranslation
|
||||
../../bmesh
|
||||
../../depsgraph
|
||||
../../gpu
|
||||
../../imbuf
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
../include
|
||||
../../blenfont
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blenloader
|
||||
../../blentranslation
|
||||
../../bmesh
|
||||
../../depsgraph
|
||||
../../gpu
|
||||
../../imbuf
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${GLEW_INCLUDE_PATH}
|
||||
${GLEW_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
area.c
|
||||
area_utils.c
|
||||
glutil.c
|
||||
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
|
||||
area.c
|
||||
area_utils.c
|
||||
glutil.c
|
||||
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
|
||||
|
||||
screen_intern.h
|
||||
screen_intern.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
bf_editor_datafiles
|
||||
bf_editor_space_sequencer
|
||||
bf_editor_datafiles
|
||||
bf_editor_space_sequencer
|
||||
)
|
||||
|
||||
if(WITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,18 +42,20 @@
|
||||
/**
|
||||
* Callback for #ARegionType.message_subscribe
|
||||
*/
|
||||
void ED_region_generic_tools_region_message_subscribe(
|
||||
const struct bContext *UNUSED(C),
|
||||
struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene),
|
||||
struct bScreen *UNUSED(screen), struct ScrArea *UNUSED(sa), struct ARegion *ar,
|
||||
struct wmMsgBus *mbus)
|
||||
void ED_region_generic_tools_region_message_subscribe(const struct bContext *UNUSED(C),
|
||||
struct WorkSpace *UNUSED(workspace),
|
||||
struct Scene *UNUSED(scene),
|
||||
struct bScreen *UNUSED(screen),
|
||||
struct ScrArea *UNUSED(sa),
|
||||
struct ARegion *ar,
|
||||
struct wmMsgBus *mbus)
|
||||
{
|
||||
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
|
||||
.owner = ar,
|
||||
.user_data = ar,
|
||||
.notify = ED_region_do_msg_notify_tag_redraw,
|
||||
};
|
||||
WM_msg_subscribe_rna_anon_prop(mbus, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
|
||||
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
|
||||
.owner = ar,
|
||||
.user_data = ar,
|
||||
.notify = ED_region_do_msg_notify_tag_redraw,
|
||||
};
|
||||
WM_msg_subscribe_rna_anon_prop(mbus, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,23 +63,23 @@ void ED_region_generic_tools_region_message_subscribe(
|
||||
*/
|
||||
int ED_region_generic_tools_region_snap_size(const ARegion *ar, int size, int axis)
|
||||
{
|
||||
if (axis == 0) {
|
||||
/* Note, this depends on the icon size: see #ICON_DEFAULT_HEIGHT_TOOLBAR. */
|
||||
const float snap_units[] = {2 + 0.8f, 4 + 0.8f};
|
||||
const float aspect = BLI_rctf_size_x(&ar->v2d.cur) / (BLI_rcti_size_x(&ar->v2d.mask) + 1);
|
||||
int best_diff = INT_MAX;
|
||||
int best_size = size;
|
||||
for (uint i = 0; i < ARRAY_SIZE(snap_units); i += 1) {
|
||||
const int test_size = (snap_units[i] * U.widget_unit) / (UI_DPI_FAC * aspect);
|
||||
const int test_diff = ABS(test_size - size);
|
||||
if (test_diff < best_diff) {
|
||||
best_size = test_size;
|
||||
best_diff = test_diff;
|
||||
}
|
||||
}
|
||||
return best_size;
|
||||
}
|
||||
return size;
|
||||
if (axis == 0) {
|
||||
/* Note, this depends on the icon size: see #ICON_DEFAULT_HEIGHT_TOOLBAR. */
|
||||
const float snap_units[] = {2 + 0.8f, 4 + 0.8f};
|
||||
const float aspect = BLI_rctf_size_x(&ar->v2d.cur) / (BLI_rcti_size_x(&ar->v2d.mask) + 1);
|
||||
int best_diff = INT_MAX;
|
||||
int best_size = size;
|
||||
for (uint i = 0; i < ARRAY_SIZE(snap_units); i += 1) {
|
||||
const int test_size = (snap_units[i] * U.widget_unit) / (UI_DPI_FAC * aspect);
|
||||
const int test_diff = ABS(test_size - size);
|
||||
if (test_diff < best_diff) {
|
||||
best_size = test_size;
|
||||
best_diff = test_diff;
|
||||
}
|
||||
}
|
||||
return best_size;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -44,80 +44,80 @@
|
||||
*/
|
||||
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;
|
||||
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;
|
||||
|
||||
if (height < width) {
|
||||
h = height / 8;
|
||||
w = height / 4;
|
||||
}
|
||||
else {
|
||||
h = width / 8;
|
||||
w = width / 4;
|
||||
}
|
||||
if (height < width) {
|
||||
h = height / 8;
|
||||
w = height / 4;
|
||||
}
|
||||
else {
|
||||
h = width / 8;
|
||||
w = width / 4;
|
||||
}
|
||||
|
||||
points[0].x = sa->v1->vec.x;
|
||||
points[0].y = sa->v1->vec.y + height / 2;
|
||||
points[0].x = sa->v1->vec.x;
|
||||
points[0].y = sa->v1->vec.y + height / 2;
|
||||
|
||||
points[1].x = sa->v1->vec.x;
|
||||
points[1].y = sa->v1->vec.y;
|
||||
points[1].x = sa->v1->vec.x;
|
||||
points[1].y = sa->v1->vec.y;
|
||||
|
||||
points[2].x = sa->v4->vec.x - w;
|
||||
points[2].y = sa->v4->vec.y;
|
||||
points[2].x = sa->v4->vec.x - w;
|
||||
points[2].y = sa->v4->vec.y;
|
||||
|
||||
points[3].x = sa->v4->vec.x - w;
|
||||
points[3].y = sa->v4->vec.y + height / 2 - 2 * h;
|
||||
points[3].x = sa->v4->vec.x - w;
|
||||
points[3].y = sa->v4->vec.y + height / 2 - 2 * h;
|
||||
|
||||
points[4].x = sa->v4->vec.x - 2 * w;
|
||||
points[4].y = sa->v4->vec.y + height / 2;
|
||||
points[4].x = sa->v4->vec.x - 2 * w;
|
||||
points[4].y = sa->v4->vec.y + height / 2;
|
||||
|
||||
points[5].x = sa->v4->vec.x - w;
|
||||
points[5].y = sa->v4->vec.y + height / 2 + 2 * h;
|
||||
points[5].x = sa->v4->vec.x - w;
|
||||
points[5].y = sa->v4->vec.y + height / 2 + 2 * h;
|
||||
|
||||
points[6].x = sa->v3->vec.x - w;
|
||||
points[6].y = sa->v3->vec.y;
|
||||
points[6].x = sa->v3->vec.x - w;
|
||||
points[6].y = sa->v3->vec.y;
|
||||
|
||||
points[7].x = sa->v2->vec.x;
|
||||
points[7].y = sa->v2->vec.y;
|
||||
points[7].x = sa->v2->vec.x;
|
||||
points[7].y = sa->v2->vec.y;
|
||||
|
||||
points[8].x = sa->v4->vec.x;
|
||||
points[8].y = sa->v4->vec.y + height / 2 - h;
|
||||
points[8].x = sa->v4->vec.x;
|
||||
points[8].y = sa->v4->vec.y + height / 2 - h;
|
||||
|
||||
points[9].x = sa->v4->vec.x;
|
||||
points[9].y = sa->v4->vec.y + height / 2 + h;
|
||||
points[9].x = sa->v4->vec.x;
|
||||
points[9].y = sa->v4->vec.y + height / 2 + h;
|
||||
|
||||
if (dir == 'l') {
|
||||
/* when direction is left, then we flip direction of arrow */
|
||||
float cx = sa->v1->vec.x + width;
|
||||
for (i = 0; i < 10; i++) {
|
||||
points[i].x -= cx;
|
||||
points[i].x = -points[i].x;
|
||||
points[i].x += sa->v1->vec.x;
|
||||
}
|
||||
}
|
||||
if (dir == 'l') {
|
||||
/* when direction is left, then we flip direction of arrow */
|
||||
float cx = sa->v1->vec.x + width;
|
||||
for (i = 0; i < 10; i++) {
|
||||
points[i].x -= cx;
|
||||
points[i].x = -points[i].x;
|
||||
points[i].x += sa->v1->vec.x;
|
||||
}
|
||||
}
|
||||
|
||||
immBegin(GPU_PRIM_TRI_FAN, 5);
|
||||
immBegin(GPU_PRIM_TRI_FAN, 5);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
immVertex2f(pos, points[i].x, points[i].y);
|
||||
}
|
||||
for (i = 0; i < 5; i++) {
|
||||
immVertex2f(pos, points[i].x, points[i].y);
|
||||
}
|
||||
|
||||
immEnd();
|
||||
immEnd();
|
||||
|
||||
immBegin(GPU_PRIM_TRI_FAN, 5);
|
||||
immBegin(GPU_PRIM_TRI_FAN, 5);
|
||||
|
||||
for (i = 4; i < 8; i++) {
|
||||
immVertex2f(pos, points[i].x, points[i].y);
|
||||
}
|
||||
for (i = 4; i < 8; i++) {
|
||||
immVertex2f(pos, points[i].x, points[i].y);
|
||||
}
|
||||
|
||||
immVertex2f(pos, points[0].x, points[0].y);
|
||||
immEnd();
|
||||
immVertex2f(pos, points[0].x, points[0].y);
|
||||
immEnd();
|
||||
|
||||
immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y);
|
||||
immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y);
|
||||
immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y);
|
||||
immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,80 +125,80 @@ 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;
|
||||
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;
|
||||
|
||||
if (height < width) {
|
||||
h = height / 4;
|
||||
w = height / 8;
|
||||
}
|
||||
else {
|
||||
h = width / 4;
|
||||
w = width / 8;
|
||||
}
|
||||
if (height < width) {
|
||||
h = height / 4;
|
||||
w = height / 8;
|
||||
}
|
||||
else {
|
||||
h = width / 4;
|
||||
w = width / 8;
|
||||
}
|
||||
|
||||
points[0].x = sa->v1->vec.x + width / 2;
|
||||
points[0].y = sa->v3->vec.y;
|
||||
points[0].x = sa->v1->vec.x + width / 2;
|
||||
points[0].y = sa->v3->vec.y;
|
||||
|
||||
points[1].x = sa->v2->vec.x;
|
||||
points[1].y = sa->v2->vec.y;
|
||||
points[1].x = sa->v2->vec.x;
|
||||
points[1].y = sa->v2->vec.y;
|
||||
|
||||
points[2].x = sa->v1->vec.x;
|
||||
points[2].y = sa->v1->vec.y + h;
|
||||
points[2].x = sa->v1->vec.x;
|
||||
points[2].y = sa->v1->vec.y + h;
|
||||
|
||||
points[3].x = sa->v1->vec.x + width / 2 - 2 * w;
|
||||
points[3].y = sa->v1->vec.y + h;
|
||||
points[3].x = sa->v1->vec.x + width / 2 - 2 * w;
|
||||
points[3].y = sa->v1->vec.y + h;
|
||||
|
||||
points[4].x = sa->v1->vec.x + width / 2;
|
||||
points[4].y = sa->v1->vec.y + 2 * h;
|
||||
points[4].x = sa->v1->vec.x + width / 2;
|
||||
points[4].y = sa->v1->vec.y + 2 * h;
|
||||
|
||||
points[5].x = sa->v1->vec.x + width / 2 + 2 * w;
|
||||
points[5].y = sa->v1->vec.y + h;
|
||||
points[5].x = sa->v1->vec.x + width / 2 + 2 * w;
|
||||
points[5].y = sa->v1->vec.y + h;
|
||||
|
||||
points[6].x = sa->v4->vec.x;
|
||||
points[6].y = sa->v4->vec.y + h;
|
||||
points[6].x = sa->v4->vec.x;
|
||||
points[6].y = sa->v4->vec.y + h;
|
||||
|
||||
points[7].x = sa->v3->vec.x;
|
||||
points[7].y = sa->v3->vec.y;
|
||||
points[7].x = sa->v3->vec.x;
|
||||
points[7].y = sa->v3->vec.y;
|
||||
|
||||
points[8].x = sa->v1->vec.x + width / 2 - w;
|
||||
points[8].y = sa->v1->vec.y;
|
||||
points[8].x = sa->v1->vec.x + width / 2 - w;
|
||||
points[8].y = sa->v1->vec.y;
|
||||
|
||||
points[9].x = sa->v1->vec.x + width / 2 + w;
|
||||
points[9].y = sa->v1->vec.y;
|
||||
points[9].x = sa->v1->vec.x + width / 2 + w;
|
||||
points[9].y = sa->v1->vec.y;
|
||||
|
||||
if (dir == 'u') {
|
||||
/* when direction is up, then we flip direction of arrow */
|
||||
float cy = sa->v1->vec.y + height;
|
||||
for (i = 0; i < 10; i++) {
|
||||
points[i].y -= cy;
|
||||
points[i].y = -points[i].y;
|
||||
points[i].y += sa->v1->vec.y;
|
||||
}
|
||||
}
|
||||
if (dir == 'u') {
|
||||
/* when direction is up, then we flip direction of arrow */
|
||||
float cy = sa->v1->vec.y + height;
|
||||
for (i = 0; i < 10; i++) {
|
||||
points[i].y -= cy;
|
||||
points[i].y = -points[i].y;
|
||||
points[i].y += sa->v1->vec.y;
|
||||
}
|
||||
}
|
||||
|
||||
immBegin(GPU_PRIM_TRI_FAN, 5);
|
||||
immBegin(GPU_PRIM_TRI_FAN, 5);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
immVertex2f(pos, points[i].x, points[i].y);
|
||||
}
|
||||
for (i = 0; i < 5; i++) {
|
||||
immVertex2f(pos, points[i].x, points[i].y);
|
||||
}
|
||||
|
||||
immEnd();
|
||||
immEnd();
|
||||
|
||||
immBegin(GPU_PRIM_TRI_FAN, 5);
|
||||
immBegin(GPU_PRIM_TRI_FAN, 5);
|
||||
|
||||
for (i = 4; i < 8; i++) {
|
||||
immVertex2f(pos, points[i].x, points[i].y);
|
||||
}
|
||||
for (i = 4; i < 8; i++) {
|
||||
immVertex2f(pos, points[i].x, points[i].y);
|
||||
}
|
||||
|
||||
immVertex2f(pos, points[0].x, points[0].y);
|
||||
immEnd();
|
||||
immVertex2f(pos, points[0].x, points[0].y);
|
||||
immEnd();
|
||||
|
||||
immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y);
|
||||
immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y);
|
||||
immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y);
|
||||
immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,88 +206,88 @@ static void draw_vertical_join_shape(ScrArea *sa, char dir, unsigned int pos)
|
||||
*/
|
||||
static void draw_join_shape(ScrArea *sa, char dir, unsigned int pos)
|
||||
{
|
||||
if (dir == 'u' || dir == 'd') {
|
||||
draw_vertical_join_shape(sa, dir, pos);
|
||||
}
|
||||
else {
|
||||
draw_horizontal_join_shape(sa, dir, pos);
|
||||
}
|
||||
if (dir == 'u' || dir == 'd') {
|
||||
draw_vertical_join_shape(sa, dir, pos);
|
||||
}
|
||||
else {
|
||||
draw_horizontal_join_shape(sa, dir, pos);
|
||||
}
|
||||
}
|
||||
|
||||
#define CORNER_RESOLUTION 3
|
||||
|
||||
static void do_vert_pair(GPUVertBuf *vbo, uint pos, uint *vidx, int corner, int i)
|
||||
{
|
||||
float inter[2], exter[2];
|
||||
inter[0] = cosf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f)));
|
||||
inter[1] = sinf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f)));
|
||||
float inter[2], exter[2];
|
||||
inter[0] = cosf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f)));
|
||||
inter[1] = sinf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f)));
|
||||
|
||||
/* Snap point to edge */
|
||||
float div = 1.0f / max_ff(fabsf(inter[0]), fabsf(inter[1]));
|
||||
mul_v2_v2fl(exter, inter, div);
|
||||
exter[0] = roundf(exter[0]);
|
||||
exter[1] = roundf(exter[1]);
|
||||
/* Snap point to edge */
|
||||
float div = 1.0f / max_ff(fabsf(inter[0]), fabsf(inter[1]));
|
||||
mul_v2_v2fl(exter, inter, div);
|
||||
exter[0] = roundf(exter[0]);
|
||||
exter[1] = roundf(exter[1]);
|
||||
|
||||
if (i == 0 || i == (CORNER_RESOLUTION - 1)) {
|
||||
copy_v2_v2(inter, exter);
|
||||
}
|
||||
if (i == 0 || i == (CORNER_RESOLUTION - 1)) {
|
||||
copy_v2_v2(inter, exter);
|
||||
}
|
||||
|
||||
/* Line width is 20% of the entire corner size. */
|
||||
const float line_width = 0.2f; /* Keep in sync with shader */
|
||||
mul_v2_fl(inter, 1.0f - line_width);
|
||||
mul_v2_fl(exter, 1.0f + line_width);
|
||||
/* Line width is 20% of the entire corner size. */
|
||||
const float line_width = 0.2f; /* Keep in sync with shader */
|
||||
mul_v2_fl(inter, 1.0f - line_width);
|
||||
mul_v2_fl(exter, 1.0f + line_width);
|
||||
|
||||
switch (corner) {
|
||||
case 0:
|
||||
add_v2_v2(inter, (float[2]){-1.0f, -1.0f});
|
||||
add_v2_v2(exter, (float[2]){-1.0f, -1.0f});
|
||||
break;
|
||||
case 1:
|
||||
add_v2_v2(inter, (float[2]){1.0f, -1.0f});
|
||||
add_v2_v2(exter, (float[2]){1.0f, -1.0f});
|
||||
break;
|
||||
case 2:
|
||||
add_v2_v2(inter, (float[2]){1.0f, 1.0f});
|
||||
add_v2_v2(exter, (float[2]){1.0f, 1.0f});
|
||||
break;
|
||||
case 3:
|
||||
add_v2_v2(inter, (float[2]){-1.0f, 1.0f});
|
||||
add_v2_v2(exter, (float[2]){-1.0f, 1.0f});
|
||||
break;
|
||||
}
|
||||
switch (corner) {
|
||||
case 0:
|
||||
add_v2_v2(inter, (float[2]){-1.0f, -1.0f});
|
||||
add_v2_v2(exter, (float[2]){-1.0f, -1.0f});
|
||||
break;
|
||||
case 1:
|
||||
add_v2_v2(inter, (float[2]){1.0f, -1.0f});
|
||||
add_v2_v2(exter, (float[2]){1.0f, -1.0f});
|
||||
break;
|
||||
case 2:
|
||||
add_v2_v2(inter, (float[2]){1.0f, 1.0f});
|
||||
add_v2_v2(exter, (float[2]){1.0f, 1.0f});
|
||||
break;
|
||||
case 3:
|
||||
add_v2_v2(inter, (float[2]){-1.0f, 1.0f});
|
||||
add_v2_v2(exter, (float[2]){-1.0f, 1.0f});
|
||||
break;
|
||||
}
|
||||
|
||||
GPU_vertbuf_attr_set(vbo, pos, (*vidx)++, inter);
|
||||
GPU_vertbuf_attr_set(vbo, pos, (*vidx)++, exter);
|
||||
GPU_vertbuf_attr_set(vbo, pos, (*vidx)++, inter);
|
||||
GPU_vertbuf_attr_set(vbo, pos, (*vidx)++, exter);
|
||||
}
|
||||
|
||||
static GPUBatch *batch_screen_edges_get(int *corner_len)
|
||||
{
|
||||
static GPUBatch *screen_edges_batch = NULL;
|
||||
static GPUBatch *screen_edges_batch = NULL;
|
||||
|
||||
if (screen_edges_batch == NULL) {
|
||||
GPUVertFormat format = {0};
|
||||
uint pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
if (screen_edges_batch == NULL) {
|
||||
GPUVertFormat format = {0};
|
||||
uint pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, CORNER_RESOLUTION * 2 * 4 + 2);
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, CORNER_RESOLUTION * 2 * 4 + 2);
|
||||
|
||||
uint vidx = 0;
|
||||
for (int corner = 0; corner < 4; ++corner) {
|
||||
for (int c = 0; c < CORNER_RESOLUTION; ++c) {
|
||||
do_vert_pair(vbo, pos, &vidx, corner, c);
|
||||
}
|
||||
}
|
||||
/* close the loop */
|
||||
do_vert_pair(vbo, pos, &vidx, 0, 0);
|
||||
uint vidx = 0;
|
||||
for (int corner = 0; corner < 4; ++corner) {
|
||||
for (int c = 0; c < CORNER_RESOLUTION; ++c) {
|
||||
do_vert_pair(vbo, pos, &vidx, corner, c);
|
||||
}
|
||||
}
|
||||
/* close the loop */
|
||||
do_vert_pair(vbo, pos, &vidx, 0, 0);
|
||||
|
||||
screen_edges_batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
||||
gpu_batch_presets_register(screen_edges_batch);
|
||||
}
|
||||
screen_edges_batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
||||
gpu_batch_presets_register(screen_edges_batch);
|
||||
}
|
||||
|
||||
if (corner_len) {
|
||||
*corner_len = CORNER_RESOLUTION * 2;
|
||||
}
|
||||
return screen_edges_batch;
|
||||
if (corner_len) {
|
||||
*corner_len = CORNER_RESOLUTION * 2;
|
||||
}
|
||||
return screen_edges_batch;
|
||||
}
|
||||
|
||||
#undef CORNER_RESOLUTION
|
||||
@@ -297,10 +297,11 @@ static GPUBatch *batch_screen_edges_get(int *corner_len)
|
||||
*/
|
||||
static void scrarea_draw_shape_dark(ScrArea *sa, char dir, unsigned int pos)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
draw_join_shape(sa, dir, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,42 +309,43 @@ 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)
|
||||
{
|
||||
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); */
|
||||
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); */
|
||||
|
||||
immRectf(pos, sa->v1->vec.x, sa->v1->vec.y, sa->v3->vec.x, sa->v3->vec.y);
|
||||
immRectf(pos, sa->v1->vec.x, sa->v1->vec.y, sa->v3->vec.x, sa->v3->vec.y);
|
||||
}
|
||||
|
||||
static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, short x2, short y2, float edge_thickness)
|
||||
static void drawscredge_area_draw(
|
||||
int sizex, int sizey, short x1, short y1, short x2, short y2, float edge_thickness)
|
||||
{
|
||||
rctf rect;
|
||||
BLI_rctf_init(&rect, (float)x1, (float)x2, (float)y1, (float)y2);
|
||||
rctf rect;
|
||||
BLI_rctf_init(&rect, (float)x1, (float)x2, (float)y1, (float)y2);
|
||||
|
||||
/* right border area */
|
||||
if (x2 >= sizex - 1) {
|
||||
rect.xmax += edge_thickness * 0.5f;
|
||||
}
|
||||
/* right border area */
|
||||
if (x2 >= sizex - 1) {
|
||||
rect.xmax += edge_thickness * 0.5f;
|
||||
}
|
||||
|
||||
/* left border area */
|
||||
if (x1 <= 0) { /* otherwise it draws the emboss of window over */
|
||||
rect.xmin -= edge_thickness * 0.5f;
|
||||
}
|
||||
/* left border area */
|
||||
if (x1 <= 0) { /* otherwise it draws the emboss of window over */
|
||||
rect.xmin -= edge_thickness * 0.5f;
|
||||
}
|
||||
|
||||
/* top border area */
|
||||
if (y2 >= sizey - 1) {
|
||||
rect.ymax += edge_thickness * 0.5f;
|
||||
}
|
||||
/* top border area */
|
||||
if (y2 >= sizey - 1) {
|
||||
rect.ymax += edge_thickness * 0.5f;
|
||||
}
|
||||
|
||||
/* bottom border area */
|
||||
if (y1 <= 0) {
|
||||
rect.ymin -= edge_thickness * 0.5f;
|
||||
}
|
||||
/* bottom border area */
|
||||
if (y1 <= 0) {
|
||||
rect.ymin -= edge_thickness * 0.5f;
|
||||
}
|
||||
|
||||
GPUBatch *batch = batch_screen_edges_get(NULL);
|
||||
GPU_batch_uniform_4fv(batch, "rect", (float *)&rect);
|
||||
GPU_batch_draw(batch);
|
||||
GPUBatch *batch = batch_screen_edges_get(NULL);
|
||||
GPU_batch_uniform_4fv(batch, "rect", (float *)&rect);
|
||||
GPU_batch_draw(batch);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -351,12 +353,12 @@ static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, shor
|
||||
*/
|
||||
static void drawscredge_area(ScrArea *sa, int sizex, int sizey, float edge_thickness)
|
||||
{
|
||||
short x1 = sa->v1->vec.x;
|
||||
short y1 = sa->v1->vec.y;
|
||||
short x2 = sa->v3->vec.x;
|
||||
short y2 = sa->v3->vec.y;
|
||||
short x1 = sa->v1->vec.x;
|
||||
short y1 = sa->v1->vec.y;
|
||||
short x2 = sa->v3->vec.x;
|
||||
short y2 = sa->v3->vec.y;
|
||||
|
||||
drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, edge_thickness);
|
||||
drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, edge_thickness);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,71 +366,72 @@ static void drawscredge_area(ScrArea *sa, int sizex, int sizey, float edge_thick
|
||||
*/
|
||||
void ED_screen_draw_edges(wmWindow *win)
|
||||
{
|
||||
bScreen *screen = WM_window_get_active_screen(win);
|
||||
screen->do_draw = false;
|
||||
bScreen *screen = WM_window_get_active_screen(win);
|
||||
screen->do_draw = false;
|
||||
|
||||
if (screen->state == SCREENFULL) {
|
||||
return;
|
||||
}
|
||||
if (screen->state == SCREENFULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (screen->temp && BLI_listbase_is_single(&screen->areabase)) {
|
||||
return;
|
||||
}
|
||||
if (screen->temp && BLI_listbase_is_single(&screen->areabase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int winsize_x = WM_window_pixels_x(win);
|
||||
const int winsize_y = WM_window_pixels_y(win);
|
||||
float col[4], corner_scale, edge_thickness;
|
||||
int verts_per_corner = 0;
|
||||
const int winsize_x = WM_window_pixels_x(win);
|
||||
const int winsize_y = WM_window_pixels_y(win);
|
||||
float col[4], corner_scale, edge_thickness;
|
||||
int verts_per_corner = 0;
|
||||
|
||||
ScrArea *sa;
|
||||
ScrArea *sa;
|
||||
|
||||
rcti scissor_rect;
|
||||
BLI_rcti_init_minmax(&scissor_rect);
|
||||
for (sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){sa->v1->vec.x, sa->v1->vec.y});
|
||||
BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){sa->v3->vec.x, sa->v3->vec.y});
|
||||
}
|
||||
rcti scissor_rect;
|
||||
BLI_rcti_init_minmax(&scissor_rect);
|
||||
for (sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){sa->v1->vec.x, sa->v1->vec.y});
|
||||
BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){sa->v3->vec.x, sa->v3->vec.y});
|
||||
}
|
||||
|
||||
if (GPU_type_matches(GPU_DEVICE_INTEL_UHD, GPU_OS_UNIX, GPU_DRIVER_ANY)) {
|
||||
/* For some reason, on linux + Intel UHD Graphics 620 the driver
|
||||
* hangs if we don't flush before this. (See T57455) */
|
||||
GPU_flush();
|
||||
}
|
||||
if (GPU_type_matches(GPU_DEVICE_INTEL_UHD, GPU_OS_UNIX, GPU_DRIVER_ANY)) {
|
||||
/* For some reason, on linux + Intel UHD Graphics 620 the driver
|
||||
* hangs if we don't flush before this. (See T57455) */
|
||||
GPU_flush();
|
||||
}
|
||||
|
||||
GPU_scissor(scissor_rect.xmin,
|
||||
scissor_rect.ymin,
|
||||
BLI_rcti_size_x(&scissor_rect) + 1,
|
||||
BLI_rcti_size_y(&scissor_rect) + 1);
|
||||
GPU_scissor(scissor_rect.xmin,
|
||||
scissor_rect.ymin,
|
||||
BLI_rcti_size_x(&scissor_rect) + 1,
|
||||
BLI_rcti_size_y(&scissor_rect) + 1);
|
||||
|
||||
/* It seems that all areas gets smaller when pixelsize is > 1.
|
||||
* So in order to avoid missing pixels we just disable de scissors. */
|
||||
if (U.pixelsize <= 1.0f) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
/* It seems that all areas gets smaller when pixelsize is > 1.
|
||||
* So in order to avoid missing pixels we just disable de scissors. */
|
||||
if (U.pixelsize <= 1.0f) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
UI_GetThemeColor4fv(TH_EDITOR_OUTLINE, col);
|
||||
col[3] = 1.0f;
|
||||
corner_scale = U.pixelsize * 8.0f;
|
||||
edge_thickness = corner_scale * 0.21f;
|
||||
UI_GetThemeColor4fv(TH_EDITOR_OUTLINE, col);
|
||||
col[3] = 1.0f;
|
||||
corner_scale = U.pixelsize * 8.0f;
|
||||
edge_thickness = corner_scale * 0.21f;
|
||||
|
||||
GPU_blend(true);
|
||||
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_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);
|
||||
|
||||
GPUBatch *batch = batch_screen_edges_get(&verts_per_corner);
|
||||
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_EDGES);
|
||||
GPU_batch_uniform_1i(batch, "cornerLen", verts_per_corner);
|
||||
GPU_batch_uniform_1f(batch, "scale", corner_scale);
|
||||
GPU_batch_uniform_4fv(batch, "color", col);
|
||||
GPUBatch *batch = batch_screen_edges_get(&verts_per_corner);
|
||||
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_EDGES);
|
||||
GPU_batch_uniform_1i(batch, "cornerLen", verts_per_corner);
|
||||
GPU_batch_uniform_1f(batch, "scale", corner_scale);
|
||||
GPU_batch_uniform_4fv(batch, "color", col);
|
||||
|
||||
for (sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
drawscredge_area(sa, winsize_x, winsize_y, edge_thickness);
|
||||
}
|
||||
for (sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
drawscredge_area(sa, winsize_x, winsize_y, edge_thickness);
|
||||
}
|
||||
|
||||
GPU_blend(false);
|
||||
GPU_blend(false);
|
||||
|
||||
if (U.pixelsize <= 1.0f) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
if (U.pixelsize <= 1.0f) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -439,100 +442,100 @@ void ED_screen_draw_edges(wmWindow *win)
|
||||
*/
|
||||
void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
|
||||
GPU_line_width(1);
|
||||
GPU_line_width(1);
|
||||
|
||||
/* blended join arrow */
|
||||
int dir = area_getorientation(sa1, sa2);
|
||||
int dira = -1;
|
||||
if (dir != -1) {
|
||||
switch (dir) {
|
||||
case 0: /* W */
|
||||
dir = 'r';
|
||||
dira = 'l';
|
||||
break;
|
||||
case 1: /* N */
|
||||
dir = 'd';
|
||||
dira = 'u';
|
||||
break;
|
||||
case 2: /* E */
|
||||
dir = 'l';
|
||||
dira = 'r';
|
||||
break;
|
||||
case 3: /* S */
|
||||
dir = 'u';
|
||||
dira = 'd';
|
||||
break;
|
||||
}
|
||||
/* blended join arrow */
|
||||
int dir = area_getorientation(sa1, sa2);
|
||||
int dira = -1;
|
||||
if (dir != -1) {
|
||||
switch (dir) {
|
||||
case 0: /* W */
|
||||
dir = 'r';
|
||||
dira = 'l';
|
||||
break;
|
||||
case 1: /* N */
|
||||
dir = 'd';
|
||||
dira = 'u';
|
||||
break;
|
||||
case 2: /* E */
|
||||
dir = 'l';
|
||||
dira = 'r';
|
||||
break;
|
||||
case 3: /* S */
|
||||
dir = 'u';
|
||||
dira = 'd';
|
||||
break;
|
||||
}
|
||||
|
||||
GPU_blend(true);
|
||||
GPU_blend(true);
|
||||
|
||||
scrarea_draw_shape_dark(sa2, dir, pos);
|
||||
scrarea_draw_shape_light(sa1, dira, pos);
|
||||
scrarea_draw_shape_dark(sa2, dir, pos);
|
||||
scrarea_draw_shape_light(sa1, dira, pos);
|
||||
|
||||
GPU_blend(false);
|
||||
}
|
||||
GPU_blend(false);
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
|
||||
/* splitpoint */
|
||||
GPU_blend(true);
|
||||
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
|
||||
/* splitpoint */
|
||||
GPU_blend(true);
|
||||
GPU_blend_set_func_separate(
|
||||
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
immUniformColor4ub(255, 255, 255, 100);
|
||||
immUniformColor4ub(255, 255, 255, 100);
|
||||
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
|
||||
if (dir == 'h') {
|
||||
const float y = (1 - fac) * sa->totrct.ymin + fac * sa->totrct.ymax;
|
||||
if (dir == 'h') {
|
||||
const float y = (1 - fac) * sa->totrct.ymin + fac * sa->totrct.ymax;
|
||||
|
||||
immVertex2f(pos, sa->totrct.xmin, y);
|
||||
immVertex2f(pos, sa->totrct.xmax, y);
|
||||
immVertex2f(pos, sa->totrct.xmin, y);
|
||||
immVertex2f(pos, sa->totrct.xmax, y);
|
||||
|
||||
immEnd();
|
||||
immEnd();
|
||||
|
||||
immUniformColor4ub(0, 0, 0, 100);
|
||||
immUniformColor4ub(0, 0, 0, 100);
|
||||
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
|
||||
immVertex2f(pos, sa->totrct.xmin, y + 1);
|
||||
immVertex2f(pos, sa->totrct.xmax, y + 1);
|
||||
immVertex2f(pos, sa->totrct.xmin, y + 1);
|
||||
immVertex2f(pos, sa->totrct.xmax, y + 1);
|
||||
|
||||
immEnd();
|
||||
}
|
||||
else {
|
||||
BLI_assert(dir == 'v');
|
||||
const float x = (1 - fac) * sa->totrct.xmin + fac * sa->totrct.xmax;
|
||||
immEnd();
|
||||
}
|
||||
else {
|
||||
BLI_assert(dir == 'v');
|
||||
const float x = (1 - fac) * sa->totrct.xmin + fac * sa->totrct.xmax;
|
||||
|
||||
immVertex2f(pos, x, sa->totrct.ymin);
|
||||
immVertex2f(pos, x, sa->totrct.ymax);
|
||||
immVertex2f(pos, x, sa->totrct.ymin);
|
||||
immVertex2f(pos, x, sa->totrct.ymax);
|
||||
|
||||
immEnd();
|
||||
immEnd();
|
||||
|
||||
immUniformColor4ub(0, 0, 0, 100);
|
||||
immUniformColor4ub(0, 0, 0, 100);
|
||||
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
|
||||
immVertex2f(pos, x + 1, sa->totrct.ymin);
|
||||
immVertex2f(pos, x + 1, sa->totrct.ymax);
|
||||
immVertex2f(pos, x + 1, sa->totrct.ymin);
|
||||
immVertex2f(pos, x + 1, sa->totrct.ymax);
|
||||
|
||||
immEnd();
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
|
||||
GPU_blend(false);
|
||||
GPU_blend(false);
|
||||
|
||||
immUnbindProgram();
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Screen Thumbnail Preview */
|
||||
|
||||
@@ -540,65 +543,65 @@ void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac)
|
||||
* Calculates a scale factor to squash the preview for \a screen into a rectangle of given size and aspect.
|
||||
*/
|
||||
static void screen_preview_scale_get(
|
||||
const bScreen *screen, float size_x, float size_y,
|
||||
const float asp[2],
|
||||
float r_scale[2])
|
||||
const bScreen *screen, float size_x, float size_y, const float asp[2], float r_scale[2])
|
||||
{
|
||||
float max_x = 0, max_y = 0;
|
||||
float max_x = 0, max_y = 0;
|
||||
|
||||
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
max_x = MAX2(max_x, sa->totrct.xmax);
|
||||
max_y = MAX2(max_y, sa->totrct.ymax);
|
||||
}
|
||||
r_scale[0] = (size_x * asp[0]) / max_x;
|
||||
r_scale[1] = (size_y * asp[1]) / max_y;
|
||||
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
max_x = MAX2(max_x, sa->totrct.xmax);
|
||||
max_y = MAX2(max_y, sa->totrct.ymax);
|
||||
}
|
||||
r_scale[0] = (size_x * asp[0]) / max_x;
|
||||
r_scale[1] = (size_y * asp[1]) / max_y;
|
||||
}
|
||||
|
||||
static void screen_preview_draw_areas(const bScreen *screen, const float scale[2], const float col[4],
|
||||
static void screen_preview_draw_areas(const bScreen *screen,
|
||||
const float scale[2],
|
||||
const float col[4],
|
||||
const float ofs_between_areas)
|
||||
{
|
||||
const float ofs_h = ofs_between_areas * 0.5f;
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
const float ofs_h = ofs_between_areas * 0.5f;
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
immUniformColor4fv(col);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
immUniformColor4fv(col);
|
||||
|
||||
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
rctf rect = {
|
||||
.xmin = sa->totrct.xmin * scale[0] + ofs_h,
|
||||
.xmax = sa->totrct.xmax * scale[0] - ofs_h,
|
||||
.ymin = sa->totrct.ymin * scale[1] + ofs_h,
|
||||
.ymax = sa->totrct.ymax * scale[1] - ofs_h,
|
||||
};
|
||||
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
rctf rect = {
|
||||
.xmin = sa->totrct.xmin * scale[0] + ofs_h,
|
||||
.xmax = sa->totrct.xmax * scale[0] - ofs_h,
|
||||
.ymin = sa->totrct.ymin * scale[1] + ofs_h,
|
||||
.ymax = sa->totrct.ymax * scale[1] - ofs_h,
|
||||
};
|
||||
|
||||
immBegin(GPU_PRIM_TRI_FAN, 4);
|
||||
immVertex2f(pos, rect.xmin, rect.ymin);
|
||||
immVertex2f(pos, rect.xmax, rect.ymin);
|
||||
immVertex2f(pos, rect.xmax, rect.ymax);
|
||||
immVertex2f(pos, rect.xmin, rect.ymax);
|
||||
immEnd();
|
||||
}
|
||||
immBegin(GPU_PRIM_TRI_FAN, 4);
|
||||
immVertex2f(pos, rect.xmin, rect.ymin);
|
||||
immVertex2f(pos, rect.xmax, rect.ymin);
|
||||
immVertex2f(pos, rect.xmax, rect.ymax);
|
||||
immVertex2f(pos, rect.xmin, rect.ymax);
|
||||
immEnd();
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void screen_preview_draw(const bScreen *screen, int size_x, int size_y)
|
||||
{
|
||||
const float asp[2] = {1.0f, 0.8f}; /* square previews look a bit ugly */
|
||||
/* could use theme color (tui.wcol_menu_item.text), but then we'd need to regenerate all previews when changing */
|
||||
const float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
float scale[2];
|
||||
const float asp[2] = {1.0f, 0.8f}; /* square previews look a bit ugly */
|
||||
/* could use theme color (tui.wcol_menu_item.text), but then we'd need to regenerate all previews when changing */
|
||||
const float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
float scale[2];
|
||||
|
||||
wmOrtho2(0.0f, size_x, 0.0f, size_y);
|
||||
/* center */
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_identity_set();
|
||||
GPU_matrix_translate_2f(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f);
|
||||
wmOrtho2(0.0f, size_x, 0.0f, size_y);
|
||||
/* center */
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_identity_set();
|
||||
GPU_matrix_translate_2f(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f);
|
||||
|
||||
screen_preview_scale_get(screen, size_x, size_y, asp, scale);
|
||||
screen_preview_draw_areas(screen, scale, col, 1.5f);
|
||||
screen_preview_scale_get(screen, size_x, size_y, asp, scale);
|
||||
screen_preview_draw_areas(screen, scale, col, 1.5f);
|
||||
|
||||
GPU_matrix_pop();
|
||||
GPU_matrix_pop();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -606,17 +609,17 @@ static void screen_preview_draw(const bScreen *screen, int size_x, int size_y)
|
||||
*/
|
||||
void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, unsigned int *r_rect)
|
||||
{
|
||||
char err_out[256] = "unknown";
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, true, false, err_out);
|
||||
char err_out[256] = "unknown";
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, true, false, err_out);
|
||||
|
||||
GPU_offscreen_bind(offscreen, true);
|
||||
GPU_clear_color(0.0, 0.0, 0.0, 0.0);
|
||||
GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT);
|
||||
GPU_offscreen_bind(offscreen, true);
|
||||
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);
|
||||
screen_preview_draw(screen, size_x, size_y);
|
||||
|
||||
GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect);
|
||||
GPU_offscreen_unbind(offscreen, true);
|
||||
GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect);
|
||||
GPU_offscreen_unbind(offscreen, true);
|
||||
|
||||
GPU_offscreen_free(offscreen);
|
||||
GPU_offscreen_free(offscreen);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,108 +39,108 @@
|
||||
|
||||
#include "screen_intern.h"
|
||||
|
||||
|
||||
int screen_geom_area_height(const ScrArea *area)
|
||||
{
|
||||
return area->v2->vec.y - area->v1->vec.y + 1;
|
||||
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;
|
||||
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;
|
||||
ScrVert *sv = MEM_callocN(sizeof(ScrVert), "addscrvert");
|
||||
sv->vec.x = x;
|
||||
sv->vec.y = y;
|
||||
|
||||
BLI_addtail(&area_map->vertbase, sv);
|
||||
return sv;
|
||||
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);
|
||||
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");
|
||||
ScrEdge *se = MEM_callocN(sizeof(ScrEdge), "addscredge");
|
||||
|
||||
BKE_screen_sort_scrvert(&v1, &v2);
|
||||
se->v1 = v1;
|
||||
se->v2 = v2;
|
||||
BKE_screen_sort_scrvert(&v1, &v2);
|
||||
se->v1 = v1;
|
||||
se->v2 = v2;
|
||||
|
||||
BLI_addtail(&area_map->edgebase, se);
|
||||
return se;
|
||||
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);
|
||||
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);
|
||||
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)
|
||||
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;
|
||||
int safety = U.widget_unit / 10;
|
||||
|
||||
CLAMP_MIN(safety, 2);
|
||||
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);
|
||||
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(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max)
|
||||
return se;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
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)
|
||||
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;
|
||||
/* 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);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,262 +152,261 @@ ScrEdge *screen_geom_find_active_scredge(
|
||||
*/
|
||||
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 */
|
||||
/* 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;
|
||||
rcti window_rect, screen_rect;
|
||||
|
||||
WM_window_rect_calc(win, &window_rect);
|
||||
WM_window_screen_rect_calc(win, &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];
|
||||
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;
|
||||
/* 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;
|
||||
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
|
||||
# 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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
/* 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 (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->temp == 0)
|
||||
continue;
|
||||
|
||||
if (sa->v1 == sa->v2)
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 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
|
||||
# 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... */
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
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 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;
|
||||
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;
|
||||
}
|
||||
// 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);
|
||||
// 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);
|
||||
if (dir == 'h') {
|
||||
y = sa->v1->vec.y + round_fl_to_short(fac * cur_area_height);
|
||||
|
||||
area_min = area_min_y;
|
||||
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 (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;
|
||||
}
|
||||
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);
|
||||
return y;
|
||||
}
|
||||
else {
|
||||
x = sa->v1->vec.x + round_fl_to_short(fac * cur_area_width);
|
||||
|
||||
area_min = area_min_x;
|
||||
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 (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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,44 +414,45 @@ short screen_geom_find_area_split_point(const ScrArea *sa, const rcti *window_re
|
||||
*/
|
||||
void screen_geom_select_connected_edge(const wmWindow *win, ScrEdge *edge)
|
||||
{
|
||||
bScreen *sc = WM_window_get_active_screen(win);
|
||||
bool oneselected = true;
|
||||
char dir;
|
||||
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 */
|
||||
/* 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';
|
||||
}
|
||||
if (edge->v1->vec.x == edge->v2->vec.x) {
|
||||
dir = 'v';
|
||||
}
|
||||
else {
|
||||
dir = 'h';
|
||||
}
|
||||
|
||||
ED_screen_verts_iter(win, sc, sv) {
|
||||
sv->flag = 0;
|
||||
}
|
||||
ED_screen_verts_iter(win, sc, sv)
|
||||
{
|
||||
sv->flag = 0;
|
||||
}
|
||||
|
||||
edge->v1->flag = 1;
|
||||
edge->v2->flag = 1;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,62 +30,69 @@ struct bContextDataResult;
|
||||
|
||||
/* internal exports only */
|
||||
|
||||
#define AZONESPOTW UI_HEADER_OFFSET /* width of corner azone - max */
|
||||
#define AZONESPOTH (0.6f * U.widget_unit) /* height of corner azone */
|
||||
#define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */
|
||||
#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */
|
||||
#define AZONESPOTW UI_HEADER_OFFSET /* width of corner azone - max */
|
||||
#define AZONESPOTH (0.6f * U.widget_unit) /* height of corner azone */
|
||||
#define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */
|
||||
#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */
|
||||
|
||||
/* area.c */
|
||||
void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free);
|
||||
void ED_area_data_swap(ScrArea *sa1, ScrArea *sa2);
|
||||
void region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade);
|
||||
void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free);
|
||||
void ED_area_data_swap(ScrArea *sa1, ScrArea *sa2);
|
||||
void region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade);
|
||||
|
||||
/* screen_edit.c */
|
||||
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(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);
|
||||
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(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);
|
||||
|
||||
struct AZone *ED_area_actionzone_find_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 rcti *bounds_rect,
|
||||
const int mx, const int my);
|
||||
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);
|
||||
|
||||
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 rcti *bounds_rect,
|
||||
const int mx,
|
||||
const int my);
|
||||
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);
|
||||
|
||||
/* screen_context.c */
|
||||
int ed_screen_context(
|
||||
const struct bContext *C, const char *member, struct bContextDataResult *result);
|
||||
int ed_screen_context(const struct bContext *C,
|
||||
const char *member,
|
||||
struct bContextDataResult *result);
|
||||
|
||||
extern const char *screen_context_dir[]; /* doc access */
|
||||
|
||||
/* screendump.c */
|
||||
void SCREEN_OT_screenshot(struct wmOperatorType *ot);
|
||||
void SCREEN_OT_screenshot(struct wmOperatorType *ot);
|
||||
|
||||
/* screen_ops.c */
|
||||
void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar);
|
||||
void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar);
|
||||
|
||||
/* workspace_layout_edit.c */
|
||||
bool workspace_layout_set_poll(const struct WorkSpaceLayout *layout);
|
||||
|
||||
|
||||
#endif /* __SCREEN_INTERN_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -57,29 +57,33 @@
|
||||
|
||||
bUserMenu **ED_screen_user_menus_find(const bContext *C, uint *r_len)
|
||||
{
|
||||
SpaceLink *sl = CTX_wm_space_data(C);
|
||||
const char *context = CTX_data_mode_string(C);
|
||||
SpaceLink *sl = CTX_wm_space_data(C);
|
||||
const char *context = CTX_data_mode_string(C);
|
||||
|
||||
if (sl == NULL) {
|
||||
*r_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (sl == NULL) {
|
||||
*r_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint array_len = 3;
|
||||
bUserMenu **um_array = MEM_calloc_arrayN(array_len, sizeof(*um_array), __func__);
|
||||
um_array[0] = BKE_blender_user_menu_find(&U.user_menus, sl->spacetype, context);
|
||||
um_array[1] = (sl->spacetype != SPACE_TOPBAR) ? BKE_blender_user_menu_find(&U.user_menus, SPACE_TOPBAR, context) : NULL;
|
||||
um_array[2] = (sl->spacetype == SPACE_VIEW3D) ? BKE_blender_user_menu_find(&U.user_menus, SPACE_PROPERTIES, context) : NULL;
|
||||
uint array_len = 3;
|
||||
bUserMenu **um_array = MEM_calloc_arrayN(array_len, sizeof(*um_array), __func__);
|
||||
um_array[0] = BKE_blender_user_menu_find(&U.user_menus, sl->spacetype, context);
|
||||
um_array[1] = (sl->spacetype != SPACE_TOPBAR) ?
|
||||
BKE_blender_user_menu_find(&U.user_menus, SPACE_TOPBAR, context) :
|
||||
NULL;
|
||||
um_array[2] = (sl->spacetype == SPACE_VIEW3D) ?
|
||||
BKE_blender_user_menu_find(&U.user_menus, SPACE_PROPERTIES, context) :
|
||||
NULL;
|
||||
|
||||
*r_len = array_len;
|
||||
return um_array;
|
||||
*r_len = array_len;
|
||||
return um_array;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -88,96 +92,98 @@ bUserMenu *ED_screen_user_menu_ensure(bContext *C)
|
||||
/** \name Menu Item
|
||||
* \{ */
|
||||
|
||||
bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(
|
||||
ListBase *lb,
|
||||
const wmOperatorType *ot, IDProperty *prop, short opcontext)
|
||||
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;
|
||||
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)
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
struct bUserMenuItem_Prop *ED_screen_user_menu_item_find_prop(
|
||||
struct ListBase *lb,
|
||||
const char *context_data_path, const char *prop_id, int prop_index)
|
||||
struct bUserMenuItem_Prop *ED_screen_user_menu_item_find_prop(struct ListBase *lb,
|
||||
const char *context_data_path,
|
||||
const char *prop_id,
|
||||
int prop_index)
|
||||
{
|
||||
for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) {
|
||||
if (umi->type == USER_MENU_TYPE_PROP) {
|
||||
bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi;
|
||||
if (STREQ(context_data_path, umi_pr->context_data_path) &&
|
||||
STREQ(prop_id, umi_pr->prop_id) &&
|
||||
(prop_index == umi_pr->prop_index))
|
||||
{
|
||||
return umi_pr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) {
|
||||
if (umi->type == USER_MENU_TYPE_PROP) {
|
||||
bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi;
|
||||
if (STREQ(context_data_path, umi_pr->context_data_path) && STREQ(prop_id, umi_pr->prop_id) &&
|
||||
(prop_index == umi_pr->prop_index)) {
|
||||
return umi_pr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ED_screen_user_menu_item_add_operator(
|
||||
ListBase *lb, const char *ui_name,
|
||||
const wmOperatorType *ot, const IDProperty *prop, short opcontext)
|
||||
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;
|
||||
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)
|
||||
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);
|
||||
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_add_prop(
|
||||
ListBase *lb, const char *ui_name,
|
||||
const char *context_data_path, const char *prop_id, int prop_index)
|
||||
void ED_screen_user_menu_item_add_prop(ListBase *lb,
|
||||
const char *ui_name,
|
||||
const char *context_data_path,
|
||||
const char *prop_id,
|
||||
int prop_index)
|
||||
{
|
||||
bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_PROP);
|
||||
STRNCPY(umi_pr->item.ui_name, ui_name);
|
||||
STRNCPY(umi_pr->context_data_path, context_data_path);
|
||||
STRNCPY(umi_pr->prop_id, prop_id);
|
||||
umi_pr->prop_index = prop_index;
|
||||
bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)BKE_blender_user_menu_item_add(
|
||||
lb, USER_MENU_TYPE_PROP);
|
||||
STRNCPY(umi_pr->item.ui_name, ui_name);
|
||||
STRNCPY(umi_pr->context_data_path, context_data_path);
|
||||
STRNCPY(umi_pr->prop_id, prop_id);
|
||||
umi_pr->prop_index = prop_index;
|
||||
}
|
||||
|
||||
void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
|
||||
{
|
||||
BLI_remlink(lb, umi);
|
||||
BKE_blender_user_menu_item_free(umi);
|
||||
BLI_remlink(lb, umi);
|
||||
BKE_blender_user_menu_item_free(umi);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -188,95 +194,92 @@ void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
|
||||
|
||||
static void screen_user_menu_draw(const bContext *C, Menu *menu)
|
||||
{
|
||||
uint um_array_len;
|
||||
bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len);
|
||||
bool is_empty = true;
|
||||
for (int um_index = 0; um_index < um_array_len; 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);
|
||||
is_empty = false;
|
||||
}
|
||||
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);
|
||||
is_empty = false;
|
||||
}
|
||||
else if (umi->type == USER_MENU_TYPE_PROP) {
|
||||
bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi;
|
||||
uint um_array_len;
|
||||
bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len);
|
||||
bool is_empty = true;
|
||||
for (int um_index = 0; um_index < um_array_len; 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);
|
||||
is_empty = false;
|
||||
}
|
||||
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);
|
||||
is_empty = false;
|
||||
}
|
||||
else if (umi->type == USER_MENU_TYPE_PROP) {
|
||||
bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi;
|
||||
|
||||
char *data_path = strchr(umi_pr->context_data_path, '.');
|
||||
if (data_path) {
|
||||
*data_path = '\0';
|
||||
}
|
||||
PointerRNA ptr = CTX_data_pointer_get(C, umi_pr->context_data_path);
|
||||
if (ptr.type == NULL) {
|
||||
PointerRNA ctx_ptr;
|
||||
RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr);
|
||||
if (!RNA_path_resolve_full(&ctx_ptr, umi_pr->context_data_path, &ptr, NULL, NULL)) {
|
||||
ptr.type = NULL;
|
||||
}
|
||||
}
|
||||
if (data_path) {
|
||||
*data_path = '.';
|
||||
data_path += 1;
|
||||
}
|
||||
char *data_path = strchr(umi_pr->context_data_path, '.');
|
||||
if (data_path) {
|
||||
*data_path = '\0';
|
||||
}
|
||||
PointerRNA ptr = CTX_data_pointer_get(C, umi_pr->context_data_path);
|
||||
if (ptr.type == NULL) {
|
||||
PointerRNA ctx_ptr;
|
||||
RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr);
|
||||
if (!RNA_path_resolve_full(&ctx_ptr, umi_pr->context_data_path, &ptr, NULL, NULL)) {
|
||||
ptr.type = NULL;
|
||||
}
|
||||
}
|
||||
if (data_path) {
|
||||
*data_path = '.';
|
||||
data_path += 1;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
if (ptr.type != NULL) {
|
||||
PropertyRNA *prop = NULL;
|
||||
PointerRNA prop_ptr = ptr;
|
||||
if ((data_path == NULL) || RNA_path_resolve_full(&ptr, data_path, &prop_ptr, NULL, NULL)) {
|
||||
prop = RNA_struct_find_property(&prop_ptr, umi_pr->prop_id);
|
||||
if (prop) {
|
||||
ok = true;
|
||||
uiItemFullR(
|
||||
menu->layout,
|
||||
&prop_ptr, prop, umi_pr->prop_index,
|
||||
0, 0, ui_name, ICON_NONE);
|
||||
is_empty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
char label[512];
|
||||
SNPRINTF(label, "Missing: %s.%s", umi_pr->context_data_path, umi_pr->prop_id);
|
||||
uiItemL(menu->layout, label, ICON_NONE);
|
||||
}
|
||||
}
|
||||
else if (umi->type == USER_MENU_TYPE_SEP) {
|
||||
uiItemS(menu->layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (um_array) {
|
||||
MEM_freeN(um_array);
|
||||
}
|
||||
bool ok = false;
|
||||
if (ptr.type != NULL) {
|
||||
PropertyRNA *prop = NULL;
|
||||
PointerRNA prop_ptr = ptr;
|
||||
if ((data_path == NULL) ||
|
||||
RNA_path_resolve_full(&ptr, data_path, &prop_ptr, NULL, NULL)) {
|
||||
prop = RNA_struct_find_property(&prop_ptr, umi_pr->prop_id);
|
||||
if (prop) {
|
||||
ok = true;
|
||||
uiItemFullR(
|
||||
menu->layout, &prop_ptr, prop, umi_pr->prop_index, 0, 0, ui_name, ICON_NONE);
|
||||
is_empty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
char label[512];
|
||||
SNPRINTF(label, "Missing: %s.%s", umi_pr->context_data_path, umi_pr->prop_id);
|
||||
uiItemL(menu->layout, label, ICON_NONE);
|
||||
}
|
||||
}
|
||||
else if (umi->type == USER_MENU_TYPE_SEP) {
|
||||
uiItemS(menu->layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (um_array) {
|
||||
MEM_freeN(um_array);
|
||||
}
|
||||
|
||||
if (is_empty) {
|
||||
uiItemL(menu->layout, IFACE_("No menu items found"), ICON_NONE);
|
||||
uiItemL(menu->layout, IFACE_("Right click on buttons to add them to this menu"), ICON_NONE);
|
||||
}
|
||||
if (is_empty) {
|
||||
uiItemL(menu->layout, IFACE_("No menu items found"), ICON_NONE);
|
||||
uiItemL(menu->layout, IFACE_("Right click on buttons to add them to this menu"), ICON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* \ingroup edscr
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -57,239 +56,249 @@
|
||||
#include "screen_intern.h"
|
||||
|
||||
typedef struct ScreenshotData {
|
||||
unsigned int *dumprect;
|
||||
int dumpsx, dumpsy;
|
||||
rcti crop;
|
||||
unsigned int *dumprect;
|
||||
int dumpsx, dumpsy;
|
||||
rcti crop;
|
||||
|
||||
ImageFormatData im_format;
|
||||
ImageFormatData im_format;
|
||||
} ScreenshotData;
|
||||
|
||||
static void screenshot_read_pixels(int x, int y, int w, int h, unsigned char *rect)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
|
||||
glFinish();
|
||||
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
|
||||
glFinish();
|
||||
|
||||
/* clear alpha, it is not set to a meaningful value in opengl */
|
||||
for (i = 0, rect += 3; i < w * h; i++, rect += 4)
|
||||
*rect = 255;
|
||||
/* clear alpha, it is not set to a meaningful value in opengl */
|
||||
for (i = 0, rect += 3; i < w * h; i++, rect += 4)
|
||||
*rect = 255;
|
||||
}
|
||||
|
||||
/* get shot from frontbuffer */
|
||||
static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
int x = 0, y = 0;
|
||||
unsigned int *dumprect = NULL;
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
int x = 0, y = 0;
|
||||
unsigned int *dumprect = NULL;
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
*dumpsx = WM_window_pixels_x(win);
|
||||
*dumpsy = WM_window_pixels_y(win);
|
||||
x = 0;
|
||||
y = 0;
|
||||
*dumpsx = WM_window_pixels_x(win);
|
||||
*dumpsy = WM_window_pixels_y(win);
|
||||
|
||||
if (*dumpsx && *dumpsy) {
|
||||
if (*dumpsx && *dumpsy) {
|
||||
|
||||
dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect");
|
||||
glReadBuffer(GL_FRONT);
|
||||
screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char *)dumprect);
|
||||
glReadBuffer(GL_BACK);
|
||||
}
|
||||
dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect");
|
||||
glReadBuffer(GL_FRONT);
|
||||
screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char *)dumprect);
|
||||
glReadBuffer(GL_BACK);
|
||||
}
|
||||
|
||||
return dumprect;
|
||||
return dumprect;
|
||||
}
|
||||
|
||||
/* call from both exec and invoke */
|
||||
static int screenshot_data_create(bContext *C, wmOperator *op)
|
||||
{
|
||||
unsigned int *dumprect;
|
||||
int dumpsx, dumpsy;
|
||||
unsigned int *dumprect;
|
||||
int dumpsx, dumpsy;
|
||||
|
||||
/* do redraw so we don't show popups/menus */
|
||||
WM_redraw_windows(C);
|
||||
/* do redraw so we don't show popups/menus */
|
||||
WM_redraw_windows(C);
|
||||
|
||||
dumprect = screenshot(C, &dumpsx, &dumpsy);
|
||||
dumprect = screenshot(C, &dumpsx, &dumpsy);
|
||||
|
||||
if (dumprect) {
|
||||
ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot");
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
if (dumprect) {
|
||||
ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot");
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
|
||||
scd->dumpsx = dumpsx;
|
||||
scd->dumpsy = dumpsy;
|
||||
scd->dumprect = dumprect;
|
||||
if (sa) {
|
||||
scd->crop = sa->totrct;
|
||||
}
|
||||
scd->dumpsx = dumpsx;
|
||||
scd->dumpsy = dumpsy;
|
||||
scd->dumprect = dumprect;
|
||||
if (sa) {
|
||||
scd->crop = sa->totrct;
|
||||
}
|
||||
|
||||
BKE_imformat_defaults(&scd->im_format);
|
||||
BKE_imformat_defaults(&scd->im_format);
|
||||
|
||||
op->customdata = scd;
|
||||
op->customdata = scd;
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
op->customdata = NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
op->customdata = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void screenshot_data_free(wmOperator *op)
|
||||
{
|
||||
ScreenshotData *scd = op->customdata;
|
||||
ScreenshotData *scd = op->customdata;
|
||||
|
||||
if (scd) {
|
||||
if (scd->dumprect)
|
||||
MEM_freeN(scd->dumprect);
|
||||
MEM_freeN(scd);
|
||||
op->customdata = NULL;
|
||||
}
|
||||
if (scd) {
|
||||
if (scd->dumprect)
|
||||
MEM_freeN(scd->dumprect);
|
||||
MEM_freeN(scd);
|
||||
op->customdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void screenshot_crop(ImBuf *ibuf, rcti crop)
|
||||
{
|
||||
unsigned int *to = ibuf->rect;
|
||||
unsigned int *from = ibuf->rect + crop.ymin * ibuf->x + crop.xmin;
|
||||
int crop_x = BLI_rcti_size_x(&crop);
|
||||
int crop_y = BLI_rcti_size_y(&crop);
|
||||
int y;
|
||||
unsigned int *to = ibuf->rect;
|
||||
unsigned int *from = ibuf->rect + crop.ymin * ibuf->x + crop.xmin;
|
||||
int crop_x = BLI_rcti_size_x(&crop);
|
||||
int crop_y = BLI_rcti_size_y(&crop);
|
||||
int y;
|
||||
|
||||
if (crop_x > 0 && crop_y > 0) {
|
||||
for (y = 0; y < crop_y; y++, to += crop_x, from += ibuf->x)
|
||||
memmove(to, from, sizeof(unsigned int) * crop_x);
|
||||
if (crop_x > 0 && crop_y > 0) {
|
||||
for (y = 0; y < crop_y; y++, to += crop_x, from += ibuf->x)
|
||||
memmove(to, from, sizeof(unsigned int) * crop_x);
|
||||
|
||||
ibuf->x = crop_x;
|
||||
ibuf->y = crop_y;
|
||||
}
|
||||
ibuf->x = crop_x;
|
||||
ibuf->y = crop_y;
|
||||
}
|
||||
}
|
||||
|
||||
static int screenshot_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
ScreenshotData *scd = op->customdata;
|
||||
bool ok = false;
|
||||
ScreenshotData *scd = op->customdata;
|
||||
bool ok = false;
|
||||
|
||||
if (scd == NULL) {
|
||||
/* when running exec directly */
|
||||
screenshot_data_create(C, op);
|
||||
scd = op->customdata;
|
||||
}
|
||||
if (scd == NULL) {
|
||||
/* when running exec directly */
|
||||
screenshot_data_create(C, op);
|
||||
scd = op->customdata;
|
||||
}
|
||||
|
||||
if (scd) {
|
||||
if (scd->dumprect) {
|
||||
ImBuf *ibuf;
|
||||
char path[FILE_MAX];
|
||||
if (scd) {
|
||||
if (scd->dumprect) {
|
||||
ImBuf *ibuf;
|
||||
char path[FILE_MAX];
|
||||
|
||||
RNA_string_get(op->ptr, "filepath", path);
|
||||
BLI_path_abs(path, BKE_main_blendfile_path_from_global());
|
||||
RNA_string_get(op->ptr, "filepath", path);
|
||||
BLI_path_abs(path, BKE_main_blendfile_path_from_global());
|
||||
|
||||
/* operator ensures the extension */
|
||||
ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0);
|
||||
ibuf->rect = scd->dumprect;
|
||||
/* operator ensures the extension */
|
||||
ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0);
|
||||
ibuf->rect = scd->dumprect;
|
||||
|
||||
/* crop to show only single editor */
|
||||
if (!RNA_boolean_get(op->ptr, "full"))
|
||||
screenshot_crop(ibuf, scd->crop);
|
||||
/* crop to show only single editor */
|
||||
if (!RNA_boolean_get(op->ptr, "full"))
|
||||
screenshot_crop(ibuf, scd->crop);
|
||||
|
||||
if (scd->im_format.planes == R_IMF_PLANES_BW) {
|
||||
/* bw screenshot? - users will notice if it fails! */
|
||||
IMB_color_to_bw(ibuf);
|
||||
}
|
||||
if (BKE_imbuf_write(ibuf, path, &scd->im_format)) {
|
||||
ok = true;
|
||||
}
|
||||
else {
|
||||
BKE_reportf(op->reports, RPT_ERROR, "Could not write image: %s", strerror(errno));
|
||||
}
|
||||
if (scd->im_format.planes == R_IMF_PLANES_BW) {
|
||||
/* bw screenshot? - users will notice if it fails! */
|
||||
IMB_color_to_bw(ibuf);
|
||||
}
|
||||
if (BKE_imbuf_write(ibuf, path, &scd->im_format)) {
|
||||
ok = true;
|
||||
}
|
||||
else {
|
||||
BKE_reportf(op->reports, RPT_ERROR, "Could not write image: %s", strerror(errno));
|
||||
}
|
||||
|
||||
IMB_freeImBuf(ibuf);
|
||||
}
|
||||
}
|
||||
IMB_freeImBuf(ibuf);
|
||||
}
|
||||
}
|
||||
|
||||
screenshot_data_free(op);
|
||||
screenshot_data_free(op);
|
||||
|
||||
return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
||||
return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
if (screenshot_data_create(C, op)) {
|
||||
if (RNA_struct_property_is_set(op->ptr, "filepath"))
|
||||
return screenshot_exec(C, op);
|
||||
if (screenshot_data_create(C, op)) {
|
||||
if (RNA_struct_property_is_set(op->ptr, "filepath"))
|
||||
return screenshot_exec(C, op);
|
||||
|
||||
/* extension is added by 'screenshot_check' after */
|
||||
char filepath[FILE_MAX] = "//screen";
|
||||
if (G.relbase_valid) {
|
||||
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);
|
||||
/* extension is added by 'screenshot_check' after */
|
||||
char filepath[FILE_MAX] = "//screen";
|
||||
if (G.relbase_valid) {
|
||||
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);
|
||||
WM_event_add_fileselect(C, op);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
return OPERATOR_CANCELLED;
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static bool screenshot_check(bContext *UNUSED(C), wmOperator *op)
|
||||
{
|
||||
ScreenshotData *scd = op->customdata;
|
||||
return WM_operator_filesel_ensure_ext_imtype(op, &scd->im_format);
|
||||
ScreenshotData *scd = op->customdata;
|
||||
return WM_operator_filesel_ensure_ext_imtype(op, &scd->im_format);
|
||||
}
|
||||
|
||||
static void screenshot_cancel(bContext *UNUSED(C), wmOperator *op)
|
||||
{
|
||||
screenshot_data_free(op);
|
||||
screenshot_data_free(op);
|
||||
}
|
||||
|
||||
static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
|
||||
static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr),
|
||||
PropertyRNA *prop,
|
||||
void *UNUSED(user_data))
|
||||
{
|
||||
const char *prop_id = RNA_property_identifier(prop);
|
||||
const char *prop_id = RNA_property_identifier(prop);
|
||||
|
||||
return !(STREQ(prop_id, "filepath"));
|
||||
return !(STREQ(prop_id, "filepath"));
|
||||
}
|
||||
|
||||
static void screenshot_draw(bContext *UNUSED(C), wmOperator *op)
|
||||
{
|
||||
uiLayout *layout = op->layout;
|
||||
ScreenshotData *scd = op->customdata;
|
||||
PointerRNA ptr;
|
||||
uiLayout *layout = op->layout;
|
||||
ScreenshotData *scd = op->customdata;
|
||||
PointerRNA ptr;
|
||||
|
||||
/* image template */
|
||||
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &scd->im_format, &ptr);
|
||||
uiTemplateImageSettings(layout, &ptr, false);
|
||||
/* image template */
|
||||
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &scd->im_format, &ptr);
|
||||
uiTemplateImageSettings(layout, &ptr, false);
|
||||
|
||||
/* main draw call */
|
||||
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
|
||||
uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
|
||||
/* main draw call */
|
||||
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
|
||||
uiDefAutoButsRNA(
|
||||
layout, &ptr, screenshot_draw_check_prop, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
|
||||
}
|
||||
|
||||
static bool screenshot_poll(bContext *C)
|
||||
{
|
||||
if (G.background)
|
||||
return false;
|
||||
if (G.background)
|
||||
return false;
|
||||
|
||||
return WM_operator_winactive(C);
|
||||
return WM_operator_winactive(C);
|
||||
}
|
||||
|
||||
void SCREEN_OT_screenshot(wmOperatorType *ot)
|
||||
{
|
||||
/* weak: opname starting with 'save' makes filewindow give save-over */
|
||||
ot->name = "Save Screenshot";
|
||||
ot->idname = "SCREEN_OT_screenshot";
|
||||
ot->description = "Capture a picture of the active area or whole Blender window";
|
||||
/* weak: opname starting with 'save' makes filewindow give save-over */
|
||||
ot->name = "Save Screenshot";
|
||||
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->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;
|
||||
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)");
|
||||
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)");
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
|
||||
#include "screen_intern.h"
|
||||
|
||||
|
||||
/** \name Workspace API
|
||||
*
|
||||
* \brief API for managing workspaces and their data.
|
||||
@@ -75,69 +74,70 @@
|
||||
|
||||
WorkSpace *ED_workspace_add(Main *bmain, const char *name)
|
||||
{
|
||||
return BKE_workspace_add(bmain, name);
|
||||
return BKE_workspace_add(bmain, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the object mode (if needed) to the one set in \a workspace_new.
|
||||
* Object mode is still stored on object level. In future it should all be workspace level instead.
|
||||
*/
|
||||
static void workspace_change_update(
|
||||
WorkSpace *workspace_new, const WorkSpace *workspace_old,
|
||||
bContext *C, wmWindowManager *wm)
|
||||
static void workspace_change_update(WorkSpace *workspace_new,
|
||||
const WorkSpace *workspace_old,
|
||||
bContext *C,
|
||||
wmWindowManager *wm)
|
||||
{
|
||||
/* needs to be done before changing mode! (to ensure right context) */
|
||||
UNUSED_VARS(workspace_old, workspace_new, C, wm);
|
||||
/* needs to be done before changing mode! (to ensure right context) */
|
||||
UNUSED_VARS(workspace_old, workspace_new, C, wm);
|
||||
#if 0
|
||||
Object *ob_act = CTX_data_active_object(C)
|
||||
eObjectMode mode_old = workspace_old->object_mode;
|
||||
eObjectMode mode_new = workspace_new->object_mode;
|
||||
Object *ob_act = CTX_data_active_object(C)
|
||||
eObjectMode mode_old = workspace_old->object_mode;
|
||||
eObjectMode mode_new = workspace_new->object_mode;
|
||||
|
||||
if (mode_old != mode_new) {
|
||||
ED_object_mode_compat_set(C, ob_act, mode_new, &wm->reports);
|
||||
ED_object_mode_toggle(C, mode_new);
|
||||
}
|
||||
if (mode_old != mode_new) {
|
||||
ED_object_mode_compat_set(C, ob_act, mode_new, &wm->reports);
|
||||
ED_object_mode_toggle(C, mode_new);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
|
||||
{
|
||||
/* return false to stop the iterator if we've found a layout that can be activated */
|
||||
return workspace_layout_set_poll(layout) ? false : true;
|
||||
/* return false to stop the iterator if we've found a layout that can be activated */
|
||||
return workspace_layout_set_poll(layout) ? false : true;
|
||||
}
|
||||
|
||||
static WorkSpaceLayout *workspace_change_get_new_layout(
|
||||
Main *bmain, WorkSpace *workspace_new, wmWindow *win)
|
||||
static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain,
|
||||
WorkSpace *workspace_new,
|
||||
wmWindow *win)
|
||||
{
|
||||
/* ED_workspace_duplicate may have stored a layout to activate once the workspace gets activated. */
|
||||
WorkSpaceLayout *layout_old = WM_window_get_active_layout(win);
|
||||
WorkSpaceLayout *layout_new;
|
||||
bScreen *screen_new;
|
||||
/* ED_workspace_duplicate may have stored a layout to activate once the workspace gets activated. */
|
||||
WorkSpaceLayout *layout_old = WM_window_get_active_layout(win);
|
||||
WorkSpaceLayout *layout_new;
|
||||
bScreen *screen_new;
|
||||
|
||||
if (win->workspace_hook->temp_workspace_store) {
|
||||
layout_new = win->workspace_hook->temp_layout_store;
|
||||
}
|
||||
else {
|
||||
layout_new = BKE_workspace_hook_layout_for_workspace_get(win->workspace_hook, workspace_new);
|
||||
if (!layout_new) {
|
||||
layout_new = BKE_workspace_layouts_get(workspace_new)->first;
|
||||
}
|
||||
}
|
||||
screen_new = BKE_workspace_layout_screen_get(layout_new);
|
||||
if (win->workspace_hook->temp_workspace_store) {
|
||||
layout_new = win->workspace_hook->temp_layout_store;
|
||||
}
|
||||
else {
|
||||
layout_new = BKE_workspace_hook_layout_for_workspace_get(win->workspace_hook, workspace_new);
|
||||
if (!layout_new) {
|
||||
layout_new = BKE_workspace_layouts_get(workspace_new)->first;
|
||||
}
|
||||
}
|
||||
screen_new = BKE_workspace_layout_screen_get(layout_new);
|
||||
|
||||
if (screen_new->winid) {
|
||||
/* screen is already used, try to find a free one */
|
||||
WorkSpaceLayout *layout_temp = BKE_workspace_layout_iter_circular(
|
||||
workspace_new, layout_new, workspace_change_find_new_layout_cb,
|
||||
NULL, false);
|
||||
if (!layout_temp) {
|
||||
/* fallback solution: duplicate layout from old workspace */
|
||||
layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win);
|
||||
}
|
||||
layout_new = layout_temp;
|
||||
}
|
||||
if (screen_new->winid) {
|
||||
/* screen is already used, try to find a free one */
|
||||
WorkSpaceLayout *layout_temp = BKE_workspace_layout_iter_circular(
|
||||
workspace_new, layout_new, workspace_change_find_new_layout_cb, NULL, false);
|
||||
if (!layout_temp) {
|
||||
/* fallback solution: duplicate layout from old workspace */
|
||||
layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win);
|
||||
}
|
||||
layout_new = layout_temp;
|
||||
}
|
||||
|
||||
return layout_new;
|
||||
return layout_new;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,464 +149,472 @@ static WorkSpaceLayout *workspace_change_get_new_layout(
|
||||
* \warning Do NOT call in area/region queues!
|
||||
* \returns if workspace changing was successful.
|
||||
*/
|
||||
bool ED_workspace_change(
|
||||
WorkSpace *workspace_new, bContext *C, wmWindowManager *wm, wmWindow *win)
|
||||
bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager *wm, wmWindow *win)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
WorkSpace *workspace_old = WM_window_get_active_workspace(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);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
WorkSpace *workspace_old = WM_window_get_active_workspace(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);
|
||||
|
||||
win->workspace_hook->temp_layout_store = NULL;
|
||||
if (workspace_old == workspace_new) {
|
||||
/* Could also return true, everything that needs to be done was done (nothing :P), but nothing changed */
|
||||
return false;
|
||||
}
|
||||
win->workspace_hook->temp_layout_store = NULL;
|
||||
if (workspace_old == workspace_new) {
|
||||
/* Could also return true, everything that needs to be done was done (nothing :P), but nothing changed */
|
||||
return false;
|
||||
}
|
||||
|
||||
screen_new = screen_change_prepare(screen_old, screen_new, bmain, C, win);
|
||||
BLI_assert(BKE_workspace_layout_screen_get(layout_new) == screen_new);
|
||||
screen_new = screen_change_prepare(screen_old, screen_new, bmain, C, win);
|
||||
BLI_assert(BKE_workspace_layout_screen_get(layout_new) == screen_new);
|
||||
|
||||
if (screen_new == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (screen_new == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BKE_workspace_hook_layout_for_workspace_set(win->workspace_hook, workspace_new, layout_new);
|
||||
BKE_workspace_active_set(win->workspace_hook, workspace_new);
|
||||
BKE_workspace_hook_layout_for_workspace_set(win->workspace_hook, workspace_new, layout_new);
|
||||
BKE_workspace_active_set(win->workspace_hook, workspace_new);
|
||||
|
||||
/* update screen *after* changing workspace - which also causes the
|
||||
* actual screen change and updates context (including CTX_wm_workspace) */
|
||||
screen_change_update(C, win, screen_new);
|
||||
workspace_change_update(workspace_new, workspace_old, C, wm);
|
||||
/* update screen *after* changing workspace - which also causes the
|
||||
* actual screen change and updates context (including CTX_wm_workspace) */
|
||||
screen_change_update(C, win, screen_new);
|
||||
workspace_change_update(workspace_new, workspace_old, C, wm);
|
||||
|
||||
BLI_assert(CTX_wm_workspace(C) == workspace_new);
|
||||
BLI_assert(CTX_wm_workspace(C) == workspace_new);
|
||||
|
||||
WM_toolsystem_unlink_all(C, workspace_old);
|
||||
/* Area initialization will initialize based on the new workspace. */
|
||||
WM_toolsystem_unlink_all(C, workspace_old);
|
||||
/* Area initialization will initialize based on the new workspace. */
|
||||
|
||||
/* Automatic mode switching. */
|
||||
if (workspace_new->object_mode != workspace_old->object_mode) {
|
||||
ED_object_mode_generic_enter(C, workspace_new->object_mode);
|
||||
}
|
||||
/* Automatic mode switching. */
|
||||
if (workspace_new->object_mode != workspace_old->object_mode) {
|
||||
ED_object_mode_generic_enter(C, workspace_new->object_mode);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a workspace including its layouts. Does not activate the workspace, but
|
||||
* it stores the screen-layout to be activated (BKE_workspace_temp_layout_store)
|
||||
*/
|
||||
WorkSpace *ED_workspace_duplicate(
|
||||
WorkSpace *workspace_old, Main *bmain, wmWindow *win)
|
||||
WorkSpace *ED_workspace_duplicate(WorkSpace *workspace_old, Main *bmain, wmWindow *win)
|
||||
{
|
||||
WorkSpaceLayout *layout_active_old = BKE_workspace_active_layout_get(win->workspace_hook);
|
||||
ListBase *layouts_old = BKE_workspace_layouts_get(workspace_old);
|
||||
WorkSpace *workspace_new = ED_workspace_add(bmain, workspace_old->id.name + 2);
|
||||
WorkSpaceLayout *layout_active_old = BKE_workspace_active_layout_get(win->workspace_hook);
|
||||
ListBase *layouts_old = BKE_workspace_layouts_get(workspace_old);
|
||||
WorkSpace *workspace_new = ED_workspace_add(bmain, workspace_old->id.name + 2);
|
||||
|
||||
workspace_new->flags = workspace_old->flags;
|
||||
BLI_duplicatelist(&workspace_new->owner_ids, &workspace_old->owner_ids);
|
||||
workspace_new->flags = workspace_old->flags;
|
||||
BLI_duplicatelist(&workspace_new->owner_ids, &workspace_old->owner_ids);
|
||||
|
||||
/* TODO(campbell): tools */
|
||||
/* TODO(campbell): tools */
|
||||
|
||||
for (WorkSpaceLayout *layout_old = layouts_old->first; layout_old; layout_old = layout_old->next) {
|
||||
WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win);
|
||||
for (WorkSpaceLayout *layout_old = layouts_old->first; layout_old;
|
||||
layout_old = layout_old->next) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
return workspace_new;
|
||||
if (layout_active_old == layout_old) {
|
||||
win->workspace_hook->temp_layout_store = layout_new;
|
||||
}
|
||||
}
|
||||
return workspace_new;
|
||||
}
|
||||
|
||||
/**
|
||||
* \return if succeeded.
|
||||
*/
|
||||
bool ED_workspace_delete(
|
||||
WorkSpace *workspace, Main *bmain, bContext *C, wmWindowManager *wm)
|
||||
bool ED_workspace_delete(WorkSpace *workspace, Main *bmain, bContext *C, wmWindowManager *wm)
|
||||
{
|
||||
if (BLI_listbase_is_single(&bmain->workspaces)) {
|
||||
return false;
|
||||
}
|
||||
if (BLI_listbase_is_single(&bmain->workspaces)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ListBase ordered;
|
||||
BKE_id_ordered_list(&ordered, &bmain->workspaces);
|
||||
WorkSpace *prev = NULL, *next = NULL;
|
||||
for (LinkData *link = ordered.first; link; link = link->next) {
|
||||
if (link->data == workspace) {
|
||||
prev = link->prev ? link->prev->data : NULL;
|
||||
next = link->next ? link->next->data : NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_freelistN(&ordered);
|
||||
BLI_assert((prev != NULL) || (next != NULL));
|
||||
ListBase ordered;
|
||||
BKE_id_ordered_list(&ordered, &bmain->workspaces);
|
||||
WorkSpace *prev = NULL, *next = NULL;
|
||||
for (LinkData *link = ordered.first; link; link = link->next) {
|
||||
if (link->data == workspace) {
|
||||
prev = link->prev ? link->prev->data : NULL;
|
||||
next = link->next ? link->next->data : NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_freelistN(&ordered);
|
||||
BLI_assert((prev != NULL) || (next != NULL));
|
||||
|
||||
for (wmWindow *win = wm->windows.first; win; win = win->next) {
|
||||
WorkSpace *workspace_active = WM_window_get_active_workspace(win);
|
||||
if (workspace_active == workspace) {
|
||||
ED_workspace_change((prev != NULL) ? prev : next, C, wm, win);
|
||||
}
|
||||
}
|
||||
for (wmWindow *win = wm->windows.first; win; win = win->next) {
|
||||
WorkSpace *workspace_active = WM_window_get_active_workspace(win);
|
||||
if (workspace_active == workspace) {
|
||||
ED_workspace_change((prev != NULL) ? prev : next, C, wm, win);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_id_free(bmain, &workspace->id);
|
||||
return true;
|
||||
BKE_id_free(bmain, &workspace->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some editor data may need to be synced with scene data (3D View camera and layers).
|
||||
* This function ensures data is synced for editors in active layout of \a workspace.
|
||||
*/
|
||||
void ED_workspace_scene_data_sync(
|
||||
WorkSpaceInstanceHook *hook, Scene *scene)
|
||||
void ED_workspace_scene_data_sync(WorkSpaceInstanceHook *hook, Scene *scene)
|
||||
{
|
||||
bScreen *screen = BKE_workspace_active_screen_get(hook);
|
||||
BKE_screen_view3d_scene_sync(screen, scene);
|
||||
bScreen *screen = BKE_workspace_active_screen_get(hook);
|
||||
BKE_screen_view3d_scene_sync(screen, scene);
|
||||
}
|
||||
|
||||
/** \} Workspace API */
|
||||
|
||||
|
||||
/** \name Workspace Operators
|
||||
*
|
||||
* \{ */
|
||||
|
||||
static WorkSpace *workspace_context_get(bContext *C)
|
||||
{
|
||||
ID *id = UI_context_active_but_get_tab_ID(C);
|
||||
if (id && GS(id->name) == ID_WS) {
|
||||
return (WorkSpace *)id;
|
||||
}
|
||||
ID *id = UI_context_active_but_get_tab_ID(C);
|
||||
if (id && GS(id->name) == ID_WS) {
|
||||
return (WorkSpace *)id;
|
||||
}
|
||||
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
return WM_window_get_active_workspace(win);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
return WM_window_get_active_workspace(win);
|
||||
}
|
||||
|
||||
static bool workspace_context_poll(bContext *C)
|
||||
{
|
||||
return workspace_context_get(C) != NULL;
|
||||
return workspace_context_get(C) != NULL;
|
||||
}
|
||||
|
||||
static int workspace_new_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
WorkSpace *workspace = workspace_context_get(C);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
WorkSpace *workspace = workspace_context_get(C);
|
||||
|
||||
workspace = ED_workspace_duplicate(workspace, bmain, win);
|
||||
workspace = ED_workspace_duplicate(workspace, bmain, win);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace);
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void WORKSPACE_OT_duplicate(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "New Workspace";
|
||||
ot->description = "Add a new workspace";
|
||||
ot->idname = "WORKSPACE_OT_duplicate";
|
||||
/* identifiers */
|
||||
ot->name = "New Workspace";
|
||||
ot->description = "Add a new workspace";
|
||||
ot->idname = "WORKSPACE_OT_duplicate";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = workspace_context_poll;
|
||||
ot->exec = workspace_new_exec;
|
||||
/* api callbacks */
|
||||
ot->poll = workspace_context_poll;
|
||||
ot->exec = workspace_new_exec;
|
||||
}
|
||||
|
||||
static int workspace_delete_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
WorkSpace *workspace = workspace_context_get(C);
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_DELETE, workspace);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
WorkSpace *workspace = workspace_context_get(C);
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_DELETE, workspace);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void WORKSPACE_OT_delete(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Delete Workspace";
|
||||
ot->description = "Delete the active workspace";
|
||||
ot->idname = "WORKSPACE_OT_delete";
|
||||
/* identifiers */
|
||||
ot->name = "Delete Workspace";
|
||||
ot->description = "Delete the active workspace";
|
||||
ot->idname = "WORKSPACE_OT_delete";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = workspace_context_poll;
|
||||
ot->exec = workspace_delete_exec;
|
||||
/* api callbacks */
|
||||
ot->poll = workspace_context_poll;
|
||||
ot->exec = workspace_delete_exec;
|
||||
}
|
||||
|
||||
static bool workspace_append_activate_poll(bContext *C)
|
||||
{
|
||||
wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false);
|
||||
return WM_operator_poll(C, ot);
|
||||
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);
|
||||
PointerRNA opptr;
|
||||
int retval;
|
||||
wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false);
|
||||
PointerRNA opptr;
|
||||
int retval;
|
||||
|
||||
WM_operator_properties_create_ptr(&opptr, ot);
|
||||
RNA_string_set(&opptr, "directory", directory);
|
||||
RNA_string_set(&opptr, "filename", idname);
|
||||
RNA_boolean_set(&opptr, "autoselect", false);
|
||||
WM_operator_properties_create_ptr(&opptr, ot);
|
||||
RNA_string_set(&opptr, "directory", directory);
|
||||
RNA_string_set(&opptr, "filename", idname);
|
||||
RNA_boolean_set(&opptr, "autoselect", false);
|
||||
|
||||
retval = WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &opptr);
|
||||
retval = WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &opptr);
|
||||
|
||||
WM_operator_properties_free(&opptr);
|
||||
WM_operator_properties_free(&opptr);
|
||||
|
||||
return retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int workspace_append_activate_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
char idname[MAX_ID_NAME - 2], filepath[FILE_MAX];
|
||||
Main *bmain = CTX_data_main(C);
|
||||
char idname[MAX_ID_NAME - 2], filepath[FILE_MAX];
|
||||
|
||||
if (!RNA_struct_property_is_set(op->ptr, "idname") ||
|
||||
!RNA_struct_property_is_set(op->ptr, "filepath"))
|
||||
{
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
RNA_string_get(op->ptr, "idname", idname);
|
||||
RNA_string_get(op->ptr, "filepath", filepath);
|
||||
if (!RNA_struct_property_is_set(op->ptr, "idname") ||
|
||||
!RNA_struct_property_is_set(op->ptr, "filepath")) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
RNA_string_get(op->ptr, "idname", idname);
|
||||
RNA_string_get(op->ptr, "filepath", filepath);
|
||||
|
||||
if (workspace_append(C, filepath, idname) != OPERATOR_CANCELLED) {
|
||||
WorkSpace *appended_workspace = BLI_findstring(&bmain->workspaces, idname, offsetof(ID, name) + 2);
|
||||
BLI_assert(appended_workspace != NULL);
|
||||
if (workspace_append(C, filepath, idname) != OPERATOR_CANCELLED) {
|
||||
WorkSpace *appended_workspace = BLI_findstring(
|
||||
&bmain->workspaces, idname, offsetof(ID, name) + 2);
|
||||
BLI_assert(appended_workspace != NULL);
|
||||
|
||||
/* Reorder to last position. */
|
||||
BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, NULL, true);
|
||||
/* Reorder to last position. */
|
||||
BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, NULL, true);
|
||||
|
||||
/* Changing workspace changes context. Do delayed! */
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace);
|
||||
/* Changing workspace changes context. Do delayed! */
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static void WORKSPACE_OT_append_activate(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Append and Activate Workspace";
|
||||
ot->description = "Append a workspace and make it the active one in the current window";
|
||||
ot->idname = "WORKSPACE_OT_append_activate";
|
||||
/* identifiers */
|
||||
ot->name = "Append and Activate Workspace";
|
||||
ot->description = "Append a workspace and make it the active one in the current window";
|
||||
ot->idname = "WORKSPACE_OT_append_activate";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = workspace_append_activate_exec;
|
||||
ot->poll = workspace_append_activate_poll;
|
||||
/* 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");
|
||||
RNA_def_string(ot->srna, "filepath", NULL, FILE_MAX, "Filepath",
|
||||
"Path to the library");
|
||||
RNA_def_string(ot->srna,
|
||||
"idname",
|
||||
NULL,
|
||||
MAX_ID_NAME - 2,
|
||||
"Identifier",
|
||||
"Name of the workspace to append and activate");
|
||||
RNA_def_string(ot->srna, "filepath", NULL, FILE_MAX, "Filepath", "Path to the library");
|
||||
}
|
||||
|
||||
static WorkspaceConfigFileData *workspace_config_file_read(const char *app_template)
|
||||
{
|
||||
const char *cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, app_template);
|
||||
char startup_file_path[FILE_MAX] = {0};
|
||||
const char *cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, app_template);
|
||||
char startup_file_path[FILE_MAX] = {0};
|
||||
|
||||
if (cfgdir) {
|
||||
BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), cfgdir, BLENDER_STARTUP_FILE);
|
||||
}
|
||||
if (cfgdir) {
|
||||
BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), cfgdir, BLENDER_STARTUP_FILE);
|
||||
}
|
||||
|
||||
bool has_path = BLI_exists(startup_file_path);
|
||||
return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL;
|
||||
bool has_path = BLI_exists(startup_file_path);
|
||||
return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL;
|
||||
}
|
||||
|
||||
static WorkspaceConfigFileData *workspace_system_file_read(const char *app_template)
|
||||
{
|
||||
if (app_template == NULL) {
|
||||
return BKE_blendfile_workspace_config_read(NULL, datatoc_startup_blend, datatoc_startup_blend_size, NULL);
|
||||
}
|
||||
if (app_template == NULL) {
|
||||
return BKE_blendfile_workspace_config_read(
|
||||
NULL, datatoc_startup_blend, datatoc_startup_blend_size, NULL);
|
||||
}
|
||||
|
||||
char template_dir[FILE_MAX];
|
||||
if (!BKE_appdir_app_template_id_search(app_template, template_dir, sizeof(template_dir))) {
|
||||
return NULL;
|
||||
}
|
||||
char template_dir[FILE_MAX];
|
||||
if (!BKE_appdir_app_template_id_search(app_template, template_dir, sizeof(template_dir))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char startup_file_path[FILE_MAX];
|
||||
BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), template_dir, BLENDER_STARTUP_FILE);
|
||||
char startup_file_path[FILE_MAX];
|
||||
BLI_join_dirfile(
|
||||
startup_file_path, sizeof(startup_file_path), template_dir, BLENDER_STARTUP_FILE);
|
||||
|
||||
bool has_path = BLI_exists(startup_file_path);
|
||||
return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL;
|
||||
bool has_path = BLI_exists(startup_file_path);
|
||||
return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL;
|
||||
}
|
||||
|
||||
static void workspace_append_button(
|
||||
uiLayout *layout, wmOperatorType *ot_append, const WorkSpace *workspace, const Main *from_main)
|
||||
static void workspace_append_button(uiLayout *layout,
|
||||
wmOperatorType *ot_append,
|
||||
const WorkSpace *workspace,
|
||||
const Main *from_main)
|
||||
{
|
||||
const ID *id = (ID *)workspace;
|
||||
PointerRNA opptr;
|
||||
char lib_path[FILE_MAX_LIBEXTRA];
|
||||
const char *filepath = from_main->name;
|
||||
const ID *id = (ID *)workspace;
|
||||
PointerRNA opptr;
|
||||
char lib_path[FILE_MAX_LIBEXTRA];
|
||||
const char *filepath = from_main->name;
|
||||
|
||||
if (strlen(filepath) == 0) {
|
||||
filepath = BLO_EMBEDDED_STARTUP_BLEND;
|
||||
}
|
||||
if (strlen(filepath) == 0) {
|
||||
filepath = BLO_EMBEDDED_STARTUP_BLEND;
|
||||
}
|
||||
|
||||
BLI_path_join(
|
||||
lib_path, sizeof(lib_path), filepath, BKE_idcode_to_name(GS(id->name)), NULL);
|
||||
BLI_path_join(lib_path, sizeof(lib_path), filepath, BKE_idcode_to_name(GS(id->name)), NULL);
|
||||
|
||||
BLI_assert(STREQ(ot_append->idname, "WORKSPACE_OT_append_activate"));
|
||||
uiItemFullO_ptr(
|
||||
layout, ot_append, workspace->id.name + 2, ICON_NONE, NULL,
|
||||
WM_OP_EXEC_DEFAULT, 0, &opptr);
|
||||
RNA_string_set(&opptr, "idname", id->name + 2);
|
||||
RNA_string_set(&opptr, "filepath", lib_path);
|
||||
BLI_assert(STREQ(ot_append->idname, "WORKSPACE_OT_append_activate"));
|
||||
uiItemFullO_ptr(
|
||||
layout, ot_append, workspace->id.name + 2, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
|
||||
RNA_string_set(&opptr, "idname", id->name + 2);
|
||||
RNA_string_set(&opptr, "filepath", lib_path);
|
||||
}
|
||||
|
||||
static void workspace_add_menu(bContext *C, uiLayout *layout, void *template_v)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
const char *app_template = template_v;
|
||||
bool has_startup_items = false;
|
||||
Main *bmain = CTX_data_main(C);
|
||||
const char *app_template = template_v;
|
||||
bool has_startup_items = false;
|
||||
|
||||
wmOperatorType *ot_append = WM_operatortype_find("WORKSPACE_OT_append_activate", true);
|
||||
WorkspaceConfigFileData *startup_config = workspace_config_file_read(app_template);
|
||||
WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template);
|
||||
wmOperatorType *ot_append = WM_operatortype_find("WORKSPACE_OT_append_activate", true);
|
||||
WorkspaceConfigFileData *startup_config = workspace_config_file_read(app_template);
|
||||
WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template);
|
||||
|
||||
if (startup_config) {
|
||||
for (WorkSpace *workspace = startup_config->workspaces.first; workspace; workspace = workspace->id.next) {
|
||||
uiLayout *row = uiLayoutRow(layout, false);
|
||||
if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) {
|
||||
uiLayoutSetActive(row, false);
|
||||
}
|
||||
if (startup_config) {
|
||||
for (WorkSpace *workspace = startup_config->workspaces.first; workspace;
|
||||
workspace = workspace->id.next) {
|
||||
uiLayout *row = uiLayoutRow(layout, false);
|
||||
if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) {
|
||||
uiLayoutSetActive(row, false);
|
||||
}
|
||||
|
||||
workspace_append_button(row, ot_append, workspace, startup_config->main);
|
||||
has_startup_items = true;
|
||||
}
|
||||
}
|
||||
workspace_append_button(row, ot_append, workspace, startup_config->main);
|
||||
has_startup_items = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (builtin_config) {
|
||||
bool has_title = false;
|
||||
if (builtin_config) {
|
||||
bool has_title = false;
|
||||
|
||||
for (WorkSpace *workspace = builtin_config->workspaces.first; workspace; workspace = workspace->id.next) {
|
||||
if (startup_config && BLI_findstring(&startup_config->workspaces, workspace->id.name, offsetof(ID, name))) {
|
||||
continue;
|
||||
}
|
||||
for (WorkSpace *workspace = builtin_config->workspaces.first; workspace;
|
||||
workspace = workspace->id.next) {
|
||||
if (startup_config &&
|
||||
BLI_findstring(&startup_config->workspaces, workspace->id.name, offsetof(ID, name))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!has_title) {
|
||||
if (has_startup_items) {
|
||||
uiItemS(layout);
|
||||
}
|
||||
has_title = true;
|
||||
}
|
||||
if (!has_title) {
|
||||
if (has_startup_items) {
|
||||
uiItemS(layout);
|
||||
}
|
||||
has_title = true;
|
||||
}
|
||||
|
||||
uiLayout *row = uiLayoutRow(layout, false);
|
||||
if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) {
|
||||
uiLayoutSetActive(row, false);
|
||||
}
|
||||
uiLayout *row = uiLayoutRow(layout, false);
|
||||
if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) {
|
||||
uiLayoutSetActive(row, false);
|
||||
}
|
||||
|
||||
workspace_append_button(row, ot_append, workspace, builtin_config->main);
|
||||
}
|
||||
}
|
||||
workspace_append_button(row, ot_append, workspace, builtin_config->main);
|
||||
}
|
||||
}
|
||||
|
||||
if (startup_config) {
|
||||
BKE_blendfile_workspace_config_data_free(startup_config);
|
||||
}
|
||||
if (builtin_config) {
|
||||
BKE_blendfile_workspace_config_data_free(builtin_config);
|
||||
}
|
||||
if (startup_config) {
|
||||
BKE_blendfile_workspace_config_data_free(startup_config);
|
||||
}
|
||||
if (builtin_config) {
|
||||
BKE_blendfile_workspace_config_data_free(builtin_config);
|
||||
}
|
||||
}
|
||||
|
||||
static int workspace_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
uiPopupMenu *pup = UI_popup_menu_begin(C, op->type->name, ICON_ADD);
|
||||
uiLayout *layout = UI_popup_menu_layout(pup);
|
||||
uiPopupMenu *pup = UI_popup_menu_begin(C, op->type->name, ICON_ADD);
|
||||
uiLayout *layout = UI_popup_menu_layout(pup);
|
||||
|
||||
uiItemMenuF(layout, IFACE_("General"), ICON_NONE, workspace_add_menu, NULL);
|
||||
uiItemMenuF(layout, IFACE_("General"), ICON_NONE, workspace_add_menu, NULL);
|
||||
|
||||
ListBase templates;
|
||||
BKE_appdir_app_templates(&templates);
|
||||
ListBase templates;
|
||||
BKE_appdir_app_templates(&templates);
|
||||
|
||||
for (LinkData *link = templates.first; link; link = link->next) {
|
||||
char *template = link->data;
|
||||
char display_name[FILE_MAX];
|
||||
for (LinkData *link = templates.first; link; link = link->next) {
|
||||
char *template = link->data;
|
||||
char display_name[FILE_MAX];
|
||||
|
||||
BLI_path_to_display_name(display_name, sizeof(display_name), template);
|
||||
BLI_path_to_display_name(display_name, sizeof(display_name), template);
|
||||
|
||||
/* Steals ownership of link data string. */
|
||||
uiItemMenuFN(layout, display_name, ICON_NONE, workspace_add_menu, template);
|
||||
}
|
||||
/* Steals ownership of link data string. */
|
||||
uiItemMenuFN(layout, display_name, ICON_NONE, workspace_add_menu, template);
|
||||
}
|
||||
|
||||
BLI_freelistN(&templates);
|
||||
BLI_freelistN(&templates);
|
||||
|
||||
uiItemS(layout);
|
||||
uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Duplicate Current"), ICON_DUPLICATE,
|
||||
"WORKSPACE_OT_duplicate");
|
||||
uiItemS(layout);
|
||||
uiItemO(layout,
|
||||
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Duplicate Current"),
|
||||
ICON_DUPLICATE,
|
||||
"WORKSPACE_OT_duplicate");
|
||||
|
||||
UI_popup_menu_end(C, pup);
|
||||
UI_popup_menu_end(C, pup);
|
||||
|
||||
return OPERATOR_INTERFACE;
|
||||
return OPERATOR_INTERFACE;
|
||||
}
|
||||
|
||||
static void WORKSPACE_OT_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Workspace";
|
||||
ot->description = "Add a new workspace by duplicating the current one or appending one "
|
||||
"from the user configuration";
|
||||
ot->idname = "WORKSPACE_OT_add";
|
||||
/* identifiers */
|
||||
ot->name = "Add Workspace";
|
||||
ot->description =
|
||||
"Add a new workspace by duplicating the current one or appending one "
|
||||
"from the user configuration";
|
||||
ot->idname = "WORKSPACE_OT_add";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = workspace_add_invoke;
|
||||
/* api callbacks */
|
||||
ot->invoke = workspace_add_invoke;
|
||||
}
|
||||
|
||||
static int workspace_reorder_to_back_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
WorkSpace *workspace = workspace_context_get(C);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
WorkSpace *workspace = workspace_context_get(C);
|
||||
|
||||
BKE_id_reorder(&bmain->workspaces, &workspace->id, NULL, true);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
BKE_id_reorder(&bmain->workspaces, &workspace->id, NULL, true);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
|
||||
return OPERATOR_INTERFACE;
|
||||
return OPERATOR_INTERFACE;
|
||||
}
|
||||
|
||||
static void WORKSPACE_OT_reorder_to_back(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Workspace Reorder to Back";
|
||||
ot->description = "Reorder workspace to be first in the list";
|
||||
ot->idname = "WORKSPACE_OT_reorder_to_back";
|
||||
/* identifiers */
|
||||
ot->name = "Workspace Reorder to Back";
|
||||
ot->description = "Reorder workspace to be first in the list";
|
||||
ot->idname = "WORKSPACE_OT_reorder_to_back";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = workspace_context_poll;
|
||||
ot->exec = workspace_reorder_to_back_exec;
|
||||
/* api callbacks */
|
||||
ot->poll = workspace_context_poll;
|
||||
ot->exec = workspace_reorder_to_back_exec;
|
||||
}
|
||||
|
||||
static int workspace_reorder_to_front_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
WorkSpace *workspace = workspace_context_get(C);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
WorkSpace *workspace = workspace_context_get(C);
|
||||
|
||||
BKE_id_reorder(&bmain->workspaces, &workspace->id, NULL, false);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
BKE_id_reorder(&bmain->workspaces, &workspace->id, NULL, false);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
|
||||
return OPERATOR_INTERFACE;
|
||||
return OPERATOR_INTERFACE;
|
||||
}
|
||||
|
||||
static void WORKSPACE_OT_reorder_to_front(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Workspace Reorder to Front";
|
||||
ot->description = "Reorder workspace to be first in the list";
|
||||
ot->idname = "WORKSPACE_OT_reorder_to_front";
|
||||
/* identifiers */
|
||||
ot->name = "Workspace Reorder to Front";
|
||||
ot->description = "Reorder workspace to be first in the list";
|
||||
ot->idname = "WORKSPACE_OT_reorder_to_front";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = workspace_context_poll;
|
||||
ot->exec = workspace_reorder_to_front_exec;
|
||||
/* api callbacks */
|
||||
ot->poll = workspace_context_poll;
|
||||
ot->exec = workspace_reorder_to_front_exec;
|
||||
}
|
||||
|
||||
void ED_operatortypes_workspace(void)
|
||||
{
|
||||
WM_operatortype_append(WORKSPACE_OT_duplicate);
|
||||
WM_operatortype_append(WORKSPACE_OT_delete);
|
||||
WM_operatortype_append(WORKSPACE_OT_add);
|
||||
WM_operatortype_append(WORKSPACE_OT_append_activate);
|
||||
WM_operatortype_append(WORKSPACE_OT_reorder_to_back);
|
||||
WM_operatortype_append(WORKSPACE_OT_reorder_to_front);
|
||||
WM_operatortype_append(WORKSPACE_OT_duplicate);
|
||||
WM_operatortype_append(WORKSPACE_OT_delete);
|
||||
WM_operatortype_append(WORKSPACE_OT_add);
|
||||
WM_operatortype_append(WORKSPACE_OT_append_activate);
|
||||
WM_operatortype_append(WORKSPACE_OT_reorder_to_back);
|
||||
WM_operatortype_append(WORKSPACE_OT_reorder_to_front);
|
||||
}
|
||||
|
||||
/** \} Workspace Operators */
|
||||
|
||||
@@ -40,164 +40,163 @@
|
||||
/**
|
||||
* 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)
|
||||
WorkSpaceLayout *ED_workspace_layout_add(Main *bmain,
|
||||
WorkSpace *workspace,
|
||||
wmWindow *win,
|
||||
const char *name)
|
||||
{
|
||||
bScreen *screen;
|
||||
rcti screen_rect;
|
||||
bScreen *screen;
|
||||
rcti screen_rect;
|
||||
|
||||
WM_window_screen_rect_calc(win, &screen_rect);
|
||||
screen = screen_add(bmain, name, &screen_rect);
|
||||
WM_window_screen_rect_calc(win, &screen_rect);
|
||||
screen = screen_add(bmain, name, &screen_rect);
|
||||
|
||||
return BKE_workspace_layout_add(bmain, workspace, screen, name);
|
||||
return BKE_workspace_layout_add(bmain, workspace, screen, name);
|
||||
}
|
||||
|
||||
WorkSpaceLayout *ED_workspace_layout_duplicate(
|
||||
Main *bmain,
|
||||
WorkSpace *workspace, const WorkSpaceLayout *layout_old,
|
||||
wmWindow *win)
|
||||
WorkSpaceLayout *ED_workspace_layout_duplicate(Main *bmain,
|
||||
WorkSpace *workspace,
|
||||
const WorkSpaceLayout *layout_old,
|
||||
wmWindow *win)
|
||||
{
|
||||
bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old);
|
||||
const char *name = BKE_workspace_layout_name_get(layout_old);
|
||||
bScreen *screen_new;
|
||||
WorkSpaceLayout *layout_new;
|
||||
bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old);
|
||||
const char *name = BKE_workspace_layout_name_get(layout_old);
|
||||
bScreen *screen_new;
|
||||
WorkSpaceLayout *layout_new;
|
||||
|
||||
layout_new = ED_workspace_layout_add(bmain, workspace, win, name);
|
||||
screen_new = BKE_workspace_layout_screen_get(layout_new);
|
||||
layout_new = ED_workspace_layout_add(bmain, workspace, win, name);
|
||||
screen_new = BKE_workspace_layout_screen_get(layout_new);
|
||||
|
||||
if (BKE_screen_is_fullscreen_area(screen_old)) {
|
||||
for (ScrArea *area_old = screen_old->areabase.first; area_old; area_old = area_old->next) {
|
||||
if (area_old->full) {
|
||||
ScrArea *area_new = (ScrArea *)screen_new->areabase.first;
|
||||
ED_area_data_copy(area_new, area_old, true);
|
||||
ED_area_tag_redraw(area_new);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
screen_data_copy(screen_new, screen_old);
|
||||
}
|
||||
if (BKE_screen_is_fullscreen_area(screen_old)) {
|
||||
for (ScrArea *area_old = screen_old->areabase.first; area_old; area_old = area_old->next) {
|
||||
if (area_old->full) {
|
||||
ScrArea *area_new = (ScrArea *)screen_new->areabase.first;
|
||||
ED_area_data_copy(area_new, area_old, true);
|
||||
ED_area_tag_redraw(area_new);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
screen_data_copy(screen_new, screen_old);
|
||||
}
|
||||
|
||||
return layout_new;
|
||||
return layout_new;
|
||||
}
|
||||
|
||||
static bool workspace_layout_delete_doit(
|
||||
WorkSpace *workspace, WorkSpaceLayout *layout_old, WorkSpaceLayout *layout_new,
|
||||
bContext *C)
|
||||
static bool workspace_layout_delete_doit(WorkSpace *workspace,
|
||||
WorkSpaceLayout *layout_old,
|
||||
WorkSpaceLayout *layout_new,
|
||||
bContext *C)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new);
|
||||
|
||||
ED_screen_change(C, screen_new);
|
||||
ED_screen_change(C, screen_new);
|
||||
|
||||
if (BKE_workspace_active_layout_get(win->workspace_hook) != layout_old) {
|
||||
BKE_workspace_layout_remove(bmain, workspace, layout_old);
|
||||
return true;
|
||||
}
|
||||
if (BKE_workspace_active_layout_get(win->workspace_hook) != layout_old) {
|
||||
BKE_workspace_layout_remove(bmain, workspace, layout_old);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool workspace_layout_set_poll(const WorkSpaceLayout *layout)
|
||||
{
|
||||
const bScreen *screen = BKE_workspace_layout_screen_get(layout);
|
||||
const bScreen *screen = BKE_workspace_layout_screen_get(layout);
|
||||
|
||||
return ((BKE_screen_is_used(screen) == false) &&
|
||||
/* in typical usage temp screens should have a nonzero winid
|
||||
* (all temp screens should be used, or closed & freed). */
|
||||
(screen->temp == false) &&
|
||||
(BKE_screen_is_fullscreen_area(screen) == false) &&
|
||||
(screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT)));
|
||||
return ((BKE_screen_is_used(screen) == false) &&
|
||||
/* in typical usage temp screens should have a nonzero winid
|
||||
* (all temp screens should be used, or closed & freed). */
|
||||
(screen->temp == false) && (BKE_screen_is_fullscreen_area(screen) == false) &&
|
||||
(screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT)));
|
||||
}
|
||||
|
||||
static WorkSpaceLayout *workspace_layout_delete_find_new(const WorkSpaceLayout *layout_old)
|
||||
{
|
||||
for (WorkSpaceLayout *layout_new = layout_old->prev; layout_new; layout_new = layout_new->next) {
|
||||
if (workspace_layout_set_poll(layout_new)) {
|
||||
return layout_new;
|
||||
}
|
||||
}
|
||||
for (WorkSpaceLayout *layout_new = layout_old->prev; layout_new; layout_new = layout_new->next) {
|
||||
if (workspace_layout_set_poll(layout_new)) {
|
||||
return layout_new;
|
||||
}
|
||||
}
|
||||
|
||||
for (WorkSpaceLayout *layout_new = layout_old->next; layout_new; layout_new = layout_new->next) {
|
||||
if (workspace_layout_set_poll(layout_new)) {
|
||||
return layout_new;
|
||||
}
|
||||
}
|
||||
for (WorkSpaceLayout *layout_new = layout_old->next; layout_new; layout_new = layout_new->next) {
|
||||
if (workspace_layout_set_poll(layout_new)) {
|
||||
return layout_new;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \warning Only call outside of area/region loops!
|
||||
* \return true if succeeded.
|
||||
*/
|
||||
bool ED_workspace_layout_delete(
|
||||
WorkSpace *workspace, WorkSpaceLayout *layout_old,
|
||||
bContext *C)
|
||||
bool ED_workspace_layout_delete(WorkSpace *workspace, WorkSpaceLayout *layout_old, bContext *C)
|
||||
{
|
||||
const bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old);
|
||||
WorkSpaceLayout *layout_new;
|
||||
const bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old);
|
||||
WorkSpaceLayout *layout_new;
|
||||
|
||||
BLI_assert(BLI_findindex(BKE_workspace_layouts_get(workspace), layout_old) != -1);
|
||||
BLI_assert(BLI_findindex(BKE_workspace_layouts_get(workspace), layout_old) != -1);
|
||||
|
||||
/* don't allow deleting temp fullscreens for now */
|
||||
if (BKE_screen_is_fullscreen_area(screen_old)) {
|
||||
return false;
|
||||
}
|
||||
/* don't allow deleting temp fullscreens for now */
|
||||
if (BKE_screen_is_fullscreen_area(screen_old)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* A layout/screen can only be in use by one window at a time, so as
|
||||
* long as we are able to find a layout/screen that is unused, we
|
||||
* can safely assume ours is not in use anywhere an delete it. */
|
||||
/* A layout/screen can only be in use by one window at a time, so as
|
||||
* long as we are able to find a layout/screen that is unused, we
|
||||
* can safely assume ours is not in use anywhere an delete it. */
|
||||
|
||||
layout_new = workspace_layout_delete_find_new(layout_old);
|
||||
layout_new = workspace_layout_delete_find_new(layout_old);
|
||||
|
||||
if (layout_new) {
|
||||
return workspace_layout_delete_doit(workspace, layout_old, layout_new, C);
|
||||
}
|
||||
if (layout_new) {
|
||||
return workspace_layout_delete_doit(workspace, layout_old, layout_new, C);
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool workspace_layout_cycle_iter_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
|
||||
{
|
||||
/* return false to stop iterator when we have found a layout to activate */
|
||||
return !workspace_layout_set_poll(layout);
|
||||
/* return false to stop iterator when we have found a layout to activate */
|
||||
return !workspace_layout_set_poll(layout);
|
||||
}
|
||||
|
||||
bool ED_workspace_layout_cycle(
|
||||
WorkSpace *workspace, const short direction, bContext *C)
|
||||
bool ED_workspace_layout_cycle(WorkSpace *workspace, const short direction, bContext *C)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
WorkSpaceLayout *old_layout = BKE_workspace_active_layout_get(win->workspace_hook);
|
||||
WorkSpaceLayout *new_layout;
|
||||
const bScreen *old_screen = BKE_workspace_layout_screen_get(old_layout);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
WorkSpaceLayout *old_layout = BKE_workspace_active_layout_get(win->workspace_hook);
|
||||
WorkSpaceLayout *new_layout;
|
||||
const bScreen *old_screen = BKE_workspace_layout_screen_get(old_layout);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
|
||||
if (old_screen->temp || (sa && sa->full && sa->full->temp)) {
|
||||
return false;
|
||||
}
|
||||
if (old_screen->temp || (sa && sa->full && sa->full->temp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BLI_assert(ELEM(direction, 1, -1));
|
||||
new_layout = BKE_workspace_layout_iter_circular(workspace, old_layout, workspace_layout_cycle_iter_cb,
|
||||
NULL, (direction == -1) ? true : false);
|
||||
BLI_assert(ELEM(direction, 1, -1));
|
||||
new_layout = BKE_workspace_layout_iter_circular(workspace,
|
||||
old_layout,
|
||||
workspace_layout_cycle_iter_cb,
|
||||
NULL,
|
||||
(direction == -1) ? true : false);
|
||||
|
||||
if (new_layout && (old_layout != new_layout)) {
|
||||
bScreen *new_screen = BKE_workspace_layout_screen_get(new_layout);
|
||||
if (new_layout && (old_layout != new_layout)) {
|
||||
bScreen *new_screen = BKE_workspace_layout_screen_get(new_layout);
|
||||
|
||||
if (sa && sa->full) {
|
||||
/* return to previous state before switching screens */
|
||||
ED_screen_full_restore(C, sa); /* may free screen of old_layout */
|
||||
}
|
||||
if (sa && sa->full) {
|
||||
/* return to previous state before switching screens */
|
||||
ED_screen_full_restore(C, sa); /* may free screen of old_layout */
|
||||
}
|
||||
|
||||
ED_screen_change(C, new_screen);
|
||||
ED_screen_change(C, new_screen);
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user