UI: Demonstration of Non-Obscuring Area Borders #115251

Open
Harley Acheson wants to merge 12 commits from Harley/blender:AreaBorders into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
11 changed files with 202 additions and 264 deletions

View File

@ -107,12 +107,13 @@ const bTheme U_theme_default = {
.roundness = 0.2f,
},
.wcol_tab = {
.outline = RGBA(0x1d1d1dff),
.inner = RGBA(0x1d1d1dff),
.inner_sel = RGBA(0x303030ff),
.outline = RGBA(0x1d1d1d00),
.inner = RGBA(0x1d1d1d00),
.inner_sel = RGBA(0xffffff15),
.item = RGBA(0x1d1d1dff),
.text = RGBA(0x989898ff),
.text_sel = RGBA(0xffffffff),
.item = RGBA(0x4772b3ff),
.roundness = 0.2f,
},
.wcol_menu = {
@ -254,15 +255,15 @@ const bTheme U_theme_default = {
.header = RGBA(0x303030b3),
.header_text = RGBA(0xeeeeeeff),
.header_text_hi = RGBA(0xffffffff),
.tab_active = RGBA(0x303030ff),
.tab_inactive = RGBA(0x1d1d1dff),
.tab_back = RGBA(0x181818ff),
.tab_outline = RGBA(0x3d3d3dff),
.tab_active = RGBA(0x30303000),
.tab_inactive = RGBA(0x1d1d1d00),
.tab_back = RGBA(0x18181800),
.tab_outline = RGBA(0x3d3d3d00),
.button = RGBA(0x30303000),
.button_title = RGBA(0xccccccff),
.button_text = RGBA(0xccccccff),
.button_text_hi = RGBA(0xffffffff),
.navigation_bar = RGBA(0x1d1d1dff),
.navigation_bar = RGBA(0x282828ff),
.execution_buts = RGBA(0x1d1d1dff),
.panelcolors = {
.header = RGBA(0x3d3d3dff),
@ -284,10 +285,10 @@ const bTheme U_theme_default = {
.header = RGBA(0x303030b3),
.header_text = RGBA(0xeeeeeeff),
.header_text_hi = RGBA(0xffffffff),
.tab_active = RGBA(0x303030ff),
.tab_inactive = RGBA(0x1d1d1dff),
.tab_back = RGBA(0x181818ff),
.tab_outline = RGBA(0x3d3d3dff),
.tab_active = RGBA(0x30303000),
.tab_inactive = RGBA(0x1d1d1d00),
.tab_back = RGBA(0x18181855),
.tab_outline = RGBA(0x3d3d3d00),
.button = RGBA(0x30303000),
.button_title = RGBA(0xffffffff),
.button_text = RGBA(0xccccccff),

View File

@ -141,11 +141,26 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a USER_VERSION_ATLEAST check.
* Versioning code until next subversion bump goes here.
*
* \note Be sure to check when bumping the version:
* - #blo_do_versions_userdef in this file.
* - "versioning_{BLENDER_VERSION}.c"
*
* \note Keep this message at the bottom of the function.
*/
{
/* Keep this block, even when empty. */
FROM_DEFAULT_V4_UCHAR(tui.wcol_tab.item);
FROM_DEFAULT_V4_UCHAR(tui.wcol_tab.inner);
FROM_DEFAULT_V4_UCHAR(tui.wcol_tab.inner_sel);
FROM_DEFAULT_V4_UCHAR(tui.wcol_tab.outline);
FROM_DEFAULT_V4_UCHAR(space_properties.navigation_bar);
FROM_DEFAULT_V4_UCHAR(space_view3d.tab_back);
FROM_DEFAULT_V4_UCHAR(space_view3d.tab_active);
FROM_DEFAULT_V4_UCHAR(space_view3d.tab_inactive);
FROM_DEFAULT_V4_UCHAR(space_view3d.tab_outline);
}
#undef FROM_DEFAULT_V4_UCHAR
@ -262,18 +277,6 @@ void blo_do_versions_userdef(UserDef *userdef)
userdef->pad_rot_angle = 15.0f;
}
/* If the userdef was created on a different platform, it may have an
* unsupported GPU backend selected. If so, pick a supported default. */
#ifdef __APPLE__
if (userdef->gpu_backend == GPU_BACKEND_OPENGL) {
userdef->gpu_backend = GPU_BACKEND_METAL;
}
#else
if (userdef->gpu_backend == GPU_BACKEND_METAL) {
userdef->gpu_backend = GPU_BACKEND_OPENGL;
}
#endif
/* graph editor - unselected F-Curve visibility */
if (userdef->fcu_inactive_alpha == 0) {
userdef->fcu_inactive_alpha = 0.25f;
@ -415,7 +418,7 @@ void blo_do_versions_userdef(UserDef *userdef)
if (!USER_VERSION_ATLEAST(257, 0)) {
/* Clear #AUTOKEY_FLAG_ONLYKEYINGSET flag from user-preferences,
* so that it doesn't linger around from old configurations like a ghost. */
userdef->keying_flag &= ~AUTOKEY_FLAG_ONLYKEYINGSET;
userdef->autokey_flag &= ~AUTOKEY_FLAG_ONLYKEYINGSET;
}
if (!USER_VERSION_ATLEAST(260, 3)) {
@ -494,8 +497,8 @@ void blo_do_versions_userdef(UserDef *userdef)
USER_FLAG_UNUSED_6 | USER_FLAG_UNUSED_7 | USER_FLAG_UNUSED_9 |
USER_DEVELOPER_UI);
userdef->uiflag &= ~(USER_HEADER_BOTTOM);
userdef->transopts &= ~(USER_TR_UNUSED_3 | USER_TR_UNUSED_4 | USER_TR_UNUSED_6 |
USER_TR_UNUSED_7);
userdef->transopts &= ~(USER_TR_UNUSED_2 | USER_TR_UNUSED_3 | USER_TR_UNUSED_4 |
USER_TR_UNUSED_6 | USER_TR_UNUSED_7);
userdef->uiflag |= USER_LOCK_CURSOR_ADJUST;
}
@ -868,6 +871,15 @@ void blo_do_versions_userdef(UserDef *userdef)
BKE_addon_remove_safe(&userdef->addons, "io_scene_obj");
}
if (!USER_VERSION_ATLEAST(400, 12)) {
#ifdef __APPLE__
/* Drop OpenGL support on MAC devices as they don't support OpenGL 4.3. */
if (userdef->gpu_backend == GPU_BACKEND_OPENGL) {
userdef->gpu_backend = GPU_BACKEND_METAL;
}
#endif
}
if (!USER_VERSION_ATLEAST(400, 15)) {
userdef->node_preview_res = 120;
}
@ -908,19 +920,18 @@ void blo_do_versions_userdef(UserDef *userdef)
USER_ANIM_KEY_CHANNEL_CUSTOM_PROPERTIES);
}
if (!USER_VERSION_ATLEAST(401, 13)) {
if (userdef->keying_flag & AUTOKEY_FLAG_INSERTNEEDED) {
userdef->keying_flag |= MANUALKEY_FLAG_INSERTNEEDED;
}
userdef->keying_flag |= AUTOKEY_FLAG_INSERTNEEDED;
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a USER_VERSION_ATLEAST check.
* Versioning code until next subversion bump goes here.
*
* \note Be sure to check when bumping the version:
* - #do_versions_theme in this file.
* - "versioning_{BLENDER_VERSION}.c"
*
* \note Keep this message at the bottom of the function.
*/
{
/* Keep this block, even when empty. */
}
LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) {
do_versions_theme(userdef, btheme);

View File

@ -490,6 +490,14 @@ void UI_draw_roundbox_4fv_ex(const rctf *rect,
float outline_width,
float rad);
/**
* Draws rounded corner segments but inverted. Imagine each corner like a filled right triangle,
* just that the hypotenuse is nicely curved inwards (towards the right angle of the triangle).
*
* Useful for connecting orthogonal shapes with a rounded corner, which can look quite nice.
*/
void ui_draw_rounded_corners_inverted(const rcti &rect, const float rad, const float color[4]);
#if 0 /* unused */
int UI_draw_roundbox_corner_get();
#endif

View File

@ -149,9 +149,7 @@ void UI_draw_roundbox_4fv(const rctf *rect, bool filled, float rad, const float
UI_draw_roundbox_4fv_ex(rect, (filled) ? col : nullptr, nullptr, 1.0f, col, U.pixelsize, rad);
}
void ui_draw_rounded_corners_inverted(const rcti &rect,
const float rad,
const blender::float4 color)
void ui_draw_rounded_corners_inverted(const rcti &rect, const float rad, const float color[4])
{
GPUVertFormat *format = immVertexFormat();
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);

View File

@ -1039,16 +1039,6 @@ void ui_panel_tag_search_filter_match(Panel *panel);
*/
void ui_draw_gradient(const rcti *rect, const float hsv[3], eButGradientType type, float alpha);
/**
* Draws rounded corner segments but inverted. Imagine each corner like a filled right triangle,
* just that the hypotenuse is nicely curved inwards (towards the right angle of the triangle).
*
* Useful for connecting orthogonal shapes with a rounded corner, which can look quite nice.
*/
void ui_draw_rounded_corners_inverted(const rcti &rect,
const float rad,
const blender::float4 color);
/* based on UI_draw_roundbox_gl_mode,
* check on making a version which allows us to skip some sides */
void ui_draw_but_TAB_outline(const rcti *rect,

View File

@ -1325,7 +1325,8 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
/* Padding between tabs. */
const int tab_v_pad = round_fl_to_int(TABS_PADDING_BETWEEN_FACTOR * dpi_fac * zoom);
bTheme *btheme = UI_GetTheme();
const float tab_curve_radius = btheme->tui.wcol_tab.roundness * U.widget_unit * zoom;
uiWidgetColors *wcol = &btheme->tui.wcol_tab;
const float tab_curve_radius = wcol->roundness * U.widget_unit * zoom;
const int roundboxtype = is_left ? (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT) :
(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
bool is_alpha;
@ -1482,18 +1483,20 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
is_active ? theme_col_tab_active : theme_col_tab_inactive);
UI_draw_roundbox_4fv(&box_rect, false, tab_curve_radius, theme_col_tab_outline);
/* Disguise the outline on one side to join the tab to the panel. */
pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(is_active ? theme_col_tab_active : theme_col_tab_inactive);
immRecti(pos,
is_left ? rct->xmax - px : rct->xmin,
rct->ymin + px,
is_left ? rct->xmax : rct->xmin + px,
rct->ymax - px);
immUnbindProgram();
if (is_active) {
pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4ubv(wcol->item);
int height = std::max(int(3.0f * UI_SCALE_FAC * zoom), int(U.pixelsize));
if (is_left) {
immRecti(pos, rct->xmax - height, rct->ymin + px, rct->xmax, rct->ymax - px);
}
else {
immRecti(pos, rct->xmin, rct->ymin + px, rct->xmin + height, rct->ymax - px);
}
immUnbindProgram();
}
}
/* Tab titles. */

View File

@ -4469,6 +4469,7 @@ static void widget_tab(uiWidgetColors *wcol,
{
const float rad = widget_radius_from_zoom(zoom, wcol);
const bool is_active = (state->but_flag & UI_SELECT);
const bool is_hover = (state->but_flag & UI_HOVER);
/* Draw shaded outline - Disabled for now,
* seems incorrect and also looks nicer without it IMHO ;). */
@ -4501,6 +4502,48 @@ static void widget_tab(uiWidgetColors *wcol,
/* We are drawing on top of widget bases. Flush cache. */
GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
if (is_active || is_hover) {
GPUVertFormat *format = immVertexFormat();
const uint pos = GPU_vertformat_attr_add(
format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
if (is_hover && !is_active) {
immUniformColor3ubvAlpha(wcol->item, wcol->item[3] / 2);
}
else {
immUniformColor4ubv(wcol->item);
}
if (roundboxalign & UI_CNR_BOTTOM_LEFT) {
int height = int(3.0f * UI_SCALE_FAC);
immRecti(pos,
rect->xmax - height - 1,
rect->ymin + U.pixelsize,
rect->xmax,
rect->ymax - U.pixelsize);
}
else if (roundboxalign & UI_CNR_BOTTOM_RIGHT) {
int height = int(3.0f * UI_SCALE_FAC);
immRecti(pos,
rect->xmin,
rect->ymin + U.pixelsize,
rect->xmin + height + 1,
rect->ymax - U.pixelsize);
}
else {
int height = int(2.0f * UI_SCALE_FAC);
immRecti(pos,
rect->xmin + U.pixelsize,
rect->ymin,
rect->xmax - U.pixelsize,
rect->ymin + height + 1);
}
immUnbindProgram();
}
GPU_blend(GPU_BLEND_NONE);
#ifdef USE_TAB_SHADED_HIGHLIGHT

View File

@ -1683,27 +1683,28 @@ static void region_rect_recursive(
memset(&region->runtime.visible_rect, 0, sizeof(region->runtime.visible_rect));
}
static void area_calc_totrct(ScrArea *area, const rcti *window_rect)
static void area_calc_totrct(const bScreen *screen, ScrArea *area, const rcti *window_rect)
{
short px = short(U.pixelsize);
area->totrct.xmin = area->v1->vec.x;
area->totrct.xmax = area->v4->vec.x;
area->totrct.ymin = area->v1->vec.y;
area->totrct.ymax = area->v2->vec.y;
/* scale down totrct by 1 pixel on all sides not matching window borders */
if (area->totrct.xmin > window_rect->xmin) {
area->totrct.xmin += px;
if (ED_area_is_global(area) || screen->state == SCREENFULL ||
(screen->temp && BLI_listbase_is_single(&screen->areabase)))
{
/* pass */
}
if (area->totrct.xmax < (window_rect->xmax - 1)) {
area->totrct.xmax -= px;
}
if (area->totrct.ymin > window_rect->ymin) {
area->totrct.ymin += px;
}
if (area->totrct.ymax < (window_rect->ymax - 1)) {
area->totrct.ymax -= px;
else {
/* split and handle odd-number widths */
int half1 = BORDERWIDTH / 2;
int half2 = BORDERWIDTH - half1;
/* scale down window borders. */
area->totrct.xmin += half2;
area->totrct.xmax -= (half1 + 1);
area->totrct.ymin += half2;
area->totrct.ymax -= (half1 + 1);
}
/* Although the following asserts are correct they lead to a very unstable Blender.
* And the asserts would fail even in 2.7x
@ -2010,8 +2011,8 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
const bScreen *screen = WM_window_get_active_screen(win);
rcti window_rect;
WM_window_rect_calc(win, &window_rect);
area_calc_totrct(area, &window_rect);
WM_window_screen_rect_calc(win, &window_rect);
area_calc_totrct(screen, area, &window_rect);
/* region rect sizes */
rcti rect = area->totrct;
@ -2088,7 +2089,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
}
rcti window_rect;
WM_window_rect_calc(win, &window_rect);
WM_window_screen_rect_calc(win, &window_rect);
/* Set type-definitions. */
area->type = BKE_spacetype_from_id(area->spacetype);
@ -2106,7 +2107,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
}
/* area sizes */
area_calc_totrct(area, &window_rect);
area_calc_totrct(screen, area, &window_rect);
/* region rect sizes */
rcti rect = area->totrct;
@ -3500,31 +3501,6 @@ bool ED_region_property_search(const bContext *C,
return has_result;
}
/**
* The drawable part of the region might be slightly smaller because of area edges. This is
* especially visible for header-like regions, where vertical space around widgets is small, and
* it's quite visible when widgets aren't centered properly.
*/
static void layout_coordinates_correct_for_drawable_rect(
const wmWindow *win, const ScrArea *area, const ARegion *region, int * /*r_xco*/, int *r_yco)
{
/* Don't do corrections at the window borders where the region rectangles are clipped already. */
{
rcti win_rect;
WM_window_rect_calc(win, &win_rect);
if (region->winrct.ymin == win_rect.ymin) {
return;
}
if (region->winrct.ymax == (win_rect.ymax - 1)) {
return;
}
}
if (region->winrct.ymax == area->totrct.ymax) {
*r_yco -= 1;
}
}
void ED_region_header_layout(const bContext *C, ARegion *region)
{
const uiStyle *style = UI_style_get_dpi();
@ -3539,9 +3515,6 @@ void ED_region_header_layout(const bContext *C, ARegion *region)
int yco = buttony + (region->winy - buttony) / 2;
int maxco = xco;
layout_coordinates_correct_for_drawable_rect(
CTX_wm_window(C), CTX_wm_area(C), region, &xco, &yco);
/* set view2d view matrix for scrolling (without scrollers) */
UI_view2d_view_ortho(&region->v2d);

View File

@ -22,132 +22,28 @@
#include "WM_api.hh"
#include "UI_interface.hh"
#include "UI_interface_c.hh"
#include "UI_resources.hh"
#include "screen_intern.h"
#define CORNER_RESOLUTION 3
static void do_vert_pair(GPUVertBuf *vbo, uint pos, uint *vidx, int corner, int i)
{
float inter[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]));
float exter[2];
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);
}
/* 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, blender::float2{-1.0f, -1.0f});
add_v2_v2(exter, blender::float2{-1.0f, -1.0f});
break;
case 1:
add_v2_v2(inter, blender::float2{1.0f, -1.0f});
add_v2_v2(exter, blender::float2{1.0f, -1.0f});
break;
case 2:
add_v2_v2(inter, blender::float2{1.0f, 1.0f});
add_v2_v2(exter, blender::float2{1.0f, 1.0f});
break;
case 3:
add_v2_v2(inter, blender::float2{-1.0f, 1.0f});
add_v2_v2(exter, blender::float2{-1.0f, 1.0f});
break;
}
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 = nullptr;
if (screen_edges_batch == nullptr) {
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);
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, nullptr, GPU_BATCH_OWNS_VBO);
gpu_batch_presets_register(screen_edges_batch);
}
if (corner_len) {
*corner_len = CORNER_RESOLUTION * 2;
}
return screen_edges_batch;
}
#undef CORNER_RESOLUTION
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));
/* 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;
}
/* 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;
}
GPUBatch *batch = batch_screen_edges_get(nullptr);
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_BORDERS);
GPU_batch_uniform_4fv(batch, "rect", (float *)&rect);
GPU_batch_draw(batch);
}
/**
* \brief Screen edges drawing.
*/
static void drawscredge_area(ScrArea *area, int sizex, int sizey, float edge_thickness)
static void drawscredge_area_edges(int pos, ScrArea *area)
{
short x1 = area->v1->vec.x;
short y1 = area->v1->vec.y;
short x2 = area->v3->vec.x;
short y2 = area->v3->vec.y;
drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, edge_thickness);
if (area->totrct.xmin != area->v1->vec.x) {
immRecti(pos, area->v1->vec.x, area->v1->vec.y, area->totrct.xmin, area->v2->vec.y);
}
if (area->totrct.xmax != area->v4->vec.x) {
immRecti(pos, area->totrct.xmax + 1, area->v1->vec.y, area->v4->vec.x + 1, area->v2->vec.y);
}
if (area->totrct.ymin != area->v1->vec.y) {
immRecti(pos, area->v1->vec.x, area->v1->vec.y, area->v4->vec.x + 1, area->totrct.ymin);
}
if (area->totrct.ymax != area->v2->vec.y) {
immRecti(pos, area->v1->vec.x, area->totrct.ymax + 1, area->v4->vec.x + 1, area->v2->vec.y);
}
}
void ED_screen_draw_edges(wmWindow *win)
@ -163,16 +59,15 @@ void ED_screen_draw_edges(wmWindow *win)
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;
rcti scissor_rect;
BLI_rcti_init_minmax(&scissor_rect);
ARegion *region = screen->active_region;
ScrArea *active_area = nullptr;
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
BLI_rcti_do_minmax_v(&scissor_rect, blender::int2{area->v1->vec.x, area->v1->vec.y});
BLI_rcti_do_minmax_v(&scissor_rect, blender::int2{area->v3->vec.x, area->v3->vec.y});
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region == screen->active_region) {
active_area = area;
break;
}
}
}
if (GPU_type_matches_ex(GPU_DEVICE_INTEL_UHD, GPU_OS_UNIX, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) {
@ -181,39 +76,50 @@ void ED_screen_draw_edges(wmWindow *win)
GPU_flush();
}
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) {
GPU_scissor_test(true);
}
UI_GetThemeColor4fv(TH_EDITOR_OUTLINE, col);
col[3] = 1.0f;
corner_scale = U.pixelsize * 8.0f;
edge_thickness = corner_scale * 0.21f;
GPU_blend(GPU_BLEND_ALPHA);
GPUBatch *batch = batch_screen_edges_get(&verts_per_corner);
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_BORDERS);
GPU_batch_uniform_1i(batch, "cornerLen", verts_per_corner);
GPU_batch_uniform_1f(batch, "scale", corner_scale);
GPU_batch_uniform_4fv(batch, "color", col);
float color[4];
UI_GetThemeColor4fv(TH_EDITOR_OUTLINE, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
/* ui_draw_rounded_corners_inverted is off by one on two edges. */
rcti rect = {
area->totrct.xmin, area->totrct.xmax + 1, area->totrct.ymin, area->totrct.ymax + 1};
ui_draw_rounded_corners_inverted(rect, 5.0f * UI_SCALE_FAC, color);
}
GPUVertFormat *format = immVertexFormat();
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformThemeColor(TH_EDITOR_OUTLINE);
immUniformColor4fv(color);
float border_highlight[4] = {1.0f, 1.0f, 1.0f, 0.05f};
float border_highlight2[4] = {1.0f, 1.0f, 1.0f, 0.1f};
float half_line = U.pixelsize / 2.0f;
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
drawscredge_area(area, winsize_x, winsize_y, edge_thickness);
rctf rectf2 = {float(area->totrct.xmin) - half_line,
float(area->totrct.xmax) + 1.0f,
float(area->totrct.ymin) - 0.5f,
float(area->totrct.ymax) + half_line};
UI_draw_roundbox_4fv_ex(&rectf2,
nullptr,
nullptr,
1.0f,
(area == active_area) ? border_highlight2 : border_highlight,
U.pixelsize,
5.0f * UI_SCALE_FAC);
drawscredge_area_edges(pos, area);
}
immUnbindProgram();
GPU_blend(GPU_BLEND_NONE);
if (U.pixelsize <= 1.0f) {
GPU_scissor_test(false);
}
}
void screen_draw_join_highlight(ScrArea *sa1, ScrArea *sa2)

View File

@ -50,6 +50,11 @@ typedef enum eScreenAxis {
#define AREAJOINTOLERANCEX (AREAMINX * UI_SCALE_FAC)
#define AREAJOINTOLERANCEY (HEADERY * UI_SCALE_FAC)
/**
* Gutter space between areas.
*/
#define BORDERWIDTH ((int)((2.0f * UI_SCALE_FAC) + (2.0f * U.pixelsize)))
/**
* Expanded interaction influence of area borders.
*/

View File

@ -1688,7 +1688,7 @@ static void area_move_set_limits(wmWindow *win,
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (dir_axis == SCREEN_AXIS_H) {
int areamin = ED_area_headersize();
int areamin = ED_area_headersize() + BORDERWIDTH;
if (area->v1->vec.y > window_rect.ymin) {
areamin += U.pixelsize;