Asset Shelf: Transparent asset shelf header with background for buttons #112241
|
@ -492,6 +492,7 @@ void ED_asset_shelf_header_region_init(wmWindowManager * /*wm*/, ARegion *region
|
|||
{
|
||||
ED_region_header_init(region);
|
||||
region->alignment |= RGN_SPLIT_SCALE_PREV;
|
||||
region->flag |= RGN_FLAG_RESIZE_RESPECT_BUTTON_SECTIONS;
|
||||
}
|
||||
|
||||
void ED_asset_shelf_header_region(const bContext *C, ARegion *region)
|
||||
|
@ -505,14 +506,17 @@ void ED_asset_shelf_header_region(const bContext *C, ARegion *region)
|
|||
*main_shelf_region);
|
||||
update_active_shelf(*C, *space_type, *shelf_regiondata);
|
||||
|
||||
ED_region_header(C, region);
|
||||
ED_region_header_with_button_sections(C, region, uiButtonSectionsAlign::Bottom);
|
||||
JulianEisel marked this conversation as resolved
Outdated
|
||||
}
|
||||
|
||||
int ED_asset_shelf_header_region_size()
|
||||
{
|
||||
/* The asset shelf tends to look like a separate area. Making the shelf header smaller than a
|
||||
* normal header helps a bit. */
|
||||
return ED_area_headersize() * 0.85f;
|
||||
/* Use a height that lets widgets sit just on top of the separator line drawn at the lower edge
|
||||
* of the region (widgets will be centered).
|
||||
*
|
||||
* Note that this is usually a bit less than the header size. The asset shelf tends to look like
|
||||
* a separate area, so making the shelf header smaller than a header helps. */
|
||||
return UI_UNIT_Y + (UI_BUTTON_SECTION_SEPERATOR_LINE_WITH * 2);
|
||||
}
|
||||
|
||||
void ED_asset_shelf_region_blend_read_data(BlendDataReader *reader, ARegion *region)
|
||||
|
|
|
@ -118,6 +118,16 @@ void ED_region_header_init(ARegion *region);
|
|||
void ED_region_header(const bContext *C, ARegion *region);
|
||||
void ED_region_header_layout(const bContext *C, ARegion *region);
|
||||
void ED_region_header_draw(const bContext *C, ARegion *region);
|
||||
/* Forward declare enum. */
|
||||
enum class uiButtonSectionsAlign : int8_t;
|
||||
/** Version of #ED_region_header() that draws with button sections. */
|
||||
void ED_region_header_with_button_sections(const bContext *C,
|
||||
ARegion *region,
|
||||
uiButtonSectionsAlign align);
|
||||
/** Version of #ED_region_header_draw() that draws with button sections. */
|
||||
void ED_region_header_draw_with_button_sections(const bContext *C,
|
||||
const ARegion *region,
|
||||
uiButtonSectionsAlign align);
|
||||
|
||||
void ED_region_cursor_set(wmWindow *win, ScrArea *area, ARegion *region);
|
||||
/**
|
||||
|
|
|
@ -839,6 +839,25 @@ void UI_block_region_set(uiBlock *block, ARegion *region);
|
|||
void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr);
|
||||
void UI_block_lock_clear(uiBlock *block);
|
||||
|
||||
#define UI_BUTTON_SECTION_MERGE_DISTANCE (UI_UNIT_X * 3)
|
||||
/* Separator line between regions if the #uiButtonSectionsAlign is not #None. */
|
||||
#define UI_BUTTON_SECTION_SEPERATOR_LINE_WITH (U.pixelsize * 2)
|
||||
|
||||
enum class uiButtonSectionsAlign : int8_t { None = 1, Top, Bottom };
|
||||
JulianEisel marked this conversation as resolved
Outdated
Campbell Barton
commented
picky I have a slight preference to set the first value to Also, why not *picky* I have a slight preference to set the first value to `1`, so it's clear when debugging what the values are and so a zeroed value isn't implicitly initializing in a non obvious way.
Also, why not `uint8_t`? (if the size is given at all, may as well not use a larger value then is needed.)
|
||||
/**
|
||||
* Draw a background with rounded corners behind each visual group of buttons. The visual groups
|
||||
* are separated by spacer buttons (#uiItemSpacer()). Button groups that are closer than
|
||||
* #UI_BUTTON_SECTION_MERGE_DISTANCE will be merged into one visual section. If the group is closer
|
||||
* than that to a region edge, it will also be extended to that, and the rounded corners will be
|
||||
* removed on that edge.
|
||||
*
|
||||
* \note This currently only works well for horizontal, header like regions.
|
||||
*/
|
||||
void UI_region_button_sections_draw(const ARegion *region,
|
||||
int /*THemeColorID*/ colorid,
|
||||
uiButtonSectionsAlign align);
|
||||
bool UI_region_button_sections_is_inside_x(const ARegion *region, const int mval_x);
|
||||
|
||||
/**
|
||||
* Automatic aligning, horizontal or vertical.
|
||||
*/
|
||||
|
|
|
@ -42,6 +42,7 @@ set(SRC
|
|||
interface_align.cc
|
||||
interface_anim.cc
|
||||
interface_button_group.cc
|
||||
interface_button_sections.cc
|
||||
interface_context_menu.cc
|
||||
interface_context_path.cc
|
||||
interface_drag.cc
|
||||
|
|
|
@ -0,0 +1,225 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edinterface
|
||||
*
|
||||
* Calculating and drawing of bounding boxes for "button sections". That is, each group of buttons
|
||||
* separated by a separator spacer button.
|
||||
*/
|
||||
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "GPU_immediate.h"
|
||||
|
||||
#include "interface_intern.hh"
|
||||
|
||||
using namespace blender;
|
||||
|
||||
/**
|
||||
* Calculate a bounding box for each section. Sections will be merged if they are closer than
|
||||
* #UI_BUTTON_SECTION_MERGE_DISTANCE.
|
||||
*
|
||||
* If a section is closer than #UI_BUTTON_SECTION_MERGE_DISTANCE to a region edge, it will be
|
||||
* extended to the edge.
|
||||
*
|
||||
* \return the bounding boxes in region space.
|
||||
*/
|
||||
static Vector<rcti> button_section_bounds_calc(const ARegion *region, const bool add_padding)
|
||||
{
|
||||
Vector<rcti> section_bounds;
|
||||
|
||||
const auto finish_section_fn = [&](const rcti cur_section_bounds) {
|
||||
if (!section_bounds.is_empty() &&
|
||||
std::abs(section_bounds.last().xmax - cur_section_bounds.xmin) <
|
||||
UI_BUTTON_SECTION_MERGE_DISTANCE)
|
||||
{
|
||||
section_bounds.last().xmax = cur_section_bounds.xmax;
|
||||
}
|
||||
else {
|
||||
section_bounds.append(cur_section_bounds);
|
||||
}
|
||||
|
||||
rcti &last_bounds = section_bounds.last();
|
||||
/* Extend to region edge if close enough. */
|
||||
if (last_bounds.xmin <= UI_BUTTON_SECTION_MERGE_DISTANCE) {
|
||||
last_bounds.xmin = 0;
|
||||
}
|
||||
if (last_bounds.xmax >= (region->winx - UI_BUTTON_SECTION_MERGE_DISTANCE)) {
|
||||
last_bounds.xmax = region->winx;
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
bool has_section_content = false;
|
||||
rcti cur_section_bounds;
|
||||
BLI_rcti_init_minmax(&cur_section_bounds);
|
||||
|
||||
LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) {
|
||||
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
|
||||
if (but->type == UI_BTYPE_SEPR_SPACER) {
|
||||
/* Start a new section. */
|
||||
if (has_section_content) {
|
||||
finish_section_fn(cur_section_bounds);
|
||||
|
||||
/* Reset for next section. */
|
||||
BLI_rcti_init_minmax(&cur_section_bounds);
|
||||
has_section_content = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
rcti but_pixelrect;
|
||||
ui_but_to_pixelrect(&but_pixelrect, region, block, but);
|
||||
BLI_rcti_do_minmax_rcti(&cur_section_bounds, &but_pixelrect);
|
||||
has_section_content = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish last section in case the last button is not a spacer. */
|
||||
if (has_section_content) {
|
||||
finish_section_fn(cur_section_bounds);
|
||||
}
|
||||
}
|
||||
|
||||
if (add_padding) {
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
for (rcti &bounds : section_bounds) {
|
||||
BLI_rcti_pad(&bounds, style->buttonspacex, style->buttonspacey);
|
||||
/* Clamp, important for the rounded-corners to draw correct. */
|
||||
CLAMP_MIN(bounds.xmin, 0);
|
||||
CLAMP_MAX(bounds.xmax, region->winx);
|
||||
CLAMP_MIN(bounds.ymin, 0);
|
||||
CLAMP_MAX(bounds.ymax, region->winy);
|
||||
}
|
||||
}
|
||||
|
||||
return section_bounds;
|
||||
}
|
||||
|
||||
static void ui_draw_button_sections_background(const ARegion *region,
|
||||
const Span<rcti> section_bounds,
|
||||
JulianEisel marked this conversation as resolved
Outdated
Hans Goudey
commented
`Span` should be passed by value, otherwise it acts like a pointer to a pointer.
Julian Eisel
commented
Heh, rushing things before the meeting much? Thanks :) Heh, rushing things before the meeting much? Thanks :)
|
||||
const ThemeColorID colorid,
|
||||
const uiButtonSectionsAlign align,
|
||||
const float corner_radius)
|
||||
{
|
||||
float bg_color[4];
|
||||
UI_GetThemeColor4fv(colorid, bg_color);
|
||||
|
||||
for (const rcti &bounds : section_bounds) {
|
||||
int roundbox_corners = [align]() -> int {
|
||||
switch (align) {
|
||||
case uiButtonSectionsAlign::Top:
|
||||
return UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT;
|
||||
case uiButtonSectionsAlign::Bottom:
|
||||
return UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
|
||||
case uiButtonSectionsAlign::None:
|
||||
return UI_CNR_ALL;
|
||||
}
|
||||
return UI_CNR_ALL;
|
||||
}();
|
||||
|
||||
/* No rounded corners at the region edge. */
|
||||
if (bounds.xmin == 0) {
|
||||
roundbox_corners &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
|
||||
}
|
||||
if (bounds.xmax >= region->winx) {
|
||||
roundbox_corners &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
|
||||
}
|
||||
|
||||
rctf bounds_float;
|
||||
BLI_rctf_rcti_copy(&bounds_float, &bounds);
|
||||
UI_draw_roundbox_corner_set(roundbox_corners);
|
||||
UI_draw_roundbox_4fv(&bounds_float, true, corner_radius, bg_color);
|
||||
}
|
||||
}
|
||||
|
||||
static void ui_draw_button_sections_alignment_separator(const ARegion *region,
|
||||
const Span<rcti> section_bounds,
|
||||
const ThemeColorID colorid,
|
||||
const uiButtonSectionsAlign align,
|
||||
const float corner_radius)
|
||||
{
|
||||
const int separator_line_width = UI_BUTTON_SECTION_SEPERATOR_LINE_WITH;
|
||||
|
||||
float bg_color[4];
|
||||
UI_GetThemeColor4fv(colorid, bg_color);
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
/* Separator line. */
|
||||
{
|
||||
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);
|
||||
immUniformColor4fv(bg_color);
|
||||
|
||||
if (align == uiButtonSectionsAlign::Top) {
|
||||
immRecti(pos, 0, region->winy - separator_line_width, region->winx, region->winy);
|
||||
}
|
||||
else if (align == uiButtonSectionsAlign::Bottom) {
|
||||
immRecti(pos, 0, 0, region->winx, separator_line_width);
|
||||
}
|
||||
else {
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
int prev_xmax = 0;
|
||||
for (const rcti &bounds : section_bounds) {
|
||||
if (prev_xmax != 0) {
|
||||
const rcti rounded_corner_rect = {
|
||||
prev_xmax, bounds.xmin, separator_line_width, region->winy - separator_line_width};
|
||||
|
||||
UI_draw_roundbox_corner_set(align == uiButtonSectionsAlign::Top ?
|
||||
(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT) :
|
||||
(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT));
|
||||
ui_draw_rounded_corners_inverted(rounded_corner_rect, corner_radius, bg_color);
|
||||
}
|
||||
|
||||
prev_xmax = bounds.xmax;
|
||||
}
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
void UI_region_button_sections_draw(const ARegion *region,
|
||||
const int /*ThemeColorID*/ colorid,
|
||||
const uiButtonSectionsAlign align)
|
||||
{
|
||||
const float aspect = BLI_rctf_size_x(®ion->v2d.cur) /
|
||||
(BLI_rcti_size_x(®ion->v2d.mask) + 1);
|
||||
const float corner_radius = 4.0f * UI_SCALE_FAC / aspect;
|
||||
|
||||
const Vector<rcti> section_bounds = button_section_bounds_calc(region, true);
|
||||
|
||||
ui_draw_button_sections_background(
|
||||
region, section_bounds, ThemeColorID(colorid), align, corner_radius);
|
||||
if (align != uiButtonSectionsAlign::None) {
|
||||
ui_draw_button_sections_alignment_separator(region,
|
||||
section_bounds,
|
||||
ThemeColorID(colorid),
|
||||
align,
|
||||
/* Slightly bigger corner radius, looks better. */
|
||||
corner_radius + 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool UI_region_button_sections_is_inside_x(const ARegion *region, const int mval_x)
|
||||
{
|
||||
const Vector<rcti> section_bounds = button_section_bounds_calc(region, true);
|
||||
|
||||
for (const rcti &bounds : section_bounds) {
|
||||
if (BLI_rcti_isect_x(&bounds, mval_x)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -149,6 +149,73 @@ 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)
|
||||
{
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
float vec[4][2] = {
|
||||
{0.195, 0.02},
|
||||
{0.55, 0.169},
|
||||
{0.831, 0.45},
|
||||
{0.98, 0.805},
|
||||
};
|
||||
for (int a = 0; a < 4; a++) {
|
||||
mul_v2_fl(vec[a], rad);
|
||||
}
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4fv(color);
|
||||
|
||||
if (roundboxtype & UI_CNR_TOP_LEFT) {
|
||||
immBegin(GPU_PRIM_TRI_FAN, 7);
|
||||
immVertex2f(pos, rect.xmin, rect.ymax);
|
||||
immVertex2f(pos, rect.xmin, rect.ymax - rad);
|
||||
for (int a = 0; a < 4; a++) {
|
||||
immVertex2f(pos, rect.xmin + vec[a][1], rect.ymax - rad + vec[a][0]);
|
||||
}
|
||||
immVertex2f(pos, rect.xmin + rad, rect.ymax);
|
||||
immEnd();
|
||||
}
|
||||
|
||||
if (roundboxtype & UI_CNR_TOP_RIGHT) {
|
||||
immBegin(GPU_PRIM_TRI_FAN, 7);
|
||||
immVertex2f(pos, rect.xmax, rect.ymax);
|
||||
immVertex2f(pos, rect.xmax - rad, rect.ymax);
|
||||
for (int a = 0; a < 4; a++) {
|
||||
immVertex2f(pos, rect.xmax - rad + vec[a][0], rect.ymax - vec[a][1]);
|
||||
}
|
||||
immVertex2f(pos, rect.xmax, rect.ymax - rad);
|
||||
immEnd();
|
||||
}
|
||||
|
||||
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
|
||||
immBegin(GPU_PRIM_TRI_FAN, 7);
|
||||
immVertex2f(pos, rect.xmax, rect.ymin);
|
||||
immVertex2f(pos, rect.xmax, rect.ymin + rad);
|
||||
for (int a = 0; a < 4; a++) {
|
||||
immVertex2f(pos, rect.xmax - vec[a][1], rect.ymin + rad - vec[a][0]);
|
||||
}
|
||||
immVertex2f(pos, rect.xmax - rad, rect.ymin);
|
||||
immEnd();
|
||||
}
|
||||
|
||||
if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
|
||||
immBegin(GPU_PRIM_TRI_FAN, 7);
|
||||
immVertex2f(pos, rect.xmin, rect.ymin);
|
||||
immVertex2f(pos, rect.xmin + rad, rect.ymin);
|
||||
for (int a = 0; a < 4; a++) {
|
||||
immVertex2f(pos, rect.xmin + rad - vec[a][0], rect.ymin + vec[a][1]);
|
||||
}
|
||||
immVertex2f(pos, rect.xmin, rect.ymin + rad);
|
||||
immEnd();
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4])
|
||||
{
|
||||
const int ofs_y = 4 * U.pixelsize;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <functional>
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
|
@ -1015,6 +1016,16 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha
|
|||
*/
|
||||
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,
|
||||
|
|
|
@ -2820,6 +2820,14 @@ void ED_region_clear(const bContext *C, const ARegion *region, const int /*Theme
|
|||
}
|
||||
}
|
||||
|
||||
static void region_clear_fully_transparent(const bContext *C)
|
||||
{
|
||||
/* view should be in pixelspace */
|
||||
UI_view2d_view_restore(C);
|
||||
|
||||
GPU_clear_color(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
BLI_INLINE bool streq_array_any(const char *s, const char *arr[])
|
||||
{
|
||||
for (uint i = 0; arr[i]; i++) {
|
||||
|
@ -3574,11 +3582,8 @@ void ED_region_header_layout(const bContext *C, ARegion *region)
|
|||
UI_view2d_view_restore(C);
|
||||
}
|
||||
|
||||
void ED_region_header_draw(const bContext *C, ARegion *region)
|
||||
static void region_draw_blocks_in_view2d(const bContext *C, const ARegion *region)
|
||||
{
|
||||
/* clear */
|
||||
ED_region_clear(C, region, region_background_color_id(C, region));
|
||||
|
||||
UI_view2d_view_ortho(®ion->v2d);
|
||||
|
||||
/* View2D matrix might have changed due to dynamic sized regions. */
|
||||
|
@ -3591,6 +3596,31 @@ void ED_region_header_draw(const bContext *C, ARegion *region)
|
|||
UI_view2d_view_restore(C);
|
||||
}
|
||||
|
||||
void ED_region_header_draw(const bContext *C, ARegion *region)
|
||||
{
|
||||
/* clear */
|
||||
ED_region_clear(C, region, region_background_color_id(C, region));
|
||||
region_draw_blocks_in_view2d(C, region);
|
||||
}
|
||||
|
||||
void ED_region_header_draw_with_button_sections(const bContext *C,
|
||||
JulianEisel marked this conversation as resolved
Outdated
Campbell Barton
commented
Worth mentioning this follows Worth mentioning this follows `ED_region_header_draw` closely, it might make sense to but this directly below that function too so changes to one aren't as likely to be missed in the other.
|
||||
const ARegion *region,
|
||||
const uiButtonSectionsAlign align)
|
||||
{
|
||||
JulianEisel marked this conversation as resolved
Outdated
Campbell Barton
commented
*picky *normally -> normal. *picky *normally -> normal.
|
||||
const ThemeColorID bgcolorid = region_background_color_id(C, region);
|
||||
|
||||
/* Clear and draw button sections background when using region overlap. Otherwise clear using the
|
||||
* background color like normal. */
|
||||
if (region->overlap) {
|
||||
region_clear_fully_transparent(C);
|
||||
UI_region_button_sections_draw(region, bgcolorid, align);
|
||||
}
|
||||
else {
|
||||
ED_region_clear(C, region, bgcolorid);
|
||||
}
|
||||
region_draw_blocks_in_view2d(C, region);
|
||||
}
|
||||
|
||||
void ED_region_header(const bContext *C, ARegion *region)
|
||||
{
|
||||
/* TODO: remove? */
|
||||
|
@ -3598,6 +3628,14 @@ void ED_region_header(const bContext *C, ARegion *region)
|
|||
ED_region_header_draw(C, region);
|
||||
}
|
||||
|
||||
void ED_region_header_with_button_sections(const bContext *C,
|
||||
ARegion *region,
|
||||
const uiButtonSectionsAlign align)
|
||||
{
|
||||
ED_region_header_layout(C, region);
|
||||
ED_region_header_draw_with_button_sections(C, region, align);
|
||||
}
|
||||
|
||||
void ED_region_header_init(ARegion *region)
|
||||
{
|
||||
UI_view2d_region_reinit(®ion->v2d, V2D_COMMONVIEW_HEADER, region->winx, region->winy);
|
||||
|
|
|
@ -856,6 +856,20 @@ static AZone *area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const b
|
|||
break;
|
||||
}
|
||||
if (az->type == AZONE_REGION) {
|
||||
const ARegion *region = az->region;
|
||||
const int local_xy[2] = {xy[0] - region->winrct.xmin, xy[1] - region->winrct.ymin};
|
||||
|
||||
/* Respect button sections: If the mouse is horizontally hovering empty space defined by a
|
||||
* separator-spacer between buttons, don't allow scaling the region from there. Used for
|
||||
* regions that have a transparent background between such button sections, users don't
|
||||
* expect to be able to resize from there. */
|
||||
if (region->visible && (region->flag & RGN_FLAG_RESIZE_RESPECT_BUTTON_SECTIONS) &&
|
||||
!UI_region_button_sections_is_inside_x(az->region, local_xy[0]))
|
||||
{
|
||||
az = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (az->type == AZONE_FULLSCREEN) {
|
||||
|
|
|
@ -740,6 +740,7 @@ enum {
|
|||
/** #ARegionType.poll() failed for the current context, and the region should be treated as if it
|
||||
* wouldn't exist. Runtime only flag. */
|
||||
RGN_FLAG_POLL_FAILED = (1 << 10),
|
||||
RGN_FLAG_RESIZE_RESPECT_BUTTON_SECTIONS = (1 << 11),
|
||||
};
|
||||
|
||||
/** #ARegion.do_draw */
|
||||
|
|
|
@ -865,8 +865,6 @@ static bool rna_Space_show_region_asset_shelf_get(PointerRNA *ptr)
|
|||
static void rna_Space_show_region_asset_shelf_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
rna_Space_bool_from_region_flag_set_by_type(ptr, RGN_TYPE_ASSET_SHELF, RGN_FLAG_HIDDEN, !value);
|
||||
rna_Space_bool_from_region_flag_set_by_type(
|
||||
ptr, RGN_TYPE_ASSET_SHELF_HEADER, RGN_FLAG_HIDDEN, !value);
|
||||
}
|
||||
static void rna_Space_show_region_asset_shelf_update(bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Might it make sense to add a
ED_region_header_with_button_sections
? Since practically all other region functions useED_region_header(C, region)
.