UI: Global "Status-bar" Area (WIP)
* Add horizontal bar at bottom of all non-temp windows, similar to the Top-bar. * Status-bar is hidden in UI-less fullscreen mode * Current contents are preliminary and based on T54861: ** Left: Current file-path if needed. "(Modified)" note if file was changed. ** Center: Scene statistics (like in 2.7 Info Editor). ** Right: Progress-bars and reports * Internally managed as own "STATUSBAR" editor-type (hidden in UI). * Like with the Top-bar, Status-bar data and SDNA writing is disabled. * Most changes in low-level screen/area code are to support layout bounds that differ from window bounds. Design task: T54861 Main changes approved by @brecht.
This commit is contained in:
parent
7b58073dc0
commit
6f20fcd598
@ -581,6 +581,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
|
||||
bf_editor_space_outliner
|
||||
bf_editor_space_script
|
||||
bf_editor_space_sequencer
|
||||
bf_editor_space_statusbar
|
||||
bf_editor_space_text
|
||||
bf_editor_space_time
|
||||
bf_editor_space_topbar
|
||||
|
@ -81,6 +81,7 @@ _modules = [
|
||||
"space_outliner",
|
||||
"space_properties",
|
||||
"space_sequencer",
|
||||
"space_statusbar",
|
||||
"space_text",
|
||||
"space_time",
|
||||
"space_topbar",
|
||||
|
84
release/scripts/startup/bl_ui/space_statusbar.py
Normal file
84
release/scripts/startup/bl_ui/space_statusbar.py
Normal file
@ -0,0 +1,84 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
from bpy.types import Header
|
||||
|
||||
|
||||
class STATUSBAR_HT_header(Header):
|
||||
bl_space_type = 'STATUSBAR'
|
||||
|
||||
def draw(self, context):
|
||||
area = context.area
|
||||
region = context.region
|
||||
|
||||
if region.alignment == 'RIGHT':
|
||||
if region == area.regions[0]:
|
||||
self.draw_right(context)
|
||||
else:
|
||||
self.draw_center(context)
|
||||
else:
|
||||
self.draw_left(context)
|
||||
|
||||
def draw_left(self, context):
|
||||
layout = self.layout
|
||||
|
||||
row = layout.row(align=True)
|
||||
if (bpy.data.filepath):
|
||||
row.label(text=bpy.data.filepath, translate=False)
|
||||
if bpy.data.is_dirty:
|
||||
row.label("(Modified)")
|
||||
|
||||
def draw_center(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
|
||||
layout.label(text=scene.statistics(view_layer), translate=False)
|
||||
|
||||
def draw_right(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.template_running_jobs()
|
||||
layout.template_reports_banner()
|
||||
|
||||
row = layout.row(align=True)
|
||||
if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False:
|
||||
row.label("Auto-run disabled", icon='ERROR')
|
||||
if bpy.data.is_saved:
|
||||
props = row.operator("wm.revert_mainfile", icon='SCREEN_BACK', text="Reload Trusted")
|
||||
props.use_scripts = True
|
||||
|
||||
row.operator("script.autoexec_warn_clear", text="Ignore")
|
||||
|
||||
# include last so text doesn't push buttons out of the header
|
||||
row.label(bpy.app.autoexec_fail_message)
|
||||
return
|
||||
|
||||
|
||||
|
||||
classes = (
|
||||
STATUSBAR_HT_header,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
from bpy.utils import register_class
|
||||
for cls in classes:
|
||||
register_class(cls)
|
@ -57,26 +57,6 @@ class TOPBAR_HT_upper_bar(Header):
|
||||
text="Back to Previous",
|
||||
)
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.template_running_jobs()
|
||||
|
||||
layout.template_reports_banner()
|
||||
|
||||
row = layout.row(align=True)
|
||||
|
||||
if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False:
|
||||
row.label("Auto-run disabled", icon='ERROR')
|
||||
if bpy.data.is_saved:
|
||||
props = row.operator("wm.revert_mainfile", icon='SCREEN_BACK', text="Reload Trusted")
|
||||
props.use_scripts = True
|
||||
|
||||
row.operator("script.autoexec_warn_clear", text="Ignore")
|
||||
|
||||
# include last so text doesn't push buttons out of the header
|
||||
row.label(bpy.app.autoexec_fail_message)
|
||||
return
|
||||
|
||||
def draw_right(self, context):
|
||||
layout = self.layout
|
||||
|
||||
|
@ -2879,10 +2879,13 @@ static void write_area_regions(WriteData *wd, ScrArea *area)
|
||||
}
|
||||
writestruct(wd, DATA, SpaceConsole, 1, sl);
|
||||
}
|
||||
#ifdef WITH_TOPBAR_WRITING
|
||||
#ifdef WITH_GLOBAL_AREA_WRITING
|
||||
else if (sl->spacetype == SPACE_TOPBAR) {
|
||||
writestruct(wd, DATA, SpaceTopBar, 1, sl);
|
||||
}
|
||||
else if (sl->spacetype == SPACE_STATUSBAR) {
|
||||
writestruct(wd, DATA, SpaceStatusBar, 1, sl);
|
||||
}
|
||||
#endif
|
||||
else if (sl->spacetype == SPACE_USERPREF) {
|
||||
writestruct(wd, DATA, SpaceUserPref, 1, sl);
|
||||
@ -2905,7 +2908,7 @@ static void write_area_map(WriteData *wd, ScrAreaMap *area_map)
|
||||
|
||||
writestruct(wd, DATA, ScrArea, 1, area);
|
||||
|
||||
#ifdef WITH_TOPBAR_WRITING
|
||||
#ifdef WITH_GLOBAL_AREA_WRITING
|
||||
writestruct(wd, DATA, ScrGlobalAreaData, 1, area->global);
|
||||
#endif
|
||||
|
||||
@ -2921,7 +2924,7 @@ static void write_windowmanager(WriteData *wd, wmWindowManager *wm)
|
||||
write_iddata(wd, &wm->id);
|
||||
|
||||
for (wmWindow *win = wm->windows.first; win; win = win->next) {
|
||||
#ifndef WITH_TOPBAR_WRITING
|
||||
#ifndef WITH_GLOBAL_AREA_WRITING
|
||||
/* Don't write global areas yet, while we make changes to them. */
|
||||
ScrAreaMap global_areas = win->global_areas;
|
||||
memset(&win->global_areas, 0, sizeof(win->global_areas));
|
||||
@ -2934,7 +2937,7 @@ static void write_windowmanager(WriteData *wd, wmWindowManager *wm)
|
||||
writestruct(wd, DATA, WorkSpaceInstanceHook, 1, win->workspace_hook);
|
||||
writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format);
|
||||
|
||||
#ifdef WITH_TOPBAR_WRITING
|
||||
#ifdef WITH_GLOBAL_AREA_WRITING
|
||||
write_area_map(wd, &win->global_areas);
|
||||
#else
|
||||
win->global_areas = global_areas;
|
||||
|
@ -54,6 +54,7 @@ if(WITH_BLENDER)
|
||||
add_subdirectory(space_outliner)
|
||||
add_subdirectory(space_script)
|
||||
add_subdirectory(space_sequencer)
|
||||
add_subdirectory(space_statusbar)
|
||||
add_subdirectory(space_text)
|
||||
add_subdirectory(space_topbar)
|
||||
add_subdirectory(space_userpref)
|
||||
|
@ -119,9 +119,6 @@ int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *bl
|
||||
void ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa);
|
||||
void ED_area_exit(struct bContext *C, struct ScrArea *sa);
|
||||
int ED_screen_area_active(const struct bContext *C);
|
||||
void ED_screen_global_topbar_area_create(
|
||||
struct wmWindow *win,
|
||||
const struct bScreen *screen);
|
||||
void ED_screen_global_areas_create(
|
||||
struct wmWindow *win);
|
||||
void ED_area_do_listen(struct bScreen *sc, ScrArea *sa, struct wmNotifier *note, Scene *scene,
|
||||
|
@ -57,6 +57,7 @@ void ED_spacetype_logic(void);
|
||||
void ED_spacetype_console(void);
|
||||
void ED_spacetype_userpref(void);
|
||||
void ED_spacetype_clip(void);
|
||||
void ED_spacetype_statusbar(void);
|
||||
void ED_spacetype_topbar(void);
|
||||
|
||||
/* calls for instancing and freeing spacetype static data
|
||||
|
@ -1259,7 +1259,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
|
||||
region_rect_recursive(win, sa, ar->next, remainder, overlap_remainder, quad);
|
||||
}
|
||||
|
||||
static void area_calc_totrct(ScrArea *sa, int window_size_x, int window_size_y)
|
||||
static void area_calc_totrct(ScrArea *sa, const rcti *window_rect)
|
||||
{
|
||||
short px = (short)U.pixelsize;
|
||||
|
||||
@ -1269,16 +1269,16 @@ static void area_calc_totrct(ScrArea *sa, int window_size_x, int window_size_y)
|
||||
sa->totrct.ymax = sa->v2->vec.y;
|
||||
|
||||
/* scale down totrct by 1 pixel on all sides not matching window borders */
|
||||
if (sa->totrct.xmin > 0) {
|
||||
if (sa->totrct.xmin > window_rect->xmin) {
|
||||
sa->totrct.xmin += px;
|
||||
}
|
||||
if (sa->totrct.xmax < (window_size_x - 1)) {
|
||||
if (sa->totrct.xmax < (window_rect->xmax - 1)) {
|
||||
sa->totrct.xmax -= px;
|
||||
}
|
||||
if (sa->totrct.ymin > 0) {
|
||||
if (sa->totrct.ymin > window_rect->ymin) {
|
||||
sa->totrct.ymin += px;
|
||||
}
|
||||
if (sa->totrct.ymax < (window_size_y - 1)) {
|
||||
if (sa->totrct.ymax < (window_rect->ymax - 1)) {
|
||||
sa->totrct.ymax -= px;
|
||||
}
|
||||
/* Although the following asserts are correct they lead to a very unstable Blender.
|
||||
@ -1373,15 +1373,15 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
|
||||
|
||||
void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *area)
|
||||
{
|
||||
rcti rect, overlap_rect;
|
||||
rcti window_rect;
|
||||
|
||||
if (!(area->flag & AREA_FLAG_REGION_SIZE_UPDATE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int size_x = WM_window_pixels_x(win);
|
||||
const int size_y = WM_window_pixels_y(win);
|
||||
rcti rect, overlap_rect;
|
||||
|
||||
area_calc_totrct(area, size_x, size_y);
|
||||
WM_window_rect_calc(win, &window_rect);
|
||||
area_calc_totrct(area, &window_rect);
|
||||
|
||||
/* region rect sizes */
|
||||
rect = area->totrct;
|
||||
@ -1406,15 +1406,14 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
|
||||
WorkSpace *workspace = WM_window_get_active_workspace(win);
|
||||
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
|
||||
Scene *scene = WM_window_get_active_scene(win);
|
||||
|
||||
const int window_size_x = WM_window_pixels_x(win);
|
||||
const int window_size_y = WM_window_pixels_y(win);
|
||||
ARegion *ar;
|
||||
rcti rect, overlap_rect;
|
||||
rcti window_rect;
|
||||
|
||||
if (ED_area_is_global(sa) && (sa->global->flag & GLOBAL_AREA_IS_HIDDEN)) {
|
||||
return;
|
||||
}
|
||||
WM_window_rect_calc(win, &window_rect);
|
||||
|
||||
/* set typedefinitions */
|
||||
sa->type = BKE_spacetype_from_id(sa->spacetype);
|
||||
@ -1428,7 +1427,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
|
||||
ar->type = BKE_regiontype_from_id(sa->type, ar->regiontype);
|
||||
|
||||
/* area sizes */
|
||||
area_calc_totrct(sa, window_size_x, window_size_y);
|
||||
area_calc_totrct(sa, &window_rect);
|
||||
|
||||
/* region rect sizes */
|
||||
rect = sa->totrct;
|
||||
|
@ -111,10 +111,12 @@ bool scredge_is_horizontal(ScrEdge *se)
|
||||
return (se->v1->vec.y == se->v2->vec.y);
|
||||
}
|
||||
|
||||
/* need win size to make sure not to include edges along screen edge */
|
||||
/**
|
||||
* \param bounds_rect: Either window or screen bounds. Used to exclude edges along window/screen edges.
|
||||
*/
|
||||
ScrEdge *screen_area_map_find_active_scredge(
|
||||
const ScrAreaMap *area_map,
|
||||
const int winsize_x, const int winsize_y,
|
||||
const rcti *bounds_rect,
|
||||
const int mx, const int my)
|
||||
{
|
||||
int safety = U.widget_unit / 10;
|
||||
@ -123,7 +125,7 @@ ScrEdge *screen_area_map_find_active_scredge(
|
||||
|
||||
for (ScrEdge *se = area_map->edgebase.first; se; se = se->next) {
|
||||
if (scredge_is_horizontal(se)) {
|
||||
if (se->v1->vec.y > 0 && se->v1->vec.y < winsize_y - 1) {
|
||||
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);
|
||||
@ -133,7 +135,7 @@ ScrEdge *screen_area_map_find_active_scredge(
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (se->v1->vec.x > 0 && se->v1->vec.x < winsize_x - 1) {
|
||||
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);
|
||||
@ -153,13 +155,17 @@ ScrEdge *screen_find_active_scredge(
|
||||
const int mx, const int my)
|
||||
{
|
||||
/* Use layout size (screen excluding global areas) for screen-layout area edges */
|
||||
const int screen_x = WM_window_screen_pixels_x(win), screen_y = WM_window_screen_pixels_y(win);
|
||||
ScrEdge *se = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(screen), screen_x, screen_y, mx, my);
|
||||
rcti screen_rect;
|
||||
ScrEdge *se;
|
||||
|
||||
WM_window_screen_rect_calc(win, &screen_rect);
|
||||
se = screen_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 */
|
||||
const int win_x = WM_window_pixels_x(win), win_y = WM_window_pixels_y(win);
|
||||
se = screen_area_map_find_active_scredge(&win->global_areas, win_x, win_y, mx, my);
|
||||
rcti win_rect;
|
||||
WM_window_rect_calc(win, &win_rect);
|
||||
se = screen_area_map_find_active_scredge(&win->global_areas, &win_rect, mx, my);
|
||||
}
|
||||
return se;
|
||||
}
|
||||
@ -334,7 +340,7 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
|
||||
/**
|
||||
* Empty screen, with 1 dummy area without spacedata. Uses window size.
|
||||
*/
|
||||
bScreen *screen_add(const char *name, const int winsize_x, const int winsize_y)
|
||||
bScreen *screen_add(const char *name, const rcti *rect)
|
||||
{
|
||||
bScreen *sc;
|
||||
ScrVert *sv1, *sv2, *sv3, *sv4;
|
||||
@ -343,10 +349,10 @@ bScreen *screen_add(const char *name, const int winsize_x, const int winsize_y)
|
||||
sc->do_refresh = true;
|
||||
sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN;
|
||||
|
||||
sv1 = screen_addvert(sc, 0, 0);
|
||||
sv2 = screen_addvert(sc, 0, winsize_y - 1);
|
||||
sv3 = screen_addvert(sc, winsize_x - 1, winsize_y - 1);
|
||||
sv4 = screen_addvert(sc, winsize_x - 1, 0);
|
||||
sv1 = screen_addvert(sc, rect->xmin, rect->ymin);
|
||||
sv2 = screen_addvert(sc, rect->xmin, rect->ymax - 1);
|
||||
sv3 = screen_addvert(sc, rect->xmax - 1, rect->ymax - 1);
|
||||
sv4 = screen_addvert(sc, rect->xmax - 1, rect->ymin);
|
||||
|
||||
screen_addedge(sc, sv1, sv2);
|
||||
screen_addedge(sc, sv2, sv3);
|
||||
@ -546,18 +552,19 @@ void select_connected_scredge(const wmWindow *win, ScrEdge *edge)
|
||||
*/
|
||||
static void screen_vertices_scale(
|
||||
const wmWindow *win, bScreen *sc,
|
||||
int window_size_x, int window_size_y,
|
||||
int screen_size_x, int screen_size_y)
|
||||
const rcti *window_rect, const rcti *screen_rect)
|
||||
{
|
||||
/* clamp Y size of header sized areas when expanding windows
|
||||
* avoids annoying empty space around file menu */
|
||||
#define USE_HEADER_SIZE_CLAMP
|
||||
|
||||
const int headery_init = ED_area_headersize();
|
||||
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 facx, facy, tempf, min[2], max[2];
|
||||
float min[2], max[2];
|
||||
|
||||
/* calculate size */
|
||||
min[0] = min[1] = 20000.0f;
|
||||
@ -568,12 +575,6 @@ static void screen_vertices_scale(
|
||||
minmax_v2v2_v2(min, max, fv);
|
||||
}
|
||||
|
||||
/* always make 0.0 left under */
|
||||
for (sv = sc->vertbase.first; sv; sv = sv->next) {
|
||||
sv->vec.x -= min[0];
|
||||
sv->vec.y -= min[1];
|
||||
}
|
||||
|
||||
screen_size_x_prev = (max[0] - min[0]) + 1;
|
||||
screen_size_y_prev = (max[1] - min[1]) + 1;
|
||||
|
||||
@ -590,12 +591,12 @@ static void screen_vertices_scale(
|
||||
sa->temp = 0;
|
||||
|
||||
if (ar && !(ar->flag & RGN_FLAG_HIDDEN)) {
|
||||
if (sa->v2->vec.y == screen_size_y_prev) {
|
||||
if (sa->v2->vec.y == max[1]) {
|
||||
if ((sa->v2->vec.y - sa->v1->vec.y) < headery_margin_max) {
|
||||
sa->temp = TEMP_TOP;
|
||||
}
|
||||
}
|
||||
else if (sa->v1->vec.y == 0) {
|
||||
else if (sa->v1->vec.y == min[1]) {
|
||||
if ((sa->v2->vec.y - sa->v1->vec.y) < headery_margin_max) {
|
||||
sa->temp = TEMP_BOTTOM;
|
||||
}
|
||||
@ -607,26 +608,16 @@ static void screen_vertices_scale(
|
||||
|
||||
|
||||
if (screen_size_x_prev != screen_size_x || screen_size_y_prev != screen_size_y) {
|
||||
facx = ((float)screen_size_x - 1) / ((float)screen_size_x_prev - 1);
|
||||
facy = ((float)screen_size_y) / ((float)screen_size_y_prev);
|
||||
const float facx = ((float)screen_size_x - 1) / ((float)screen_size_x_prev - 1);
|
||||
const float facy = ((float)screen_size_y) / ((float)screen_size_y_prev);
|
||||
|
||||
/* make sure it fits! */
|
||||
for (sv = sc->vertbase.first; sv; sv = sv->next) {
|
||||
/* FIXME, this re-sizing logic is no good when re-sizing the window + redrawing [#24428]
|
||||
* need some way to store these as floats internally and re-apply from there. */
|
||||
tempf = ((float)sv->vec.x) * facx;
|
||||
sv->vec.x = (short)(tempf + 0.5f);
|
||||
//sv->vec.x += AREAGRID - 1;
|
||||
//sv->vec.x -= (sv->vec.x % AREAGRID);
|
||||
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);
|
||||
|
||||
CLAMP(sv->vec.x, 0, screen_size_x - 1);
|
||||
|
||||
tempf = ((float)sv->vec.y) * facy;
|
||||
sv->vec.y = (short)(tempf + 0.5f);
|
||||
//sv->vec.y += AREAGRID - 1;
|
||||
//sv->vec.y -= (sv->vec.y % AREAGRID);
|
||||
|
||||
CLAMP(sv->vec.y, 0, screen_size_y);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,21 +681,20 @@ static void screen_vertices_scale(
|
||||
int headery = headery_init;
|
||||
|
||||
/* adjust headery if verts are along the edge of window */
|
||||
if (sa->v1->vec.y > 0)
|
||||
if (sa->v1->vec.y > window_rect->ymin)
|
||||
headery += U.pixelsize;
|
||||
if (sa->v2->vec.y < screen_size_y)
|
||||
if (sa->v2->vec.y < window_rect->ymax)
|
||||
headery += U.pixelsize;
|
||||
|
||||
if (sa->v2->vec.y - sa->v1->vec.y + 1 < headery) {
|
||||
/* lower edge */
|
||||
ScrEdge *se = BKE_screen_find_edge(sc, sa->v4, sa->v1);
|
||||
if (se && sa->v1 != sa->v2) {
|
||||
int yval;
|
||||
const int yval = sa->v2->vec.y - headery + 1;
|
||||
|
||||
select_connected_scredge(win, se);
|
||||
|
||||
/* all selected vertices get the right offset */
|
||||
yval = sa->v2->vec.y - headery + 1;
|
||||
for (sv = sc->vertbase.first; sv; sv = sv->next) {
|
||||
/* if is a collapsed area */
|
||||
if (sv != sa->v2 && sv != sa->v3) {
|
||||
@ -717,18 +707,25 @@ static void screen_vertices_scale(
|
||||
}
|
||||
}
|
||||
|
||||
/* Global areas have a fixed size that only changes with the DPI. Here we ensure that exactly this size is set.
|
||||
* TODO Assumes global area to be top-aligned. Should be made more generic */
|
||||
/* 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;
|
||||
}
|
||||
/* width */
|
||||
area->v1->vec.x = area->v2->vec.x = 0;
|
||||
area->v3->vec.x = area->v4->vec.x = window_size_x - 1;
|
||||
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->v2->vec.y = area->v3->vec.y = window_size_y - 1;
|
||||
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 - ED_area_global_size_y(area);
|
||||
break;
|
||||
case GLOBAL_AREA_ALIGN_BOTTOM:
|
||||
area->v2->vec.y = area->v3->vec.y = area->v1->vec.y + ED_area_global_size_y(area);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -802,18 +799,16 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
|
||||
|
||||
/* exception for bg mode, we only need the screen context */
|
||||
if (!G.background) {
|
||||
WM_window_set_dpi(win);
|
||||
|
||||
/* Get window pixels __after__ updating window DPI! */
|
||||
const int window_size_x = WM_window_pixels_x(win);
|
||||
const int window_size_y = WM_window_pixels_y(win);
|
||||
const int screen_size_x = WM_window_screen_pixels_x(win);
|
||||
const int screen_size_y = WM_window_screen_pixels_y(win);
|
||||
rcti window_rect, screen_rect;
|
||||
|
||||
/* header size depends on DPI, let's verify */
|
||||
WM_window_set_dpi(win);
|
||||
screen_refresh_headersizes();
|
||||
|
||||
screen_vertices_scale(win, screen, window_size_x, window_size_y, screen_size_x, screen_size_y);
|
||||
WM_window_rect_calc(win, &window_rect);
|
||||
WM_window_screen_rect_calc(win, &screen_rect); /* Get screen bounds __after__ updating window DPI! */
|
||||
|
||||
screen_vertices_scale(win, screen, &window_rect, &screen_rect);
|
||||
|
||||
ED_screen_areas_iter(win, screen, area) {
|
||||
/* set spacetype and region callbacks, calls init() */
|
||||
@ -921,8 +916,6 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmWindow *prevwin = CTX_wm_window(C);
|
||||
ScrArea *sa;
|
||||
ARegion *ar;
|
||||
|
||||
CTX_wm_window_set(C, window);
|
||||
|
||||
@ -933,13 +926,14 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
|
||||
|
||||
screen->active_region = NULL;
|
||||
|
||||
for (ar = screen->regionbase.first; ar; ar = ar->next) {
|
||||
for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) {
|
||||
ED_region_exit(C, ar);
|
||||
}
|
||||
for (sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
ED_area_exit(C, sa);
|
||||
}
|
||||
for (sa = window->global_areas.areabase.first; sa; sa = sa->next) {
|
||||
/* Don't use ED_screen_areas_iter here, it skips hidden areas. */
|
||||
for (ScrArea *sa = window->global_areas.areabase.first; sa; sa = sa->next) {
|
||||
ED_area_exit(C, sa);
|
||||
}
|
||||
|
||||
@ -1113,39 +1107,56 @@ static ScrArea *screen_area_create_with_geometry(
|
||||
return screen_addarea_ex(area_map, bottom_left, top_left, top_right, bottom_right, spacetype);
|
||||
}
|
||||
|
||||
void ED_screen_global_topbar_area_create(wmWindow *win, const bScreen *screen)
|
||||
static void screen_global_area_create(
|
||||
wmWindow *win, eSpace_Type space_type, GlobalAreaAlign align, const rcti *rect,
|
||||
const short height_cur, const short height_min, const short height_max)
|
||||
{
|
||||
ScrArea *area = screen_area_create_with_geometry(&win->global_areas, rect, space_type);
|
||||
SpaceType *stype = BKE_spacetype_from_id(space_type);
|
||||
SpaceLink *slink = stype->new(area, WM_window_get_active_scene(win));
|
||||
|
||||
area->regionbase = slink->regionbase;
|
||||
|
||||
/* Data specific to global areas. */
|
||||
area->global = MEM_callocN(sizeof(*area->global), __func__);
|
||||
area->global->cur_fixed_height = height_cur;
|
||||
area->global->size_max = height_max;
|
||||
area->global->size_min = height_min;
|
||||
area->global->align = align;
|
||||
|
||||
BLI_addhead(&area->spacedata, slink);
|
||||
BLI_listbase_clear(&slink->regionbase);
|
||||
}
|
||||
|
||||
static void screen_global_topbar_area_create(wmWindow *win)
|
||||
{
|
||||
if (screen->temp == 0) {
|
||||
const short size_y = 2.25 * HEADERY;
|
||||
SpaceType *st;
|
||||
SpaceLink *sl;
|
||||
ScrArea *sa;
|
||||
rcti rect;
|
||||
|
||||
BLI_rcti_init(&rect, 0, WM_window_pixels_x(win) - 1, 0, WM_window_pixels_y(win) - 1);
|
||||
rect.ymin = rect.ymax - size_y;
|
||||
|
||||
sa = screen_area_create_with_geometry(&win->global_areas, &rect, SPACE_TOPBAR);
|
||||
st = BKE_spacetype_from_id(SPACE_TOPBAR);
|
||||
sl = st->new(sa, WM_window_get_active_scene(win));
|
||||
sa->regionbase = sl->regionbase;
|
||||
screen_global_area_create(win, SPACE_TOPBAR, GLOBAL_AREA_ALIGN_TOP, &rect, size_y, HEADERY, size_y);
|
||||
}
|
||||
|
||||
/* Data specific to global areas. */
|
||||
sa->global = MEM_callocN(sizeof(*sa->global), __func__);
|
||||
sa->global->cur_fixed_height = size_y;
|
||||
sa->global->size_max = size_y;
|
||||
sa->global->size_min = HEADERY;
|
||||
static void screen_global_statusbar_area_create(wmWindow *win)
|
||||
{
|
||||
const short size_y = HEADERY;
|
||||
rcti rect;
|
||||
|
||||
BLI_addhead(&sa->spacedata, sl);
|
||||
BLI_listbase_clear(&sl->regionbase);
|
||||
}
|
||||
/* Do not create more area types here! Function is called on file load (wm_window_ghostwindows_ensure). TODO */
|
||||
BLI_rcti_init(&rect, 0, WM_window_pixels_x(win) - 1, 0, WM_window_pixels_y(win) - 1);
|
||||
rect.ymax = rect.ymin + size_y;
|
||||
|
||||
screen_global_area_create(win, SPACE_STATUSBAR, GLOBAL_AREA_ALIGN_BOTTOM, &rect, size_y, size_y, size_y);
|
||||
}
|
||||
|
||||
void ED_screen_global_areas_create(wmWindow *win)
|
||||
{
|
||||
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
|
||||
ED_screen_global_topbar_area_create(win, screen);
|
||||
bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
|
||||
if (screen->temp == 0) {
|
||||
screen_global_topbar_area_create(win);
|
||||
screen_global_statusbar_area_create(win);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,7 +48,7 @@ void screen_area_update_region_sizes(wmWindowManager *wm, wmWindow *win,
|
||||
void region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade);
|
||||
|
||||
/* screen_edit.c */
|
||||
bScreen *screen_add(const char *name, const int winsize_x, const int winsize_y);
|
||||
bScreen *screen_add(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);
|
||||
@ -61,7 +61,7 @@ void select_connected_scredge(const wmWindow *win, ScrEdge *edge);
|
||||
bool scredge_is_horizontal(ScrEdge *se);
|
||||
ScrEdge *screen_area_map_find_active_scredge(
|
||||
const struct ScrAreaMap *area_map,
|
||||
const int winsize_x, const int winsize_y,
|
||||
const rcti *bounds_rect,
|
||||
const int mx, const int my);
|
||||
ScrEdge *screen_find_active_scredge(
|
||||
const wmWindow *win, const bScreen *screen,
|
||||
|
@ -842,11 +842,8 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
||||
static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
bScreen *sc = CTX_wm_screen(C);
|
||||
sActionzoneData *sad = op->customdata;
|
||||
const int screen_size_x = WM_window_screen_pixels_x(win);
|
||||
const int screen_size_y = WM_window_screen_pixels_y(win);
|
||||
|
||||
switch (event->type) {
|
||||
case MOUSEMOVE:
|
||||
@ -867,11 +864,15 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
sad->gesture_dir = 'w';
|
||||
|
||||
if (sad->az->type == AZONE_AREA) {
|
||||
const wmWindow *win = CTX_wm_window(C);
|
||||
rcti screen_rect;
|
||||
|
||||
WM_window_screen_rect_calc(win, &screen_rect);
|
||||
/* once we drag outside the actionzone, register a gesture
|
||||
* check we're not on an edge so join finds the other area */
|
||||
is_gesture = ((is_in_area_actionzone(sad->sa1, &event->x) != sad->az) &&
|
||||
(screen_area_map_find_active_scredge(
|
||||
AREAMAP_FROM_SCREEN(sc), screen_size_x, screen_size_y, event->x, event->y) == NULL));
|
||||
AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y) == NULL));
|
||||
}
|
||||
else {
|
||||
const int delta_min = 1;
|
||||
@ -1186,10 +1187,10 @@ typedef struct sAreaMoveData {
|
||||
} sAreaMoveData;
|
||||
|
||||
/* helper call to move area-edge, sets limits
|
||||
* need window size in order to get correct limits */
|
||||
* need window bounds in order to get correct limits */
|
||||
static void area_move_set_limits(
|
||||
wmWindow *win, bScreen *sc, int dir,
|
||||
const int winsize_x, const int winsize_y,
|
||||
const rcti *screen_rect,
|
||||
int *bigger, int *smaller,
|
||||
bool *use_bigger_smaller_snap)
|
||||
{
|
||||
@ -1242,9 +1243,9 @@ static void area_move_set_limits(
|
||||
int y1;
|
||||
areamin = areaminy;
|
||||
|
||||
if (sa->v1->vec.y > 0)
|
||||
if (sa->v1->vec.y > screen_rect->ymin)
|
||||
areamin += U.pixelsize;
|
||||
if (sa->v2->vec.y < winsize_y - 1)
|
||||
if (sa->v2->vec.y < (screen_rect->ymax - 1))
|
||||
areamin += U.pixelsize;
|
||||
|
||||
y1 = sa->v2->vec.y - sa->v1->vec.y + 1 - areamin;
|
||||
@ -1259,9 +1260,9 @@ static void area_move_set_limits(
|
||||
int x1;
|
||||
areamin = AREAMINX;
|
||||
|
||||
if (sa->v1->vec.x > 0)
|
||||
if (sa->v1->vec.x > screen_rect->xmin)
|
||||
areamin += U.pixelsize;
|
||||
if (sa->v4->vec.x < winsize_x - 1)
|
||||
if (sa->v4->vec.x < (screen_rect->xmax - 1))
|
||||
areamin += U.pixelsize;
|
||||
|
||||
x1 = sa->v4->vec.x - sa->v1->vec.x + 1 - areamin;
|
||||
@ -1283,8 +1284,7 @@ static int area_move_init(bContext *C, wmOperator *op)
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
ScrEdge *actedge;
|
||||
sAreaMoveData *md;
|
||||
const int screen_size_x = WM_window_screen_pixels_x(win);
|
||||
const int screen_size_y = WM_window_screen_pixels_y(win);
|
||||
rcti screen_rect;
|
||||
int x, y;
|
||||
|
||||
/* required properties */
|
||||
@ -1308,8 +1308,10 @@ static int area_move_init(bContext *C, wmOperator *op)
|
||||
v1->editflag = v1->flag;
|
||||
}
|
||||
|
||||
WM_window_screen_rect_calc(win, &screen_rect);
|
||||
|
||||
bool use_bigger_smaller_snap = false;
|
||||
area_move_set_limits(win, sc, md->dir, screen_size_x, screen_size_y,
|
||||
area_move_set_limits(win, sc, md->dir, &screen_rect,
|
||||
&md->bigger, &md->smaller,
|
||||
&use_bigger_smaller_snap);
|
||||
|
||||
@ -1772,14 +1774,15 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
bScreen *sc = CTX_wm_screen(C);
|
||||
sAreaSplitData *sd;
|
||||
const int screen_size_x = WM_window_screen_pixels_x(win);
|
||||
const int screen_size_y = WM_window_screen_pixels_y(win);
|
||||
rcti screen_rect;
|
||||
int dir;
|
||||
|
||||
/* no full window splitting allowed */
|
||||
if (sc->state != SCREENNORMAL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
WM_window_screen_rect_calc(win, &screen_rect);
|
||||
|
||||
if (event->type == EVT_ACTIONZONE_AREA) {
|
||||
sActionzoneData *sad = event->customdata;
|
||||
|
||||
@ -1826,7 +1829,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
else
|
||||
y = event->x;
|
||||
|
||||
actedge = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), screen_size_x, screen_size_y, x, y);
|
||||
actedge = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), &screen_rect, x, y);
|
||||
if (actedge == NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
@ -1846,7 +1849,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
||||
/* do the split */
|
||||
if (area_split_apply(C, op)) {
|
||||
area_move_set_limits(win, sc, dir, screen_size_x, screen_size_y, &sd->bigger, &sd->smaller, NULL);
|
||||
area_move_set_limits(win, sc, dir, &screen_rect, &sd->bigger, &sd->smaller, NULL);
|
||||
|
||||
/* add temp handler for edge move or cancel */
|
||||
WM_event_add_modal_handler(C, op);
|
||||
@ -2731,7 +2734,8 @@ static int screen_maximize_area_poll(bContext *C)
|
||||
const bScreen *screen = CTX_wm_screen(C);
|
||||
const ScrArea *area = CTX_wm_area(C);
|
||||
return ED_operator_areaactive(C) &&
|
||||
((screen->state != SCREENNORMAL) || (area->spacetype != SPACE_TOPBAR));
|
||||
/* Don't allow maximizing global areas but allow minimizing from them. */
|
||||
((screen->state != SCREENNORMAL) || !ED_area_is_global(area));
|
||||
}
|
||||
|
||||
static void SCREEN_OT_screen_full_area(wmOperatorType *ot)
|
||||
@ -3047,17 +3051,16 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
|
||||
|
||||
static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
bScreen *sc = CTX_wm_screen(C);
|
||||
const wmWindow *win = CTX_wm_window(C);
|
||||
const bScreen *sc = CTX_wm_screen(C);
|
||||
uiPopupMenu *pup;
|
||||
uiLayout *layout;
|
||||
PointerRNA ptr;
|
||||
ScrEdge *actedge;
|
||||
const int screen_size_x = WM_window_screen_pixels_x(win);
|
||||
const int screen_size_y = WM_window_screen_pixels_y(win);
|
||||
rcti screen_rect;
|
||||
|
||||
actedge = screen_area_map_find_active_scredge(
|
||||
AREAMAP_FROM_SCREEN(sc), screen_size_x, screen_size_y, event->x, event->y);
|
||||
WM_window_screen_rect_calc(win, &screen_rect);
|
||||
actedge = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y);
|
||||
|
||||
if (actedge == NULL) return OPERATOR_CANCELLED;
|
||||
|
||||
|
@ -50,13 +50,13 @@ WorkSpaceLayout *ED_workspace_layout_add(
|
||||
wmWindow *win,
|
||||
const char *name)
|
||||
{
|
||||
const int screen_size_x = WM_window_screen_pixels_x(win);
|
||||
const int screen_size_y = WM_window_screen_pixels_y(win);
|
||||
bScreen *screen;
|
||||
rcti screen_rect;
|
||||
|
||||
bScreen *screen = screen_add(name, screen_size_x, screen_size_y);
|
||||
WorkSpaceLayout *layout = BKE_workspace_layout_add(workspace, screen, name);
|
||||
WM_window_screen_rect_calc(win, &screen_rect);
|
||||
screen = screen_add(name, &screen_rect);
|
||||
|
||||
return layout;
|
||||
return BKE_workspace_layout_add(workspace, screen, name);
|
||||
}
|
||||
|
||||
WorkSpaceLayout *ED_workspace_layout_duplicate(
|
||||
|
@ -97,6 +97,7 @@ void ED_spacetypes_init(void)
|
||||
ED_spacetype_console();
|
||||
ED_spacetype_userpref();
|
||||
ED_spacetype_clip();
|
||||
ED_spacetype_statusbar();
|
||||
ED_spacetype_topbar();
|
||||
// ...
|
||||
|
||||
|
45
source/blender/editors/space_statusbar/CMakeLists.txt
Normal file
45
source/blender/editors/space_statusbar/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Contributor(s): Jacques Beaurain.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
../include
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blenloader
|
||||
../../blentranslation
|
||||
../../gpu
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${GLEW_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
space_statusbar.c
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_editor_space_statusbar "${SRC}" "${INC}" "${INC_SYS}")
|
200
source/blender/editors/space_statusbar/space_statusbar.c
Normal file
200
source/blender/editors/space_statusbar/space_statusbar.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/editors/space_statusbar/space_statusbar.c
|
||||
* \ingroup spstatusbar
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
#include "ED_space_api.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
#include "WM_message.h"
|
||||
|
||||
|
||||
/* ******************** default callbacks for statusbar space ******************** */
|
||||
|
||||
static SpaceLink *statusbar_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
|
||||
{
|
||||
ARegion *ar;
|
||||
SpaceStatusBar *sstatusbar;
|
||||
|
||||
sstatusbar = MEM_callocN(sizeof(*sstatusbar), "init statusbar");
|
||||
sstatusbar->spacetype = SPACE_STATUSBAR;
|
||||
|
||||
/* header regions */
|
||||
/* *** NOTE: ***
|
||||
* Python layout code (space_statusbar.py) depends on the list order of
|
||||
* these! Not nice at all, but the only way to identify the correct header
|
||||
* to draw to is using alignment + list position. It can't use alignment
|
||||
* only since code below has to set two right aligned regions - XXX. */
|
||||
ar = MEM_callocN(sizeof(*ar), "right aligned header for statusbar");
|
||||
BLI_addtail(&sstatusbar->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_HEADER;
|
||||
ar->alignment = RGN_ALIGN_RIGHT;
|
||||
ar = MEM_callocN(sizeof(*ar), "center header for statusbar");
|
||||
BLI_addtail(&sstatusbar->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_HEADER;
|
||||
ar->alignment = RGN_ALIGN_RIGHT; /* Right aligned too, so region layout code scales it correctly. */
|
||||
ar = MEM_callocN(sizeof(*ar), "left aligned header for statusbar");
|
||||
BLI_addtail(&sstatusbar->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_HEADER;
|
||||
ar->alignment = RGN_ALIGN_NONE;
|
||||
|
||||
return (SpaceLink *)sstatusbar;
|
||||
}
|
||||
|
||||
/* not spacelink itself */
|
||||
static void statusbar_free(SpaceLink *UNUSED(sl))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* spacetype; init callback */
|
||||
static void statusbar_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static SpaceLink *statusbar_duplicate(SpaceLink *sl)
|
||||
{
|
||||
SpaceStatusBar *sstatusbarn = MEM_dupallocN(sl);
|
||||
|
||||
/* clear or remove stuff from old */
|
||||
|
||||
return (SpaceLink *)sstatusbarn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* add handlers, stuff you only do once or on area/region changes */
|
||||
static void statusbar_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
|
||||
{
|
||||
if (ELEM(region->alignment, RGN_ALIGN_RIGHT)) {
|
||||
region->flag |= RGN_FLAG_DYNAMIC_SIZE;
|
||||
}
|
||||
ED_region_header_init(region);
|
||||
}
|
||||
|
||||
static void statusbar_operatortypes(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void statusbar_keymap(struct wmKeyConfig *UNUSED(keyconf))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void statusbar_header_region_listener(
|
||||
bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
|
||||
wmNotifier *wmn, const Scene *UNUSED(scene))
|
||||
{
|
||||
/* context changes */
|
||||
switch (wmn->category) {
|
||||
case NC_SCREEN:
|
||||
if (ELEM(wmn->data, ND_LAYER, ND_SCREENCAST, ND_ANIMPLAY)) {
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
break;
|
||||
case NC_WM:
|
||||
if (wmn->data == ND_JOB)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_SCENE:
|
||||
if (wmn->data == ND_RENDER_RESULT)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_SPACE:
|
||||
if (wmn->data == ND_SPACE_INFO)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_ID:
|
||||
if (wmn->action == NA_RENAME)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void statusbar_header_region_message_subscribe(
|
||||
const bContext *UNUSED(C),
|
||||
WorkSpace *UNUSED(workspace), Scene *UNUSED(scene),
|
||||
bScreen *UNUSED(screen), ScrArea *UNUSED(sa), 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, Window, view_layer, &msg_sub_value_region_tag_redraw);
|
||||
WM_msg_subscribe_rna_anon_prop(mbus, ViewLayer, name, &msg_sub_value_region_tag_redraw);
|
||||
}
|
||||
|
||||
/* only called once, from space/spacetypes.c */
|
||||
void ED_spacetype_statusbar(void)
|
||||
{
|
||||
SpaceType *st = MEM_callocN(sizeof(*st), "spacetype statusbar");
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_STATUSBAR;
|
||||
strncpy(st->name, "Status Bar", BKE_ST_MAXNAME);
|
||||
|
||||
st->new = statusbar_new;
|
||||
st->free = statusbar_free;
|
||||
st->init = statusbar_init;
|
||||
st->duplicate = statusbar_duplicate;
|
||||
st->operatortypes = statusbar_operatortypes;
|
||||
st->keymap = statusbar_keymap;
|
||||
|
||||
/* regions: header window */
|
||||
art = MEM_callocN(sizeof(*art), "spacetype statusbar header region");
|
||||
art->regionid = RGN_TYPE_HEADER;
|
||||
art->prefsizey = HEADERY;
|
||||
art->prefsizex = UI_UNIT_X * 5; /* Mainly to avoid glitches */
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
|
||||
art->init = statusbar_header_region_init;
|
||||
art->layout = ED_region_header_layout;
|
||||
art->draw = ED_region_header_draw;
|
||||
art->listener = statusbar_header_region_listener;
|
||||
art->message_subscribe = statusbar_header_region_message_subscribe;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
}
|
@ -227,7 +227,7 @@ typedef struct uiPreview { /* some preview UI data need to be saved in
|
||||
} uiPreview;
|
||||
|
||||
/* These two lines with # tell makesdna this struct can be excluded.
|
||||
* Should be: #ifndef WITH_TOPBAR_WRITING */
|
||||
* Should be: #ifndef WITH_GLOBAL_AREA_WRITING */
|
||||
#
|
||||
#
|
||||
typedef struct ScrGlobalAreaData {
|
||||
@ -240,14 +240,21 @@ typedef struct ScrGlobalAreaData {
|
||||
* if they are 'collapsed' or not. Value is set on area creation and not
|
||||
* touched afterwards. */
|
||||
short size_min, size_max;
|
||||
short align; /* GlobalAreaAlign */
|
||||
|
||||
short flag; /* GlobalAreaFlag */
|
||||
short pad;
|
||||
} ScrGlobalAreaData;
|
||||
|
||||
enum GlobalAreaFlag {
|
||||
GLOBAL_AREA_IS_HIDDEN = (1 << 0),
|
||||
};
|
||||
|
||||
typedef enum GlobalAreaAlign {
|
||||
GLOBAL_AREA_ALIGN_TOP,
|
||||
GLOBAL_AREA_ALIGN_BOTTOM,
|
||||
} GlobalAreaAlign;
|
||||
|
||||
typedef struct ScrArea_Runtime {
|
||||
struct bToolRef *tool;
|
||||
char is_tool_set;
|
||||
|
@ -67,9 +67,9 @@ struct MovieClipScopes;
|
||||
struct Mask;
|
||||
struct BLI_mempool;
|
||||
|
||||
/* TODO 2.8: We don't write the topbar to files currently. Uncomment this
|
||||
/* TODO 2.8: We don't write the global areas to files currently. Uncomment
|
||||
* define to enable writing (should become the default in a bit). */
|
||||
//#define WITH_TOPBAR_WRITING
|
||||
//#define WITH_GLOBAL_AREA_WRITING
|
||||
|
||||
|
||||
/* SpaceLink (Base) ==================================== */
|
||||
@ -1327,7 +1327,7 @@ typedef enum eSpaceClip_GPencil_Source {
|
||||
/* Top Bar ======================================= */
|
||||
|
||||
/* These two lines with # tell makesdna this struct can be excluded.
|
||||
* Should be: #ifndef WITH_TOPBAR_WRITING */
|
||||
* Should be: #ifndef WITH_GLOBAL_AREA_WRITING */
|
||||
#
|
||||
#
|
||||
typedef struct SpaceTopBar {
|
||||
@ -1338,6 +1338,20 @@ typedef struct SpaceTopBar {
|
||||
int pad;
|
||||
} SpaceTopBar;
|
||||
|
||||
/* Status Bar ======================================= */
|
||||
|
||||
/* These two lines with # tell makesdna this struct can be excluded.
|
||||
* Should be: #ifndef WITH_GLOBAL_AREA_WRITING */
|
||||
#
|
||||
#
|
||||
typedef struct SpaceStatusBar {
|
||||
SpaceLink *next, *prev;
|
||||
ListBase regionbase; /* storage of regions for inactive spaces */
|
||||
int spacetype;
|
||||
|
||||
int pad;
|
||||
} SpaceStatusBar;
|
||||
|
||||
|
||||
/* **************** SPACE DEFINES ********************* */
|
||||
|
||||
@ -1369,8 +1383,9 @@ typedef enum eSpace_Type {
|
||||
SPACE_USERPREF = 19,
|
||||
SPACE_CLIP = 20,
|
||||
SPACE_TOPBAR = 21,
|
||||
SPACE_STATUSBAR = 22,
|
||||
|
||||
SPACE_TYPE_LAST = SPACE_TOPBAR
|
||||
SPACE_TYPE_LAST = SPACE_STATUSBAR
|
||||
} eSpace_Type;
|
||||
|
||||
/* use for function args */
|
||||
|
@ -145,7 +145,7 @@ static const EnumPropertyItem *rna_Area_type_itemf(bContext *UNUSED(C), PointerR
|
||||
|
||||
/* +1 to skip SPACE_EMPTY */
|
||||
for (const EnumPropertyItem *item_from = rna_enum_space_type_items + 1; item_from->identifier; item_from++) {
|
||||
if (ELEM(item_from->value, SPACE_TOPBAR)) {
|
||||
if (ELEM(item_from->value, SPACE_TOPBAR, SPACE_STATUSBAR)) {
|
||||
continue;
|
||||
}
|
||||
RNA_enum_item_add(&item, &totitem, item_from);
|
||||
@ -166,7 +166,7 @@ static int rna_Area_type_get(PointerRNA *ptr)
|
||||
|
||||
static void rna_Area_type_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
if (ELEM(value, SPACE_TOPBAR)) {
|
||||
if (ELEM(value, SPACE_TOPBAR, SPACE_STATUSBAR)) {
|
||||
/* Special case: An area can not be set to show the top-bar editor (or
|
||||
* other global areas). However it should still be possible to identify
|
||||
* its type from Python. */
|
||||
|
@ -90,8 +90,11 @@ const EnumPropertyItem rna_enum_space_type_items[] = {
|
||||
"advanced editing and script development"},
|
||||
{SPACE_INFO, "INFO", ICON_INFO, "Info", "Main menu bar and list of error messages "
|
||||
"(drag down to expand and display)"},
|
||||
/* Special case: Top-bar isn't supposed to be a regular editor for the user. */
|
||||
{SPACE_TOPBAR, "TOPBAR", ICON_NONE, "Top Bar", "Global bar at the top of the screen for global per-window settings"},
|
||||
/* Special case: Top-bar and Status-bar aren't supposed to be a regular editor for the user. */
|
||||
{SPACE_TOPBAR, "TOPBAR", ICON_NONE, "Top Bar", "Global bar at the top of the screen for "
|
||||
"global per-window settings"},
|
||||
{SPACE_STATUSBAR, "STATUSBAR", ICON_NONE, "Status Bar", "Global bar at the bottom of the "
|
||||
"screen for general status information"},
|
||||
|
||||
/* Data */
|
||||
{0, "", ICON_NONE, "Data", ""},
|
||||
|
@ -102,8 +102,8 @@ void WM_check (struct bContext *C);
|
||||
|
||||
int WM_window_pixels_x(const struct wmWindow *win);
|
||||
int WM_window_pixels_y(const struct wmWindow *win);
|
||||
int WM_window_screen_pixels_x(const struct wmWindow *win);
|
||||
int WM_window_screen_pixels_y(const struct wmWindow *win);
|
||||
void WM_window_rect_calc(const struct wmWindow *win, struct rcti *r_rect);
|
||||
void WM_window_screen_rect_calc(const struct wmWindow *win, struct rcti *r_rect);
|
||||
bool WM_window_is_fullscreen(struct wmWindow *win);
|
||||
|
||||
void WM_windows_scene_data_sync(const ListBase *win_lb, struct Scene *scene) ATTR_NONNULL();
|
||||
|
@ -2135,23 +2135,44 @@ int WM_window_pixels_y(const wmWindow *win)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total pixels that are usable by the screen-layouts, excluding global areas.
|
||||
* Get boundaries usable by all window contents, including global areas.
|
||||
*/
|
||||
int WM_window_screen_pixels_x(const wmWindow *win)
|
||||
void WM_window_rect_calc(const wmWindow *win, rcti *r_rect)
|
||||
{
|
||||
return WM_window_pixels_x(win);
|
||||
BLI_rcti_init(r_rect, 0, WM_window_pixels_x(win), 0, WM_window_pixels_y(win));
|
||||
}
|
||||
int WM_window_screen_pixels_y(const wmWindow *win)
|
||||
/**
|
||||
* Get boundaries usable by screen-layouts, excluding global areas.
|
||||
* \note Depends on U.dpi_fac. Should that be outdated, call #WM_window_set_dpi first.
|
||||
*/
|
||||
void WM_window_screen_rect_calc(const wmWindow *win, rcti *r_rect)
|
||||
{
|
||||
short screen_size_y = WM_window_pixels_y(win);
|
||||
rcti rect;
|
||||
|
||||
for (ScrArea *sa = win->global_areas.areabase.first; sa; sa = sa->next) {
|
||||
if ((sa->global->flag & GLOBAL_AREA_IS_HIDDEN) == 0) {
|
||||
screen_size_y -= ED_area_global_size_y(sa);
|
||||
BLI_rcti_init(&rect, 0, WM_window_pixels_x(win), 0, WM_window_pixels_y(win));
|
||||
|
||||
/* Substract global areas from screen rectangle. */
|
||||
for (ScrArea *global_area = win->global_areas.areabase.first; global_area; global_area = global_area->next) {
|
||||
if (global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (global_area->global->align) {
|
||||
case GLOBAL_AREA_ALIGN_TOP:
|
||||
rect.ymax -= ED_area_global_size_y(global_area);
|
||||
break;
|
||||
case GLOBAL_AREA_ALIGN_BOTTOM:
|
||||
rect.ymin += ED_area_global_size_y(global_area);
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return screen_size_y;
|
||||
BLI_assert(rect.xmin < rect.xmax);
|
||||
BLI_assert(rect.ymin < rect.ymax);
|
||||
*r_rect = rect;
|
||||
}
|
||||
|
||||
bool WM_window_is_fullscreen(wmWindow *win)
|
||||
|
Loading…
Reference in New Issue
Block a user