Finish porting of borders and layout
This commit is contained in:
parent
e30f88d382
commit
0ec793e8bc
@ -11,20 +11,20 @@ from .fast_data_types import (
|
||||
from .utils import color_as_int, load_shaders, pt_to_px
|
||||
|
||||
|
||||
def vertical_edge(color, width, top, bottom, left):
|
||||
add_borders_rect(left, top, left + width, bottom, color)
|
||||
def vertical_edge(os_window_id, tab_id, color, width, top, bottom, left):
|
||||
add_borders_rect(os_window_id, tab_id, left, top, left + width, bottom, color)
|
||||
|
||||
|
||||
def horizontal_edge(color, height, left, right, top):
|
||||
add_borders_rect(left, top, right, top + height, color)
|
||||
def horizontal_edge(os_window_id, tab_id, color, height, left, right, top):
|
||||
add_borders_rect(os_window_id, tab_id, left, top, right, top + height, color)
|
||||
|
||||
|
||||
def edge(func, color, sz, a, b):
|
||||
return partial(func, color, sz, a, b)
|
||||
def edge(func, os_window_id, tab_id, color, sz, a, b):
|
||||
return partial(func, os_window_id, tab_id, color, sz, a, b)
|
||||
|
||||
|
||||
def border(color, sz, left, top, right, bottom):
|
||||
horz = edge(horizontal_edge, color, sz, left, right)
|
||||
def border(os_window_id, tab_id, color, sz, left, top, right, bottom):
|
||||
horz = edge(horizontal_edge, os_window_id, tab_id, color, sz, left, right)
|
||||
horz(top), horz(bottom - sz) # top, bottom edges
|
||||
vert = edge(vertical_edge, color, sz, top, bottom)
|
||||
vert(left), vert(right - sz) # left, right edges
|
||||
@ -32,11 +32,17 @@ def border(color, sz, left, top, right, bottom):
|
||||
|
||||
class Borders:
|
||||
|
||||
def __init__(self, opts):
|
||||
program_initialized = False
|
||||
|
||||
def __init__(self, os_window_id, tab_id, opts):
|
||||
self.os_window_id = os_window_id
|
||||
self.tab_id = tab_id
|
||||
self.border_width = pt_to_px(opts.window_border_width)
|
||||
self.padding_width = pt_to_px(opts.window_padding_width)
|
||||
compile_program(BORDERS_PROGRAM, *load_shaders('border'))
|
||||
init_borders_program()
|
||||
if not Borders.program_initialized:
|
||||
compile_program(BORDERS_PROGRAM, *load_shaders('border'))
|
||||
init_borders_program()
|
||||
Borders.program_initialized = True
|
||||
self.background = color_as_int(opts.background)
|
||||
self.active_border = color_as_int(opts.active_border_color)
|
||||
self.inactive_border = color_as_int(opts.inactive_border_color)
|
||||
@ -49,9 +55,9 @@ class Borders:
|
||||
extra_blank_rects,
|
||||
draw_window_borders=True
|
||||
):
|
||||
add_borders_rect(0, 0, 0, 0, 0)
|
||||
add_borders_rect(self.os_window_id, self.tab_id, 0, 0, 0, 0, 0)
|
||||
for br in chain(current_layout.blank_rects, extra_blank_rects):
|
||||
add_borders_rect(*br, self.background)
|
||||
add_borders_rect(self.os_window_id, self.tab_id, *br, self.background)
|
||||
bw, pw = self.border_width, self.padding_width
|
||||
fw = bw + pw
|
||||
|
||||
@ -62,6 +68,7 @@ class Borders:
|
||||
# Draw the border rectangles
|
||||
color = self.active_border if w is active_window else self.inactive_border
|
||||
border(
|
||||
self.os_window_id, self.tab_id,
|
||||
color, bw, g.left - fw, g.top - fw, g.right + fw,
|
||||
g.bottom + fw
|
||||
)
|
||||
@ -69,6 +76,7 @@ class Borders:
|
||||
# Draw the background rectangles over the padding region
|
||||
color = self.background
|
||||
border(
|
||||
self.os_window_id, self.tab_id,
|
||||
color, pw, g.left - pw, g.top - pw, g.right + pw,
|
||||
g.bottom + pw
|
||||
)
|
||||
|
||||
@ -7,10 +7,11 @@ from itertools import islice
|
||||
|
||||
from .constants import WindowGeometry, get_boss
|
||||
from .utils import pt_to_px
|
||||
from .fast_data_types import viewport_for_window
|
||||
|
||||
|
||||
def available_height():
|
||||
return viewport_size.height - get_boss().current_tab_bar_height
|
||||
viewport_width = viewport_height = 400
|
||||
cell_width = cell_height = 20
|
||||
|
||||
|
||||
def layout_dimension(length, cell_length, number_of_windows=1, border_length=0, margin_length=0, padding_length=0, left_align=False):
|
||||
@ -74,17 +75,26 @@ class Layout:
|
||||
def set_active_window(self, windows, active_window_idx):
|
||||
pass
|
||||
|
||||
def __call__(self, windows, active_window_idx):
|
||||
def __call__(self, os_window_id, windows, active_window_idx):
|
||||
global viewport_width, viewport_height, cell_width, cell_height
|
||||
viewport_width, viewport_height, cell_width, cell_height = viewport_for_window(os_window_id)
|
||||
self.do_layout(windows, active_window_idx)
|
||||
|
||||
def do_layout(self, windows, active_window_idx):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def available_height():
|
||||
return viewport_height - get_boss().current_tab_bar_height
|
||||
|
||||
|
||||
def window_geometry(xstart, xnum, ystart, ynum):
|
||||
return WindowGeometry(left=xstart, top=ystart, xnum=xnum, ynum=ynum, right=xstart + cell_size.width * xnum, bottom=ystart + cell_size.height * ynum)
|
||||
return WindowGeometry(left=xstart, top=ystart, xnum=xnum, ynum=ynum, right=xstart + cell_width * xnum, bottom=ystart + cell_height * ynum)
|
||||
|
||||
|
||||
def layout_single_window(margin_length, padding_length):
|
||||
xstart, xnum = next(layout_dimension(viewport_size.width, cell_size.width, margin_length=margin_length, padding_length=padding_length))
|
||||
ystart, ynum = next(layout_dimension(available_height(), cell_size.height, margin_length=margin_length, padding_length=padding_length))
|
||||
xstart, xnum = next(layout_dimension(viewport_width, cell_width, margin_length=margin_length, padding_length=padding_length))
|
||||
ystart, ynum = next(layout_dimension(available_height(), cell_height, margin_length=margin_length, padding_length=padding_length))
|
||||
return window_geometry(xstart, xnum, ystart, ynum)
|
||||
|
||||
|
||||
@ -94,18 +104,18 @@ def left_blank_rect(w, rects, vh):
|
||||
|
||||
|
||||
def right_blank_rect(w, rects, vh):
|
||||
if w.geometry.right < viewport_size.width:
|
||||
rects.append(Rect(w.geometry.right, 0, viewport_size.width, vh))
|
||||
if w.geometry.right < viewport_width:
|
||||
rects.append(Rect(w.geometry.right, 0, viewport_width, vh))
|
||||
|
||||
|
||||
def top_blank_rect(w, rects, vh):
|
||||
if w.geometry.top > 0:
|
||||
rects.append(Rect(0, 0, viewport_size.width, w.geometry.top))
|
||||
rects.append(Rect(0, 0, viewport_width, w.geometry.top))
|
||||
|
||||
|
||||
def bottom_blank_rect(w, rects, vh):
|
||||
if w.geometry.bottom < available_height():
|
||||
rects.append(Rect(0, w.geometry.bottom, viewport_size.width, vh))
|
||||
rects.append(Rect(0, w.geometry.bottom, viewport_width, vh))
|
||||
|
||||
|
||||
def blank_rects_for_window(w):
|
||||
@ -124,7 +134,7 @@ class Stack(Layout):
|
||||
for i, w in enumerate(windows):
|
||||
w.set_visible_in_layout(i, i == active_window_idx)
|
||||
|
||||
def __call__(self, windows, active_window_idx):
|
||||
def do_layout(self, windows, active_window_idx):
|
||||
self.blank_rects = []
|
||||
wg = layout_single_window(self.margin_width, self.padding_width)
|
||||
for i, w in enumerate(windows):
|
||||
@ -138,7 +148,7 @@ class Tall(Layout):
|
||||
|
||||
name = 'tall'
|
||||
|
||||
def __call__(self, windows, active_window_idx):
|
||||
def do_layout(self, windows, active_window_idx):
|
||||
self.blank_rects = br = []
|
||||
if len(windows) == 1:
|
||||
wg = layout_single_window(self.margin_width, self.padding_width)
|
||||
@ -146,24 +156,24 @@ class Tall(Layout):
|
||||
self.blank_rects = blank_rects_for_window(windows[0])
|
||||
return
|
||||
xlayout = layout_dimension(
|
||||
viewport_size.width, cell_size.width, 2, self.border_width,
|
||||
viewport_width, cell_width, 2, self.border_width,
|
||||
margin_length=self.margin_width, padding_length=self.padding_width)
|
||||
xstart, xnum = next(xlayout)
|
||||
ystart, ynum = next(layout_dimension(
|
||||
available_height(), cell_size.height, 1, self.border_width, left_align=True,
|
||||
available_height(), cell_height, 1, self.border_width, left_align=True,
|
||||
margin_length=self.margin_width, padding_length=self.padding_width))
|
||||
windows[0].set_geometry(0, window_geometry(xstart, xnum, ystart, ynum))
|
||||
vh = available_height()
|
||||
xstart, xnum = next(xlayout)
|
||||
ylayout = layout_dimension(
|
||||
available_height(), cell_size.height, len(windows) - 1, self.border_width, left_align=True,
|
||||
available_height(), cell_height, len(windows) - 1, self.border_width, left_align=True,
|
||||
margin_length=self.margin_width, padding_length=self.padding_width)
|
||||
for i, (w, (ystart, ynum)) in enumerate(zip(islice(windows, 1, None), ylayout)):
|
||||
w.set_geometry(i + 1, window_geometry(xstart, xnum, ystart, ynum))
|
||||
left_blank_rect(windows[0], br, vh), top_blank_rect(windows[0], br, vh), right_blank_rect(windows[-1], br, vh)
|
||||
br.append(Rect(windows[0].geometry.right, 0, windows[1].geometry.left, vh))
|
||||
br.append(Rect(0, windows[0].geometry.bottom, windows[0].geometry.right, vh))
|
||||
br.append(Rect(windows[-1].geometry.left, windows[-1].geometry.bottom, viewport_size.width, vh))
|
||||
br.append(Rect(windows[-1].geometry.left, windows[-1].geometry.bottom, viewport_width, vh))
|
||||
|
||||
|
||||
all_layouts = {o.name: o for o in globals().values() if isinstance(o, type) and issubclass(o, Layout) and o is not Layout}
|
||||
|
||||
@ -324,6 +324,15 @@ PYWRAP1(set_tab_bar_render_data) {
|
||||
#undef A
|
||||
}
|
||||
|
||||
PYWRAP1(viewport_for_window) {
|
||||
id_type os_window_id = PyLong_AsUnsignedLongLong(args);
|
||||
WITH_OS_WINDOW(os_window_id)
|
||||
return Py_BuildValue("iiII", os_window->viewport_width, os_window->viewport_height, global_state.cell_width, global_state.cell_height);
|
||||
END_WITH_OS_WINDOW
|
||||
return Py_BuildValue("iiII", 400, 400, global_state.cell_width, global_state.cell_height);
|
||||
}
|
||||
|
||||
|
||||
PYWRAP1(set_window_render_data) {
|
||||
#define A(name) &(d.name)
|
||||
#define B(name) &(g.name)
|
||||
@ -408,6 +417,7 @@ static PyMethodDef module_methods[] = {
|
||||
MW(add_borders_rect, METH_VARARGS),
|
||||
MW(set_tab_bar_render_data, METH_VARARGS),
|
||||
MW(set_window_render_data, METH_VARARGS),
|
||||
MW(viewport_for_window, METH_O),
|
||||
MW(update_window_visibility, METH_VARARGS),
|
||||
MW(set_boss, METH_O),
|
||||
MW(set_display_state, METH_VARARGS),
|
||||
|
||||
@ -22,7 +22,6 @@ from .utils import color_as_int
|
||||
from .window import Window, calculate_gl_geometry
|
||||
|
||||
TabbarData = namedtuple('TabbarData', 'title is_active is_last')
|
||||
borders = None
|
||||
tab_counter = count()
|
||||
next(tab_counter)
|
||||
|
||||
@ -34,7 +33,6 @@ def SpecialWindow(cmd, stdin=None, override_title=None):
|
||||
class Tab: # {{{
|
||||
|
||||
def __init__(self, os_window_id, opts, args, on_title_change, session_tab=None, special_window=None):
|
||||
global borders
|
||||
self.id = next(tab_counter)
|
||||
self.os_window_id = os_window_id
|
||||
add_tab(os_window_id, self.id)
|
||||
@ -42,8 +40,7 @@ class Tab: # {{{
|
||||
self.name = getattr(session_tab, 'name', '')
|
||||
self.on_title_change = on_title_change
|
||||
self.enabled_layouts = list(getattr(session_tab, 'enabled_layouts', None) or opts.enabled_layouts)
|
||||
if borders is None:
|
||||
borders = Borders(opts)
|
||||
self.borders = Borders(self.os_window_id, self.id, opts)
|
||||
self.windows = deque()
|
||||
self.active_window_idx = 0
|
||||
for i, which in enumerate('first second third fourth fifth sixth seventh eighth ninth tenth'.split()):
|
||||
@ -51,7 +48,7 @@ class Tab: # {{{
|
||||
if session_tab is None:
|
||||
self.cwd = args.directory
|
||||
sl = self.enabled_layouts[0]
|
||||
self.current_layout = all_layouts[sl](opts, borders.border_width, self.windows)
|
||||
self.current_layout = all_layouts[sl](opts, self.borders.border_width, self.windows)
|
||||
if special_window is None:
|
||||
self.new_window()
|
||||
else:
|
||||
@ -59,7 +56,7 @@ class Tab: # {{{
|
||||
else:
|
||||
self.cwd = session_tab.cwd or args.directory
|
||||
l0 = session_tab.layout
|
||||
self.current_layout = all_layouts[l0](opts, borders.border_width, self.windows)
|
||||
self.current_layout = all_layouts[l0](opts, self.borders.border_width, self.windows)
|
||||
self.startup(session_tab)
|
||||
|
||||
def startup(self, session_tab):
|
||||
@ -90,13 +87,13 @@ class Tab: # {{{
|
||||
|
||||
def relayout(self):
|
||||
if self.windows:
|
||||
self.current_layout(self.windows, self.active_window_idx)
|
||||
self.current_layout(self.os_window_id, self.windows, self.active_window_idx)
|
||||
self.relayout_borders()
|
||||
|
||||
def relayout_borders(self):
|
||||
tm = get_boss().tab_manager
|
||||
borders(self.windows, self.active_window, self.current_layout, tm.blank_rects,
|
||||
self.current_layout.needs_window_borders and len(self.windows) > 1)
|
||||
self.borders(self.windows, self.active_window, self.current_layout,
|
||||
tm.blank_rects, self.current_layout.needs_window_borders and len(self.windows) > 1)
|
||||
|
||||
def next_layout(self):
|
||||
if len(self.opts.enabled_layouts) > 1:
|
||||
@ -105,7 +102,7 @@ class Tab: # {{{
|
||||
except Exception:
|
||||
idx = -1
|
||||
nl = self.opts.enabled_layouts[(idx + 1) % len(self.opts.enabled_layouts)]
|
||||
self.current_layout = all_layouts[nl](self.opts, borders.border_width, self.windows)
|
||||
self.current_layout = all_layouts[nl](self.opts, self.borders.border_width, self.windows)
|
||||
for i, w in enumerate(self.windows):
|
||||
w.set_visible_in_layout(i, True)
|
||||
self.relayout()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user