Files
blender-portable-repo/scripts/addons/blender_kitsu/sqe/draw.py
T
2026-03-17 14:58:51 -06:00

127 lines
3.8 KiB
Python

# SPDX-FileCopyrightText: 2021 Blender Studio Tools Authors
#
# SPDX-License-Identifier: GPL-3.0-or-later
import typing
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
# Shaders and batches
rect_coords = ((0, 0), (1, 0), (1, 1), (0, 1))
indices = ((0, 1, 2), (2, 3, 0))
# Setup shaders only if Blender runs in the foreground.
# If running in the background, no handles are registered, as drawing extra UI
# elements does not make sense.
# See register() and unregister().
if not bpy.app.background:
ucolor_2d_shader = gpu.shader.from_builtin("UNIFORM_COLOR")
ucolor_2d_rect_batch = batch_for_shader(
ucolor_2d_shader, "TRIS", {"pos": rect_coords}, indices=indices
)
Float2 = typing.Tuple[float, float]
Float3 = typing.Tuple[float, float, float]
Float4 = typing.Tuple[float, float, float, float]
def draw_line(position: Float2, size: Float2, color: Float4):
with gpu.matrix.push_pop():
gpu.state.blend_set("ALPHA")
gpu.matrix.translate(position)
gpu.matrix.scale(size)
ucolor_2d_shader.uniform_float("color", color)
ucolor_2d_rect_batch.draw(ucolor_2d_shader)
gpu.state.blend_set("NONE")
def get_strip_rectf(strip) -> Float4:
# Get x and y in terms of the grid's frames and channels.
x1 = strip.frame_final_start
x2 = strip.frame_final_end
# Seems to be a 5 % offset from channel top start of strip.
y1 = strip.channel + 0.05
y2 = strip.channel - 0.05 + 1
return x1, y1, x2, y2
def draw_line_in_strip(strip_coords: Float4, height_factor: float, color: Float4):
# Unpack strip coordinates.
s_x1, channel, s_x2, _ = strip_coords
# Get the line's measures, as a percentage of channel height.
# Note that the strip's height is 10% smaller than the channel (centered 5% top and bottom).
# Note 2: offset the height slightly (0.005) to make room for the selection outline (channel coords).
line_height_in_channel = (0.9 - 0.005 * 2) * height_factor + 0.005
line_thickness = 0.04
# Offset the width slightly to make room for the selection outline (virtual grid horizontal coords).
width_offset = 0.2
width = (s_x2 - s_x1) - width_offset * 2
pos = (s_x1 + width_offset, channel + line_height_in_channel)
scale = (width, line_thickness)
draw_line(pos, scale, color)
def draw_callback_px():
context = bpy.context
sqe = context.scene.sequence_editor
if not sqe:
return
strips = sqe.sequences_all
for strip in strips:
# Get corners of the strip rectangle in terms of the grid's frames and channels (virtual, not px).
strip_coords = get_strip_rectf(strip)
if strip.kitsu.initialized or strip.kitsu.linked:
try:
color = tuple(
context.scene.kitsu.sequence_colors[strip.kitsu.sequence_id].color
)
except KeyError:
color = (1, 1, 1)
alpha = 0.75 if strip.kitsu.linked else 0.25
line_color = color + (alpha,)
draw_line_in_strip(strip_coords, 0.0, line_color)
if strip.kitsu.media_outdated:
line_color = (1.0, 0.05, 0.145, 0.75)
draw_line_in_strip(strip_coords, 0.9, line_color)
draw_handles = []
def register():
if bpy.app.background:
# Do not register anything if Blender runs in the background (no UI needed).
return
draw_handles.append(
bpy.types.SpaceSequenceEditor.draw_handler_add(
draw_callback_px, (), "WINDOW", "POST_VIEW"
)
)
def unregister():
if bpy.app.background:
return
for handle in reversed(draw_handles):
try:
bpy.types.SpaceSequenceEditor.draw_handler_remove(handle, "WINDOW")
except ValueError:
# Not sure why, but sometimes the handler seems to already be removed...??
pass